@4xeoz/re-entry 0.2.15 → 0.2.17
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.
- package/README.md +4 -1
- package/package.json +1 -1
- package/src/codex-exec-adapter.mjs +59 -9
- package/src/main.mjs +9 -1
package/README.md
CHANGED
|
@@ -132,7 +132,10 @@ npx --yes --package=@4xeoz/re-entry re-entry test "Reply with: Re-entry is worki
|
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
This starts one fresh local Codex process through the same adapter seam used by real deliveries. It
|
|
135
|
-
|
|
135
|
+
forwards Codex output when run in an interactive terminal, so the smoke test behaves like the
|
|
136
|
+
underlying direct `codex exec` command. It does not create a Grant, claim Receiver work, or prove a
|
|
137
|
+
Desktop UI thread, browser, or WebMCP return path. If it times out, run the equivalent direct
|
|
138
|
+
`codex exec` command to inspect Codex's own output; the test does not contact the Receiver.
|
|
136
139
|
|
|
137
140
|
To pause or remove the local Connector:
|
|
138
141
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@4xeoz/re-entry",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Outbound Local Connector process for Re-entry Core; uses the Cloud Receiver v2 preview by default with an explicit override for other accepted origins.",
|
|
6
6
|
"publishConfig": {
|
|
@@ -59,6 +59,7 @@ export function createCodexExecAdapter(options) {
|
|
|
59
59
|
executable,
|
|
60
60
|
workingDirectory,
|
|
61
61
|
prompt: buildContinuationPrompt(activation),
|
|
62
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
62
63
|
commandTimeoutMs,
|
|
63
64
|
spawnCommand,
|
|
64
65
|
});
|
|
@@ -79,7 +80,7 @@ export function createCodexExecAdapter(options) {
|
|
|
79
80
|
export async function runCodexPrompt(options) {
|
|
80
81
|
requireExactRecord(
|
|
81
82
|
options,
|
|
82
|
-
["workingDirectory", "prompt", "executable", "commandTimeoutMs", "spawnCommand"],
|
|
83
|
+
["workingDirectory", "prompt", "executable", "commandTimeoutMs", "spawnCommand", "stdio"],
|
|
83
84
|
["workingDirectory", "prompt"],
|
|
84
85
|
"Codex prompt options",
|
|
85
86
|
);
|
|
@@ -93,7 +94,8 @@ export async function runCodexPrompt(options) {
|
|
|
93
94
|
if (typeof spawnCommand !== "function") {
|
|
94
95
|
throw new TypeError("Codex prompt spawnCommand must be a function");
|
|
95
96
|
}
|
|
96
|
-
|
|
97
|
+
const stdio = requireStdio(options.stdio ?? "inherit");
|
|
98
|
+
await runCodexExec({ executable, workingDirectory, prompt, timeoutMs, spawnCommand, stdio });
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
function buildContinuationPrompt(activation) {
|
|
@@ -114,7 +116,7 @@ function buildContinuationPrompt(activation) {
|
|
|
114
116
|
].join("\n");
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
function runCodexExec({ executable, workingDirectory, prompt, timeoutMs, spawnCommand }) {
|
|
119
|
+
function runCodexExec({ executable, workingDirectory, prompt, timeoutMs, spawnCommand, stdio }) {
|
|
118
120
|
return new Promise((resolve, reject) => {
|
|
119
121
|
let child;
|
|
120
122
|
let settled = false;
|
|
@@ -131,15 +133,25 @@ function runCodexExec({ executable, workingDirectory, prompt, timeoutMs, spawnCo
|
|
|
131
133
|
child = spawnCommand(
|
|
132
134
|
executable,
|
|
133
135
|
["exec", "--cd", workingDirectory, prompt],
|
|
134
|
-
{ stdio
|
|
136
|
+
{ stdio },
|
|
135
137
|
);
|
|
136
138
|
} catch (error) {
|
|
137
|
-
finish(
|
|
139
|
+
finish(
|
|
140
|
+
reject,
|
|
141
|
+
codexExecError(
|
|
142
|
+
"connector_codex_exec_start_failed",
|
|
143
|
+
"Codex exec could not be started",
|
|
144
|
+
error,
|
|
145
|
+
),
|
|
146
|
+
);
|
|
138
147
|
return;
|
|
139
148
|
}
|
|
140
149
|
|
|
141
150
|
if (!child || typeof child.once !== "function") {
|
|
142
|
-
finish(
|
|
151
|
+
finish(
|
|
152
|
+
reject,
|
|
153
|
+
codexExecError("connector_codex_exec_invalid", "Codex exec returned an invalid process"),
|
|
154
|
+
);
|
|
143
155
|
return;
|
|
144
156
|
}
|
|
145
157
|
|
|
@@ -149,16 +161,36 @@ function runCodexExec({ executable, workingDirectory, prompt, timeoutMs, spawnCo
|
|
|
149
161
|
} catch {
|
|
150
162
|
// The activation remains unknown even if the process cannot be terminated.
|
|
151
163
|
}
|
|
152
|
-
finish(
|
|
164
|
+
finish(
|
|
165
|
+
reject,
|
|
166
|
+
codexExecError(
|
|
167
|
+
"connector_codex_exec_timeout",
|
|
168
|
+
`Codex exec process timed out after ${timeoutMs} milliseconds`,
|
|
169
|
+
),
|
|
170
|
+
);
|
|
153
171
|
}, timeoutMs);
|
|
154
172
|
|
|
155
|
-
child.once("error", (error) => finish(
|
|
173
|
+
child.once("error", (error) => finish(
|
|
174
|
+
reject,
|
|
175
|
+
codexExecError("connector_codex_exec_start_failed", "Codex exec process failed to start", error),
|
|
176
|
+
));
|
|
156
177
|
child.once("close", (code, signal) => {
|
|
157
178
|
if (code === 0 && signal === null) {
|
|
158
179
|
finish(resolve);
|
|
159
180
|
return;
|
|
160
181
|
}
|
|
161
|
-
|
|
182
|
+
const detail = signal
|
|
183
|
+
? ` (signal ${signal})`
|
|
184
|
+
: code === null
|
|
185
|
+
? ""
|
|
186
|
+
: ` (exit code ${code})`;
|
|
187
|
+
finish(
|
|
188
|
+
reject,
|
|
189
|
+
codexExecError(
|
|
190
|
+
"connector_codex_exec_failed",
|
|
191
|
+
`Codex exec process did not complete successfully${detail}`,
|
|
192
|
+
),
|
|
193
|
+
);
|
|
162
194
|
});
|
|
163
195
|
});
|
|
164
196
|
}
|
|
@@ -221,6 +253,24 @@ function requirePrompt(value) {
|
|
|
221
253
|
return value;
|
|
222
254
|
}
|
|
223
255
|
|
|
256
|
+
function requireStdio(value) {
|
|
257
|
+
if (value === "inherit") return value;
|
|
258
|
+
if (
|
|
259
|
+
Array.isArray(value) &&
|
|
260
|
+
value.length === 3 &&
|
|
261
|
+
value.every((entry) => entry === "ignore" || entry === "inherit" || entry === "pipe")
|
|
262
|
+
) {
|
|
263
|
+
return value;
|
|
264
|
+
}
|
|
265
|
+
throw new TypeError("Codex prompt stdio is invalid");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function codexExecError(code, message, cause = undefined) {
|
|
269
|
+
const error = cause === undefined ? new Error(message) : new Error(message, { cause });
|
|
270
|
+
error.code = code;
|
|
271
|
+
return error;
|
|
272
|
+
}
|
|
273
|
+
|
|
224
274
|
function requireExactRecord(value, allowedFields, requiredFields, label) {
|
|
225
275
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
226
276
|
throw new TypeError(`${label} must be an object`);
|
package/src/main.mjs
CHANGED
|
@@ -514,10 +514,14 @@ async function testCodex(flags, positionals, ui) {
|
|
|
514
514
|
ui.info("Prompt", prompt);
|
|
515
515
|
ui.wait("Starting a fresh Codex session…");
|
|
516
516
|
}
|
|
517
|
+
if (ui.interactive) {
|
|
518
|
+
ui.stopWait("Codex", "running the local prompt; Codex output follows below", "info");
|
|
519
|
+
}
|
|
517
520
|
await runCodexPrompt({
|
|
518
521
|
workingDirectory: readiness.workingDirectory,
|
|
519
522
|
executable: readiness.installation.executable,
|
|
520
523
|
prompt,
|
|
524
|
+
stdio: ui.interactive ? "inherit" : ["ignore", "ignore", "ignore"],
|
|
521
525
|
commandTimeoutMs: readBoundedNumber(
|
|
522
526
|
flags["activation-timeout"] ?? 60_000,
|
|
523
527
|
100,
|
|
@@ -1114,6 +1118,10 @@ function errorHint(error) {
|
|
|
1114
1118
|
pairing_expired: "ask the Host backend for a new pairing code",
|
|
1115
1119
|
pairing_request_timeout: "the Receiver took too long to answer; check your connection and run the command again",
|
|
1116
1120
|
pairing_network_error: "check your internet connection and the Receiver address, then try again",
|
|
1121
|
+
connector_codex_exec_timeout: "Codex did not finish in time; run the same codex exec command directly to inspect its output",
|
|
1122
|
+
connector_codex_exec_failed: "run the same codex exec command directly and confirm that Codex is signed in and the workspace is accessible",
|
|
1123
|
+
connector_codex_exec_start_failed: "open Codex, complete login if needed, then run the command again",
|
|
1124
|
+
connector_codex_exec_invalid: "the installed Codex executable returned an invalid process; run doctor and try again",
|
|
1117
1125
|
workspace_directory_unavailable: "choose a readable folder or pass --codex-cd /absolute/path",
|
|
1118
1126
|
workspace_selection_cancelled: "run the command again when you are ready to choose a workspace",
|
|
1119
1127
|
device_authorization_expired: `run \`${cliCommand("connect")}\` again and approve within ten minutes`,
|
|
@@ -1127,7 +1135,7 @@ function errorHint(error) {
|
|
|
1127
1135
|
connector_test_prompt_invalid: "use one short, single-line prompt inside quotes",
|
|
1128
1136
|
connector_activation_timeout_invalid: "use an activation timeout between 100 and 60000 milliseconds",
|
|
1129
1137
|
};
|
|
1130
|
-
return hints[error?.code] ?? "check the
|
|
1138
|
+
return hints[error?.code] ?? "check the command output and try again";
|
|
1131
1139
|
}
|
|
1132
1140
|
|
|
1133
1141
|
await main();
|