Commit
a867dca
·
verified ·
1 Parent(s): 95ecc67

Upload 2 files

Browse files
Files changed (2) hide show
  1. codex.js +229 -0
  2. rg +79 -0
codex.js ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env node
2
+ // Unified entry point for the Codex CLI.
3
+
4
+ import { spawn } from "node:child_process";
5
+ import { existsSync } from "fs";
6
+ import { createRequire } from "node:module";
7
+ import path from "path";
8
+ import { fileURLToPath } from "url";
9
+
10
+ // __dirname equivalent in ESM
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
13
+ const require = createRequire(import.meta.url);
14
+
15
+ const PLATFORM_PACKAGE_BY_TARGET = {
16
+ "x86_64-unknown-linux-musl": "@openai/codex-linux-x64",
17
+ "aarch64-unknown-linux-musl": "@openai/codex-linux-arm64",
18
+ "x86_64-apple-darwin": "@openai/codex-darwin-x64",
19
+ "aarch64-apple-darwin": "@openai/codex-darwin-arm64",
20
+ "x86_64-pc-windows-msvc": "@openai/codex-win32-x64",
21
+ "aarch64-pc-windows-msvc": "@openai/codex-win32-arm64",
22
+ };
23
+
24
+ const { platform, arch } = process;
25
+
26
+ let targetTriple = null;
27
+ switch (platform) {
28
+ case "linux":
29
+ case "android":
30
+ switch (arch) {
31
+ case "x64":
32
+ targetTriple = "x86_64-unknown-linux-musl";
33
+ break;
34
+ case "arm64":
35
+ targetTriple = "aarch64-unknown-linux-musl";
36
+ break;
37
+ default:
38
+ break;
39
+ }
40
+ break;
41
+ case "darwin":
42
+ switch (arch) {
43
+ case "x64":
44
+ targetTriple = "x86_64-apple-darwin";
45
+ break;
46
+ case "arm64":
47
+ targetTriple = "aarch64-apple-darwin";
48
+ break;
49
+ default:
50
+ break;
51
+ }
52
+ break;
53
+ case "win32":
54
+ switch (arch) {
55
+ case "x64":
56
+ targetTriple = "x86_64-pc-windows-msvc";
57
+ break;
58
+ case "arm64":
59
+ targetTriple = "aarch64-pc-windows-msvc";
60
+ break;
61
+ default:
62
+ break;
63
+ }
64
+ break;
65
+ default:
66
+ break;
67
+ }
68
+
69
+ if (!targetTriple) {
70
+ throw new Error(`Unsupported platform: ${platform} (${arch})`);
71
+ }
72
+
73
+ const platformPackage = PLATFORM_PACKAGE_BY_TARGET[targetTriple];
74
+ if (!platformPackage) {
75
+ throw new Error(`Unsupported target triple: ${targetTriple}`);
76
+ }
77
+
78
+ const codexBinaryName = process.platform === "win32" ? "codex.exe" : "codex";
79
+ const localVendorRoot = path.join(__dirname, "..", "vendor");
80
+ const localBinaryPath = path.join(
81
+ localVendorRoot,
82
+ targetTriple,
83
+ "codex",
84
+ codexBinaryName,
85
+ );
86
+
87
+ let vendorRoot;
88
+ try {
89
+ const packageJsonPath = require.resolve(`${platformPackage}/package.json`);
90
+ vendorRoot = path.join(path.dirname(packageJsonPath), "vendor");
91
+ } catch {
92
+ if (existsSync(localBinaryPath)) {
93
+ vendorRoot = localVendorRoot;
94
+ } else {
95
+ const packageManager = detectPackageManager();
96
+ const updateCommand =
97
+ packageManager === "bun"
98
+ ? "bun install -g @openai/codex@latest"
99
+ : "npm install -g @openai/codex@latest";
100
+ throw new Error(
101
+ `Missing optional dependency ${platformPackage}. Reinstall Codex: ${updateCommand}`,
102
+ );
103
+ }
104
+ }
105
+
106
+ if (!vendorRoot) {
107
+ const packageManager = detectPackageManager();
108
+ const updateCommand =
109
+ packageManager === "bun"
110
+ ? "bun install -g @openai/codex@latest"
111
+ : "npm install -g @openai/codex@latest";
112
+ throw new Error(
113
+ `Missing optional dependency ${platformPackage}. Reinstall Codex: ${updateCommand}`,
114
+ );
115
+ }
116
+
117
+ const archRoot = path.join(vendorRoot, targetTriple);
118
+ const binaryPath = path.join(archRoot, "codex", codexBinaryName);
119
+
120
+ // Use an asynchronous spawn instead of spawnSync so that Node is able to
121
+ // respond to signals (e.g. Ctrl-C / SIGINT) while the native binary is
122
+ // executing. This allows us to forward those signals to the child process
123
+ // and guarantees that when either the child terminates or the parent
124
+ // receives a fatal signal, both processes exit in a predictable manner.
125
+
126
+ function getUpdatedPath(newDirs) {
127
+ const pathSep = process.platform === "win32" ? ";" : ":";
128
+ const existingPath = process.env.PATH || "";
129
+ const updatedPath = [
130
+ ...newDirs,
131
+ ...existingPath.split(pathSep).filter(Boolean),
132
+ ].join(pathSep);
133
+ return updatedPath;
134
+ }
135
+
136
+ /**
137
+ * Use heuristics to detect the package manager that was used to install Codex
138
+ * in order to give the user a hint about how to update it.
139
+ */
140
+ function detectPackageManager() {
141
+ const userAgent = process.env.npm_config_user_agent || "";
142
+ if (/\bbun\//.test(userAgent)) {
143
+ return "bun";
144
+ }
145
+
146
+ const execPath = process.env.npm_execpath || "";
147
+ if (execPath.includes("bun")) {
148
+ return "bun";
149
+ }
150
+
151
+ if (
152
+ __dirname.includes(".bun/install/global") ||
153
+ __dirname.includes(".bun\\install\\global")
154
+ ) {
155
+ return "bun";
156
+ }
157
+
158
+ return userAgent ? "npm" : null;
159
+ }
160
+
161
+ const additionalDirs = [];
162
+ const pathDir = path.join(archRoot, "path");
163
+ if (existsSync(pathDir)) {
164
+ additionalDirs.push(pathDir);
165
+ }
166
+ const updatedPath = getUpdatedPath(additionalDirs);
167
+
168
+ const env = { ...process.env, PATH: updatedPath };
169
+ const packageManagerEnvVar =
170
+ detectPackageManager() === "bun"
171
+ ? "CODEX_MANAGED_BY_BUN"
172
+ : "CODEX_MANAGED_BY_NPM";
173
+ env[packageManagerEnvVar] = "1";
174
+
175
+ const child = spawn(binaryPath, process.argv.slice(2), {
176
+ stdio: "inherit",
177
+ env,
178
+ });
179
+
180
+ child.on("error", (err) => {
181
+ // Typically triggered when the binary is missing or not executable.
182
+ // Re-throwing here will terminate the parent with a non-zero exit code
183
+ // while still printing a helpful stack trace.
184
+ // eslint-disable-next-line no-console
185
+ console.error(err);
186
+ process.exit(1);
187
+ });
188
+
189
+ // Forward common termination signals to the child so that it shuts down
190
+ // gracefully. In the handler we temporarily disable the default behavior of
191
+ // exiting immediately; once the child has been signaled we simply wait for
192
+ // its exit event which will in turn terminate the parent (see below).
193
+ const forwardSignal = (signal) => {
194
+ if (child.killed) {
195
+ return;
196
+ }
197
+ try {
198
+ child.kill(signal);
199
+ } catch {
200
+ /* ignore */
201
+ }
202
+ };
203
+
204
+ ["SIGINT", "SIGTERM", "SIGHUP"].forEach((sig) => {
205
+ process.on(sig, () => forwardSignal(sig));
206
+ });
207
+
208
+ // When the child exits, mirror its termination reason in the parent so that
209
+ // shell scripts and other tooling observe the correct exit status.
210
+ // Wrap the lifetime of the child process in a Promise so that we can await
211
+ // its termination in a structured way. The Promise resolves with an object
212
+ // describing how the child exited: either via exit code or due to a signal.
213
+ const childResult = await new Promise((resolve) => {
214
+ child.on("exit", (code, signal) => {
215
+ if (signal) {
216
+ resolve({ type: "signal", signal });
217
+ } else {
218
+ resolve({ type: "code", exitCode: code ?? 1 });
219
+ }
220
+ });
221
+ });
222
+
223
+ if (childResult.type === "signal") {
224
+ // Re-emit the same signal so that the parent terminates with the expected
225
+ // semantics (this also sets the correct exit code of 128 + n).
226
+ process.kill(process.pid, childResult.signal);
227
+ } else {
228
+ process.exit(childResult.exitCode);
229
+ }
rg ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env dotslash
2
+
3
+ {
4
+ "name": "rg",
5
+ "platforms": {
6
+ "macos-aarch64": {
7
+ "size": 1777930,
8
+ "hash": "sha256",
9
+ "digest": "378e973289176ca0c6054054ee7f631a065874a352bf43f0fa60ef079b6ba715",
10
+ "format": "tar.gz",
11
+ "path": "ripgrep-15.1.0-aarch64-apple-darwin/rg",
12
+ "providers": [
13
+ {
14
+ "url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-apple-darwin.tar.gz"
15
+ }
16
+ ]
17
+ },
18
+ "linux-aarch64": {
19
+ "size": 1869959,
20
+ "hash": "sha256",
21
+ "digest": "2b661c6ef508e902f388e9098d9c4c5aca72c87b55922d94abdba830b4dc885e",
22
+ "format": "tar.gz",
23
+ "path": "ripgrep-15.1.0-aarch64-unknown-linux-gnu/rg",
24
+ "providers": [
25
+ {
26
+ "url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-unknown-linux-gnu.tar.gz"
27
+ }
28
+ ]
29
+ },
30
+ "macos-x86_64": {
31
+ "size": 1894127,
32
+ "hash": "sha256",
33
+ "digest": "64811cb24e77cac3057d6c40b63ac9becf9082eedd54ca411b475b755d334882",
34
+ "format": "tar.gz",
35
+ "path": "ripgrep-15.1.0-x86_64-apple-darwin/rg",
36
+ "providers": [
37
+ {
38
+ "url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-apple-darwin.tar.gz"
39
+ }
40
+ ]
41
+ },
42
+ "linux-x86_64": {
43
+ "size": 2263077,
44
+ "hash": "sha256",
45
+ "digest": "1c9297be4a084eea7ecaedf93eb03d058d6faae29bbc57ecdaf5063921491599",
46
+ "format": "tar.gz",
47
+ "path": "ripgrep-15.1.0-x86_64-unknown-linux-musl/rg",
48
+ "providers": [
49
+ {
50
+ "url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-unknown-linux-musl.tar.gz"
51
+ }
52
+ ]
53
+ },
54
+ "windows-x86_64": {
55
+ "size": 1810687,
56
+ "hash": "sha256",
57
+ "digest": "124510b94b6baa3380d051fdf4650eaa80a302c876d611e9dba0b2e18d87493a",
58
+ "format": "zip",
59
+ "path": "ripgrep-15.1.0-x86_64-pc-windows-msvc/rg.exe",
60
+ "providers": [
61
+ {
62
+ "url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-x86_64-pc-windows-msvc.zip"
63
+ }
64
+ ]
65
+ },
66
+ "windows-aarch64": {
67
+ "size": 1675460,
68
+ "hash": "sha256",
69
+ "digest": "00d931fb5237c9696ca49308818edb76d8eb6fc132761cb2a1bd616b2df02f8e",
70
+ "format": "zip",
71
+ "path": "ripgrep-15.1.0-aarch64-pc-windows-msvc/rg.exe",
72
+ "providers": [
73
+ {
74
+ "url": "https://github.com/BurntSushi/ripgrep/releases/download/15.1.0/ripgrep-15.1.0-aarch64-pc-windows-msvc.zip"
75
+ }
76
+ ]
77
+ }
78
+ }
79
+ }