@loucompanion/forge-bridge 0.1.3-dev.d1ca67076aa9 → 0.1.3-dev.eeefdb0d19c1
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 +78 -0
- package/dist/bridge/bridge.base.d.ts +6 -1
- package/dist/bridge/bridge.service.d.ts +60 -3
- package/dist/bridge/bridge.service.js +962 -22
- package/dist/bridge/bridge.types.d.ts +172 -1
- package/dist/cleanup/cleanup.service.d.ts +13 -2
- package/dist/cleanup/cleanup.service.js +435 -3
- package/dist/cleanup/cleanup.types.d.ts +10 -0
- package/dist/cleanup/index.d.ts +1 -1
- package/dist/cleanup/index.js +1 -1
- package/dist/cleanup/internals.d.ts +2 -2
- package/dist/cleanup/internals.js +1 -1
- package/dist/cli/cli.help.js +47 -1
- package/dist/cli/cli.service.d.ts +42 -2
- package/dist/cli/cli.service.js +351 -22
- package/dist/cli/local-config.d.ts +6 -0
- package/dist/cli/local-config.js +47 -3
- package/dist/runtime/attempt-node-runtime-launcher.d.ts +17 -0
- package/dist/runtime/attempt-node-runtime-launcher.js +101 -0
- package/dist/runtime/attempt-process-supervisor-registry.d.ts +20 -0
- package/dist/runtime/attempt-process-supervisor-registry.js +64 -0
- package/dist/runtime/attempt-process-supervisor.d.ts +86 -0
- package/dist/runtime/attempt-process-supervisor.js +343 -0
- package/dist/runtime/generated-output-reset.d.ts +10 -0
- package/dist/runtime/generated-output-reset.js +103 -0
- package/dist/runtime/host-listener-inspector.d.ts +44 -0
- package/dist/runtime/host-listener-inspector.js +324 -0
- package/dist/runtime/host-port-broker.d.ts +76 -0
- package/dist/runtime/host-port-broker.js +333 -0
- package/dist/runtime/host-runtime-contract.d.ts +47 -0
- package/dist/runtime/host-runtime-contract.js +700 -0
- package/dist/runtime/host-runtime-lease.d.ts +133 -0
- package/dist/runtime/host-runtime-lease.js +1460 -0
- package/dist/runtime/host-runtime-promotion.d.ts +23 -0
- package/dist/runtime/host-runtime-promotion.js +159 -0
- package/dist/runtime/node-host-runtime-adapter.d.ts +51 -0
- package/dist/runtime/node-host-runtime-adapter.js +268 -0
- package/dist/runtime/playwright-host-runtime-adapter.d.ts +20 -0
- package/dist/runtime/playwright-host-runtime-adapter.js +220 -0
- package/dist/runtime/runtime-isolation-lease.d.ts +67 -0
- package/dist/runtime/runtime-isolation-lease.js +158 -0
- package/dist/sandbox/command-runner.d.ts +4 -0
- package/dist/sandbox/command-runner.js +47 -0
- package/dist/sandbox/contract.d.ts +5 -0
- package/dist/sandbox/contract.js +276 -0
- package/dist/sandbox/event-budget.d.ts +11 -0
- package/dist/sandbox/event-budget.js +27 -0
- package/dist/sandbox/image-policy.d.ts +35 -0
- package/dist/sandbox/image-policy.js +247 -0
- package/dist/sandbox/index.d.ts +5 -0
- package/dist/sandbox/index.js +5 -0
- package/dist/sandbox/lease-watchdog.d.ts +18 -0
- package/dist/sandbox/lease-watchdog.js +67 -0
- package/dist/sandbox/preflight.d.ts +54 -0
- package/dist/sandbox/preflight.js +335 -0
- package/dist/sandbox/process.d.ts +20 -0
- package/dist/sandbox/process.js +209 -0
- package/dist/sandbox/provider-auth/codex.d.ts +26 -0
- package/dist/sandbox/provider-auth/codex.js +212 -0
- package/dist/sandbox/repository-lock.d.ts +5 -0
- package/dist/sandbox/repository-lock.js +119 -0
- package/dist/sandbox/runtime.d.ts +297 -0
- package/dist/sandbox/runtime.js +2338 -0
- package/dist/sandbox/sandbox.types.d.ts +86 -0
- package/dist/sandbox/sandbox.types.js +1 -0
- package/dist/sandbox/smoke.d.ts +76 -0
- package/dist/sandbox/smoke.js +380 -0
- package/dist/sandbox/worker-supervisor.d.ts +13 -0
- package/dist/sandbox/worker-supervisor.js +36 -0
- package/dist/sandbox/worker.d.ts +1 -0
- package/dist/sandbox/worker.js +225 -0
- package/dist/sandbox/workspace.service.d.ts +13 -0
- package/dist/sandbox/workspace.service.js +72 -0
- package/dist/session/managed-attempt-tools.d.ts +12 -0
- package/dist/session/managed-attempt-tools.js +350 -0
- package/dist/session/phase-completion.artifacts.js +32 -4
- package/dist/session/phase-completion.d.ts +4 -2
- package/dist/session/phase-completion.helpers.js +27 -3
- package/dist/session/phase-completion.js +12 -3
- package/dist/session/phase-completion.prompts.d.ts +3 -3
- package/dist/session/phase-completion.prompts.js +19 -5
- package/dist/session/phase-completion.runtime.d.ts +12 -1
- package/dist/session/phase-completion.runtime.js +127 -7
- package/dist/session/phase-completion.schemas.js +108 -3
- package/dist/session/phase-completion.validation.d.ts +4 -1
- package/dist/session/phase-completion.validation.js +106 -2
- package/dist/session/provider-cli/ci-repair-readiness.d.ts +8 -0
- package/dist/session/provider-cli/ci-repair-readiness.js +90 -0
- package/dist/session/provider-cli/provider-cli.artifacts.d.ts +1 -1
- package/dist/session/provider-cli/provider-cli.artifacts.js +28 -4
- package/dist/session/provider-cli/provider-cli.base.d.ts +1 -0
- package/dist/session/provider-cli/provider-cli.deterministic.d.ts +2 -0
- package/dist/session/provider-cli/provider-cli.deterministic.js +66 -9
- package/dist/session/provider-cli/provider-cli.process.d.ts +17 -0
- package/dist/session/provider-cli/provider-cli.process.js +223 -14
- package/dist/session/provider-cli/provider-cli.prompts.d.ts +16 -2
- package/dist/session/provider-cli/provider-cli.prompts.js +202 -18
- package/dist/session/provider-cli/provider-cli.qa-sidecars.js +1 -0
- package/dist/session/provider-cli/provider-cli.runtime.d.ts +1 -1
- package/dist/session/provider-cli/provider-cli.runtime.js +3 -2
- package/dist/session/provider-cli/provider-cli.service.d.ts +7 -3
- package/dist/session/provider-cli/provider-cli.service.js +399 -98
- package/dist/session/provider-cli/provider-cli.types.d.ts +6 -0
- package/dist/session/provider-cli/provider-output-state.d.ts +2 -0
- package/dist/session/provider-cli/provider-output-state.js +30 -2
- package/dist/session/session-redaction.d.ts +3 -0
- package/dist/session/session-redaction.js +23 -0
- package/dist/session/session.base.d.ts +6 -1
- package/dist/session/session.service.d.ts +8 -2
- package/dist/session/session.service.js +463 -58
- package/dist/session/session.types.d.ts +107 -1
- package/dist/session/session.types.js +226 -3
- package/dist/shared/path/path.js +3 -1
- package/dist/shared/process/host-process-recovery.d.ts +12 -0
- package/dist/shared/process/host-process-recovery.js +78 -0
- package/dist/shared/process/host-process-supervisor.d.ts +57 -0
- package/dist/shared/process/host-process-supervisor.js +282 -0
- package/dist/shared/process/process.d.ts +1 -0
- package/dist/shared/process/process.js +1 -0
- package/dist/shared/process/windows-launch.d.ts +1 -1
- package/dist/shared/process/windows-launch.js +6 -3
- package/dist/shared/provider-capabilities.d.ts +1 -0
- package/dist/shared/provider-capabilities.js +3 -0
- package/dist/shared/redaction/redaction.js +10 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/worktree/artifact-injector.d.ts +3 -2
- package/dist/worktree/artifact-injector.js +43 -4
- package/dist/worktree/dependency-warmer.d.ts +21 -1
- package/dist/worktree/dependency-warmer.js +138 -5
- package/dist/worktree/index.d.ts +1 -0
- package/dist/worktree/index.js +1 -0
- package/dist/worktree/prior-phase-artifact-hydrator.d.ts +2 -0
- package/dist/worktree/prior-phase-artifact-hydrator.js +136 -0
- package/dist/worktree/worktree-paths.d.ts +4 -0
- package/dist/worktree/worktree-paths.js +30 -0
- package/dist/worktree/worktree.base.d.ts +3 -0
- package/dist/worktree/worktree.service.d.ts +7 -2
- package/dist/worktree/worktree.service.js +72 -44
- package/dist/worktree/worktree.types.d.ts +3 -1
- package/package.json +6 -3
- package/runtime/windows-job-supervisor.ps1 +356 -0
- package/runtime/windows-listener-owner.ps1 +33 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
2
3
|
import os from "node:os";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import readline from "node:readline";
|
|
5
6
|
import { promisify } from "node:util";
|
|
6
7
|
import { resolveCursorAgentDirectLaunch } from "../../shared/cursor-agent/cursor-agent.launch.js";
|
|
8
|
+
import { persistHostProcessSupervisorMetadata, resolveHostProcessSupervisedLaunch, terminateHostProcessTree, } from "../../shared/process/host-process-supervisor.js";
|
|
7
9
|
import { buildWindowsLaunchCommand } from "../../shared/process/windows-launch.js";
|
|
8
10
|
const execFileAsync = promisify(execFile);
|
|
9
11
|
const allowedProviderParentEnvNames = [
|
|
@@ -137,24 +139,35 @@ function setEnvironmentValueIfMissing(env, name, value) {
|
|
|
137
139
|
}
|
|
138
140
|
export class StreamingProviderProcessRunner {
|
|
139
141
|
async run(request, handlers = {}, signal) {
|
|
140
|
-
const
|
|
142
|
+
const providerLaunch = await resolveProviderProcessLaunch(request.command, request.args);
|
|
143
|
+
const supervisedLaunch = resolveHostProcessSupervisedLaunch(request, providerLaunch.command, providerLaunch.args);
|
|
144
|
+
const launch = supervisedLaunch ?? { ...providerLaunch, detached: false };
|
|
141
145
|
return await new Promise((resolve, reject) => {
|
|
146
|
+
const rootCreatedAt = new Date().toISOString();
|
|
142
147
|
const child = spawn(launch.command, launch.args, {
|
|
143
148
|
cwd: request.cwd,
|
|
144
149
|
env: buildProviderChildEnvironment(request.env),
|
|
145
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
146
|
-
windowsHide: true
|
|
150
|
+
stdio: [request.stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
|
|
151
|
+
windowsHide: true,
|
|
152
|
+
detached: launch.detached,
|
|
147
153
|
});
|
|
154
|
+
let termination = null;
|
|
155
|
+
const terminate = () => {
|
|
156
|
+
termination ??= terminateHostProcessTree(child, supervisedLaunch);
|
|
157
|
+
return termination;
|
|
158
|
+
};
|
|
148
159
|
const childStdout = child.stdout;
|
|
149
160
|
const childStderr = child.stderr;
|
|
150
161
|
if (!childStdout || !childStderr) {
|
|
151
|
-
|
|
162
|
+
void terminate();
|
|
152
163
|
reject(new Error("Provider process stdout/stderr streams were not piped."));
|
|
153
164
|
return;
|
|
154
165
|
}
|
|
155
166
|
let stdout = "";
|
|
156
167
|
let stderr = "";
|
|
157
168
|
let settled = false;
|
|
169
|
+
let closed = false;
|
|
170
|
+
let readiness = null;
|
|
158
171
|
const cleanup = () => {
|
|
159
172
|
signal?.removeEventListener("abort", abort);
|
|
160
173
|
};
|
|
@@ -164,15 +177,14 @@ export class StreamingProviderProcessRunner {
|
|
|
164
177
|
}
|
|
165
178
|
settled = true;
|
|
166
179
|
cleanup();
|
|
180
|
+
void terminate().catch(() => undefined);
|
|
167
181
|
reject(error);
|
|
168
182
|
};
|
|
169
183
|
const abort = () => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
catch
|
|
174
|
-
// Best effort; close/error will settle the promise.
|
|
175
|
-
}
|
|
184
|
+
// Cancellation is not a launch failure when the supervised tree can be
|
|
185
|
+
// proven stopped. Let the close handler settle the command after exact
|
|
186
|
+
// termination; only a failed termination proof rejects the run.
|
|
187
|
+
void terminate().catch(fail);
|
|
176
188
|
};
|
|
177
189
|
if (signal?.aborted) {
|
|
178
190
|
abort();
|
|
@@ -181,18 +193,66 @@ export class StreamingProviderProcessRunner {
|
|
|
181
193
|
signal?.addEventListener("abort", abort, { once: true });
|
|
182
194
|
}
|
|
183
195
|
child.on("error", fail);
|
|
196
|
+
child.once("spawn", () => {
|
|
197
|
+
readiness = (async () => {
|
|
198
|
+
const providerReady = supervisedLaunch?.strategy === "windows_job_object"
|
|
199
|
+
? await waitForWindowsProviderReady(supervisedLaunch, signal, () => closed)
|
|
200
|
+
: undefined;
|
|
201
|
+
if (supervisedLaunch) {
|
|
202
|
+
persistHostProcessSupervisorMetadata(supervisedLaunch, request, child.pid ?? 0, rootCreatedAt, providerReady);
|
|
203
|
+
}
|
|
204
|
+
await handlers.onStarted?.();
|
|
205
|
+
if (supervisedLaunch?.strategy === "windows_job_object") {
|
|
206
|
+
grantWindowsProviderStart(supervisedLaunch);
|
|
207
|
+
}
|
|
208
|
+
})();
|
|
209
|
+
void readiness.catch(error => {
|
|
210
|
+
if (!closed && !signal?.aborted)
|
|
211
|
+
fail(error);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
const writeProviderInput = () => {
|
|
215
|
+
if (request.stdin === undefined)
|
|
216
|
+
return;
|
|
217
|
+
if (!child.stdin) {
|
|
218
|
+
void terminate();
|
|
219
|
+
fail(new Error("Provider process stdin stream was not piped."));
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
child.stdin.on("error", (error) => {
|
|
223
|
+
void terminate();
|
|
224
|
+
fail(error);
|
|
225
|
+
});
|
|
226
|
+
child.stdin.end(request.stdin, "utf8");
|
|
227
|
+
};
|
|
228
|
+
if (request.stdin !== undefined) {
|
|
229
|
+
if (supervisedLaunch?.strategy === "windows_job_object") {
|
|
230
|
+
// The outer supervisor must receive stdin before it can launch the
|
|
231
|
+
// inner provider. Its start-grant file prevents prompt delivery.
|
|
232
|
+
writeProviderInput();
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
child.once("spawn", () => {
|
|
236
|
+
void readiness?.then(writeProviderInput).catch(fail);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
}
|
|
184
240
|
const readers = [
|
|
185
241
|
readProcessLines(childStdout, (line) => {
|
|
186
|
-
|
|
242
|
+
if (request.captureOutput !== false)
|
|
243
|
+
stdout += `${line}\n`;
|
|
187
244
|
return handlers.onStdoutLine?.(line);
|
|
188
245
|
}),
|
|
189
246
|
readProcessLines(childStderr, (line) => {
|
|
190
|
-
|
|
247
|
+
if (request.captureOutput !== false)
|
|
248
|
+
stderr += `${line}\n`;
|
|
191
249
|
return handlers.onStderrLine?.(line);
|
|
192
250
|
})
|
|
193
251
|
];
|
|
194
252
|
child.on("close", (code) => {
|
|
195
|
-
|
|
253
|
+
closed = true;
|
|
254
|
+
Promise.allSettled(readers).then(async (readerResults) => {
|
|
255
|
+
await readiness?.catch(() => undefined);
|
|
196
256
|
const rejected = readerResults.find((result) => result.status === "rejected");
|
|
197
257
|
if (rejected?.status === "rejected") {
|
|
198
258
|
fail(rejected.reason);
|
|
@@ -201,6 +261,18 @@ export class StreamingProviderProcessRunner {
|
|
|
201
261
|
if (settled) {
|
|
202
262
|
return;
|
|
203
263
|
}
|
|
264
|
+
try {
|
|
265
|
+
if (supervisedLaunch?.strategy === "unix_process_group") {
|
|
266
|
+
await terminate();
|
|
267
|
+
}
|
|
268
|
+
else if (termination) {
|
|
269
|
+
await termination;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
fail(error);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
204
276
|
settled = true;
|
|
205
277
|
cleanup();
|
|
206
278
|
resolve({
|
|
@@ -222,12 +294,115 @@ async function resolveProviderProcessLaunch(command, args) {
|
|
|
222
294
|
return cursorDirect;
|
|
223
295
|
}
|
|
224
296
|
const resolved = await resolveWindowsCommand(command);
|
|
225
|
-
|
|
297
|
+
if (!resolved) {
|
|
298
|
+
return { command, args };
|
|
299
|
+
}
|
|
300
|
+
return resolveCodexNpmDirectLaunch(resolved, args)
|
|
301
|
+
?? resolvePackageManagerDirectLaunch(resolved, args)
|
|
302
|
+
?? buildWindowsLaunchCommand(resolved, args);
|
|
303
|
+
}
|
|
304
|
+
function grantWindowsProviderStart(launch) {
|
|
305
|
+
if (!launch.startGrantPath) {
|
|
306
|
+
throw new Error("host_process_supervisor_invalid: Windows provider start-grant path was not assigned.");
|
|
307
|
+
}
|
|
308
|
+
fs.writeFileSync(launch.startGrantPath, "granted\n", {
|
|
309
|
+
encoding: "utf8",
|
|
310
|
+
flag: "wx",
|
|
311
|
+
mode: 0o600,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
async function waitForWindowsProviderReady(launch, signal, isClosed) {
|
|
315
|
+
const readyPath = launch.readyPath;
|
|
316
|
+
if (!readyPath) {
|
|
317
|
+
throw new Error("host_process_supervisor_invalid: Windows provider-ready path was not assigned.");
|
|
318
|
+
}
|
|
319
|
+
while (true) {
|
|
320
|
+
try {
|
|
321
|
+
const parsed = JSON.parse(await fs.promises.readFile(readyPath, "utf8"));
|
|
322
|
+
if (parsed.schemaVersion !== 1
|
|
323
|
+
|| parsed.supervisorId !== launch.supervisorId
|
|
324
|
+
|| !Number.isSafeInteger(parsed.rootPid)
|
|
325
|
+
|| (parsed.rootPid ?? 0) <= 0
|
|
326
|
+
|| typeof parsed.rootIdentity !== "string"
|
|
327
|
+
|| !/^win32:\d+$/u.test(parsed.rootIdentity)
|
|
328
|
+
|| !Number.isSafeInteger(parsed.providerPid)
|
|
329
|
+
|| (parsed.providerPid ?? 0) <= 0
|
|
330
|
+
|| typeof parsed.providerCreatedAt !== "string"
|
|
331
|
+
|| Number.isNaN(Date.parse(parsed.providerCreatedAt))
|
|
332
|
+
|| (parsed.providerIdentity !== undefined
|
|
333
|
+
&& (typeof parsed.providerIdentity !== "string" || !/^win32:\d+$/u.test(parsed.providerIdentity)))
|
|
334
|
+
|| !Number.isSafeInteger(parsed.startAttempt)
|
|
335
|
+
|| (parsed.startAttempt ?? 0) < 1) {
|
|
336
|
+
throw new Error("host_process_supervisor_invalid: provider-ready receipt was invalid.");
|
|
337
|
+
}
|
|
338
|
+
return parsed;
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
if (error.code !== "ENOENT")
|
|
342
|
+
throw error;
|
|
343
|
+
}
|
|
344
|
+
if (isClosed()) {
|
|
345
|
+
throw new Error("host_process_supervisor_start_failed: supervisor exited before the provider became ready.");
|
|
346
|
+
}
|
|
347
|
+
if (signal?.aborted) {
|
|
348
|
+
throw signal.reason instanceof Error ? signal.reason : new Error("Provider process launch was aborted.");
|
|
349
|
+
}
|
|
350
|
+
await new Promise(resolve => setTimeout(resolve, 25));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
export function resolveCodexNpmDirectLaunch(commandPath, args) {
|
|
354
|
+
const extension = path.extname(commandPath).toLowerCase();
|
|
355
|
+
if ((extension !== ".cmd" && extension !== ".ps1")
|
|
356
|
+
|| path.basename(commandPath, extension).toLowerCase() !== "codex") {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
const entryPoint = path.join(path.dirname(commandPath), "node_modules", "@openai", "codex", "bin", "codex.js");
|
|
360
|
+
return fs.existsSync(entryPoint)
|
|
361
|
+
? { command: process.execPath, args: [entryPoint, ...args] }
|
|
362
|
+
: null;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Avoids cmd.exe's nested-quote handling for package-manager shims. That
|
|
366
|
+
* quoting loses executable paths containing spaces after the command is
|
|
367
|
+
* wrapped by the Windows Job Object supervisor.
|
|
368
|
+
*/
|
|
369
|
+
export function resolvePackageManagerDirectLaunch(commandPath, args) {
|
|
370
|
+
const extension = path.extname(commandPath).toLowerCase();
|
|
371
|
+
if (extension !== ".cmd" && extension !== ".ps1")
|
|
372
|
+
return null;
|
|
373
|
+
const packageManager = path.basename(commandPath, extension).toLowerCase();
|
|
374
|
+
if (!["npm", "npx", "pnpm", "pnpx", "yarn", "yarnpkg"].includes(packageManager))
|
|
375
|
+
return null;
|
|
376
|
+
const root = path.dirname(commandPath);
|
|
377
|
+
const candidates = [
|
|
378
|
+
path.join(root, "node_modules", "corepack", "dist", `${packageManager}.js`),
|
|
379
|
+
...(packageManager === "npm" || packageManager === "npx"
|
|
380
|
+
? [path.join(root, "node_modules", "npm", "bin", `${packageManager}-cli.js`)]
|
|
381
|
+
: []),
|
|
382
|
+
...(packageManager === "pnpm" || packageManager === "pnpx"
|
|
383
|
+
? [path.join(root, "node_modules", "pnpm", "bin", `${packageManager}.cjs`)]
|
|
384
|
+
: []),
|
|
385
|
+
...(packageManager === "yarn" || packageManager === "yarnpkg"
|
|
386
|
+
? [path.join(root, "node_modules", "yarn", "bin", "yarn.js")]
|
|
387
|
+
: []),
|
|
388
|
+
];
|
|
389
|
+
const entryPoint = candidates.find(candidate => fs.existsSync(candidate));
|
|
390
|
+
if (!entryPoint)
|
|
391
|
+
return null;
|
|
392
|
+
const adjacentNode = path.join(root, "node.exe");
|
|
393
|
+
return {
|
|
394
|
+
command: fs.existsSync(adjacentNode) ? adjacentNode : process.execPath,
|
|
395
|
+
args: [entryPoint, ...args],
|
|
396
|
+
};
|
|
226
397
|
}
|
|
227
398
|
async function resolveWindowsCommand(command) {
|
|
228
399
|
if (path.isAbsolute(command)) {
|
|
229
400
|
return command;
|
|
230
401
|
}
|
|
402
|
+
const resolvedFromPath = resolveWindowsCommandFromPath(command);
|
|
403
|
+
if (resolvedFromPath) {
|
|
404
|
+
return resolvedFromPath;
|
|
405
|
+
}
|
|
231
406
|
try {
|
|
232
407
|
const result = await execFileAsync("where.exe", [command], { timeout: 2000 });
|
|
233
408
|
return chooseWindowsCommandCandidate(result.stdout.split(/\r?\n/));
|
|
@@ -236,6 +411,40 @@ async function resolveWindowsCommand(command) {
|
|
|
236
411
|
return null;
|
|
237
412
|
}
|
|
238
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Resolves Windows commands without spawning where.exe. Runtime launches can
|
|
416
|
+
* happen while the machine is under enough process pressure for where.exe to
|
|
417
|
+
* miss its timeout; returning the unresolved package-manager name in that case
|
|
418
|
+
* makes Node fall back to a shell shim that cannot survive Job Object wrapping.
|
|
419
|
+
*/
|
|
420
|
+
export function resolveWindowsCommandFromPath(command, pathValue = process.env.PATH ?? "", pathExtValue = process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD") {
|
|
421
|
+
if (!command || path.isAbsolute(command) || command.includes("/") || command.includes("\\")) {
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
424
|
+
const hasExtension = path.extname(command).length > 0;
|
|
425
|
+
const extensions = hasExtension
|
|
426
|
+
? [""]
|
|
427
|
+
: [...new Set([
|
|
428
|
+
"",
|
|
429
|
+
".exe",
|
|
430
|
+
".ps1",
|
|
431
|
+
".cmd",
|
|
432
|
+
".bat",
|
|
433
|
+
...pathExtValue.split(";").map(value => value.trim().toLowerCase()).filter(Boolean),
|
|
434
|
+
])];
|
|
435
|
+
const candidates = [];
|
|
436
|
+
for (const rawDirectory of pathValue.split(path.delimiter)) {
|
|
437
|
+
const directory = rawDirectory.trim().replace(/^"|"$/gu, "");
|
|
438
|
+
if (!directory)
|
|
439
|
+
continue;
|
|
440
|
+
for (const extension of extensions) {
|
|
441
|
+
const candidate = path.join(directory, `${command}${extension}`);
|
|
442
|
+
if (fs.existsSync(candidate))
|
|
443
|
+
candidates.push(candidate);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
return chooseWindowsCommandCandidate(candidates);
|
|
447
|
+
}
|
|
239
448
|
export function chooseWindowsCommandCandidate(candidates) {
|
|
240
449
|
const normalized = candidates
|
|
241
450
|
.map((candidate) => candidate.trim())
|
|
@@ -2,18 +2,30 @@ import { completionPhaseFromDispatch, type CompletionToolRuntime } from "../phas
|
|
|
2
2
|
import type { RunOnceDispatchPacket } from "../session.types.js";
|
|
3
3
|
import type { ProviderCliCommand } from "./provider-cli.process.js";
|
|
4
4
|
export declare function buildDraftSpec(dispatch: RunOnceDispatchPacket): string;
|
|
5
|
-
export
|
|
5
|
+
export interface DraftAttachmentPromptReference {
|
|
6
|
+
readonly index: number;
|
|
7
|
+
readonly path: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildDraftPrompt(dispatch: RunOnceDispatchPacket, options?: {
|
|
10
|
+
readonly attachmentReferences?: readonly DraftAttachmentPromptReference[];
|
|
11
|
+
}): string;
|
|
12
|
+
export declare function durableDraftInput(dispatch: RunOnceDispatchPacket): RunOnceDispatchPacket["draft"];
|
|
6
13
|
export declare function isDecomposeDraftKind(kind: string | null | undefined): boolean;
|
|
7
14
|
export declare function isDecomposeDraftDispatch(dispatch: RunOnceDispatchPacket): boolean;
|
|
8
15
|
export declare function formatProviderCliCommand(command: ProviderCliCommand): string;
|
|
16
|
+
export declare function formatProviderCliCommandForCheckpoint(command: ProviderCliCommand): string;
|
|
9
17
|
export declare function singleLine(value: string): string;
|
|
10
18
|
export declare function buildProviderCliCommand(dispatch: RunOnceDispatchPacket, run?: {
|
|
11
19
|
readonly prompt?: string;
|
|
20
|
+
readonly promptFromStdin?: boolean;
|
|
12
21
|
readonly worktreePath?: string;
|
|
13
22
|
readonly completionTools?: CompletionToolRuntime;
|
|
14
23
|
readonly skipGitRepoCheck?: boolean;
|
|
24
|
+
readonly imagePaths?: readonly string[];
|
|
25
|
+
readonly runtimeEnvironment?: Readonly<Record<string, string>>;
|
|
15
26
|
}): ProviderCliCommand;
|
|
16
|
-
export declare function
|
|
27
|
+
export declare function buildProviderCliPrompt(dispatch: RunOnceDispatchPacket, prompt: string, runtimeEnvironment?: Readonly<Record<string, string>>): string;
|
|
28
|
+
export declare function codexSandboxModeForPlatform(platform?: NodeJS.Platform, executionMode?: string): "workspace-write" | "danger-full-access";
|
|
17
29
|
export declare function buildArchitectPrompt(dispatch: RunOnceDispatchPacket): string;
|
|
18
30
|
export declare function architectDependencyInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
19
31
|
export declare function designerRefInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
@@ -29,5 +41,7 @@ export declare function qaBrowserInstruction(dispatch: RunOnceDispatchPacket): s
|
|
|
29
41
|
export declare function storyQaInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
30
42
|
export declare function buildQaPrompt(dispatch: RunOnceDispatchPacket, laneSpec: string): string;
|
|
31
43
|
export declare function buildConflictResolvePrompt(dispatch: RunOnceDispatchPacket, branchName: string): string;
|
|
44
|
+
export declare function buildPullRequestCheckRepairPrompt(dispatch: RunOnceDispatchPacket, branchName: string): string;
|
|
32
45
|
export declare function buildPullRequestCommentsPrompt(dispatch: RunOnceDispatchPacket, branchName: string): string;
|
|
46
|
+
export declare function isPullRequestCheckRepairDispatch(dispatch: RunOnceDispatchPacket): boolean;
|
|
33
47
|
export declare function isPullRequestCommentsDispatch(dispatch: RunOnceDispatchPacket): boolean;
|