@openai/codex 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
Binary file
Binary file
Binary file
Binary file
package/bin/codex.js CHANGED
@@ -15,7 +15,6 @@
15
15
  * current platform / architecture, an error is thrown.
16
16
  */
17
17
 
18
- import { spawnSync } from "child_process";
19
18
  import fs from "fs";
20
19
  import path from "path";
21
20
  import { fileURLToPath, pathToFileURL } from "url";
@@ -35,7 +34,7 @@ const wantsNative = fs.existsSync(path.join(__dirname, "use-native")) ||
35
34
  : false);
36
35
 
37
36
  // Try native binary if requested.
38
- if (wantsNative) {
37
+ if (wantsNative && process.platform !== 'win32') {
39
38
  const { platform, arch } = process;
40
39
 
41
40
  let targetTriple = null;
@@ -74,22 +73,76 @@ if (wantsNative) {
74
73
  }
75
74
 
76
75
  const binaryPath = path.join(__dirname, "..", "bin", `codex-${targetTriple}`);
77
- const result = spawnSync(binaryPath, process.argv.slice(2), {
76
+
77
+ // Use an asynchronous spawn instead of spawnSync so that Node is able to
78
+ // respond to signals (e.g. Ctrl-C / SIGINT) while the native binary is
79
+ // executing. This allows us to forward those signals to the child process
80
+ // and guarantees that when either the child terminates or the parent
81
+ // receives a fatal signal, both processes exit in a predictable manner.
82
+ const { spawn } = await import("child_process");
83
+
84
+ const child = spawn(binaryPath, process.argv.slice(2), {
78
85
  stdio: "inherit",
79
86
  });
80
87
 
81
- const exitCode = typeof result.status === "number" ? result.status : 1;
82
- process.exit(exitCode);
83
- }
88
+ child.on("error", (err) => {
89
+ // Typically triggered when the binary is missing or not executable.
90
+ // Re-throwing here will terminate the parent with a non-zero exit code
91
+ // while still printing a helpful stack trace.
92
+ // eslint-disable-next-line no-console
93
+ console.error(err);
94
+ process.exit(1);
95
+ });
84
96
 
85
- // Fallback: execute the original JavaScript CLI.
97
+ // Forward common termination signals to the child so that it shuts down
98
+ // gracefully. In the handler we temporarily disable the default behavior of
99
+ // exiting immediately; once the child has been signaled we simply wait for
100
+ // its exit event which will in turn terminate the parent (see below).
101
+ const forwardSignal = (signal) => {
102
+ if (child.killed) {
103
+ return;
104
+ }
105
+ try {
106
+ child.kill(signal);
107
+ } catch {
108
+ /* ignore */
109
+ }
110
+ };
86
111
 
87
- // Resolve the path to the compiled CLI bundle
88
- const cliPath = path.resolve(__dirname, "../dist/cli.js");
89
- const cliUrl = pathToFileURL(cliPath).href;
112
+ ["SIGINT", "SIGTERM", "SIGHUP"].forEach((sig) => {
113
+ process.on(sig, () => forwardSignal(sig));
114
+ });
90
115
 
91
- // Load and execute the CLI
92
- (async () => {
116
+ // When the child exits, mirror its termination reason in the parent so that
117
+ // shell scripts and other tooling observe the correct exit status.
118
+ // Wrap the lifetime of the child process in a Promise so that we can await
119
+ // its termination in a structured way. The Promise resolves with an object
120
+ // describing how the child exited: either via exit code or due to a signal.
121
+ const childResult = await new Promise((resolve) => {
122
+ child.on("exit", (code, signal) => {
123
+ if (signal) {
124
+ resolve({ type: "signal", signal });
125
+ } else {
126
+ resolve({ type: "code", exitCode: code ?? 1 });
127
+ }
128
+ });
129
+ });
130
+
131
+ if (childResult.type === "signal") {
132
+ // Re-emit the same signal so that the parent terminates with the expected
133
+ // semantics (this also sets the correct exit code of 128 + n).
134
+ process.kill(process.pid, childResult.signal);
135
+ } else {
136
+ process.exit(childResult.exitCode);
137
+ }
138
+ } else {
139
+ // Fallback: execute the original JavaScript CLI.
140
+
141
+ // Resolve the path to the compiled CLI bundle
142
+ const cliPath = path.resolve(__dirname, "../dist/cli.js");
143
+ const cliUrl = pathToFileURL(cliPath).href;
144
+
145
+ // Load and execute the CLI
93
146
  try {
94
147
  await import(cliUrl);
95
148
  } catch (err) {
@@ -97,4 +150,4 @@ const cliUrl = pathToFileURL(cliPath).href;
97
150
  console.error(err);
98
151
  process.exit(1);
99
152
  }
100
- })();
153
+ }