@loucompanion/forge-bridge 0.1.3-dev.b6be5e7f9668 → 0.1.3-dev.ba7d36726eda
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 +5 -1
- package/dist/bridge/bridge.service.d.ts +52 -3
- package/dist/bridge/bridge.service.js +796 -22
- package/dist/bridge/bridge.types.d.ts +135 -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.d.ts +2 -0
- package/dist/cli/cli.help.js +217 -0
- package/dist/cli/cli.service.d.ts +42 -2
- package/dist/cli/cli.service.js +356 -205
- package/dist/cli/local-config.d.ts +6 -0
- package/dist/cli/local-config.js +45 -2
- package/dist/runtime/attempt-node-runtime-launcher.d.ts +15 -0
- package/dist/runtime/attempt-node-runtime-launcher.js +50 -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 +74 -0
- package/dist/runtime/attempt-process-supervisor.js +290 -0
- package/dist/runtime/host-listener-inspector.d.ts +28 -0
- package/dist/runtime/host-listener-inspector.js +185 -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 +39 -0
- package/dist/runtime/host-runtime-contract.js +295 -0
- package/dist/runtime/host-runtime-lease.d.ts +122 -0
- package/dist/runtime/host-runtime-lease.js +1241 -0
- package/dist/runtime/host-runtime-promotion.d.ts +21 -0
- package/dist/runtime/host-runtime-promotion.js +128 -0
- package/dist/runtime/node-host-runtime-adapter.d.ts +44 -0
- package/dist/runtime/node-host-runtime-adapter.js +205 -0
- package/dist/runtime/playwright-host-runtime-adapter.d.ts +20 -0
- package/dist/runtime/playwright-host-runtime-adapter.js +136 -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 +45 -0
- package/dist/sandbox/preflight.js +300 -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 +67 -0
- package/dist/session/phase-completion.artifacts.d.ts +10 -0
- package/dist/session/phase-completion.artifacts.js +620 -0
- package/dist/session/phase-completion.d.ts +32 -44
- package/dist/session/phase-completion.helpers.d.ts +112 -0
- package/dist/session/phase-completion.helpers.js +665 -0
- package/dist/session/phase-completion.js +28 -3485
- package/dist/session/phase-completion.prompts.d.ts +14 -0
- package/dist/session/phase-completion.prompts.js +220 -0
- package/dist/session/phase-completion.runtime.d.ts +36 -0
- package/dist/session/phase-completion.runtime.js +611 -0
- package/dist/session/phase-completion.schemas.d.ts +3 -0
- package/dist/session/phase-completion.schemas.js +707 -0
- package/dist/session/phase-completion.validation.d.ts +34 -0
- package/dist/session/phase-completion.validation.js +724 -0
- package/dist/session/provider-cli/provider-cli.artifacts.d.ts +93 -0
- package/dist/session/provider-cli/provider-cli.artifacts.js +778 -0
- package/dist/session/provider-cli/provider-cli.base.d.ts +1 -0
- package/dist/session/provider-cli/provider-cli.deterministic-payloads.d.ts +12 -0
- package/dist/session/provider-cli/provider-cli.deterministic-payloads.js +279 -0
- package/dist/session/provider-cli/provider-cli.deterministic.d.ts +14 -0
- package/dist/session/provider-cli/provider-cli.deterministic.js +329 -0
- package/dist/session/provider-cli/provider-cli.process.d.ts +34 -0
- package/dist/session/provider-cli/provider-cli.process.js +316 -0
- package/dist/session/provider-cli/provider-cli.prompts.d.ts +47 -0
- package/dist/session/provider-cli/provider-cli.prompts.js +573 -0
- package/dist/session/provider-cli/provider-cli.qa-sidecars.d.ts +11 -0
- package/dist/session/provider-cli/provider-cli.qa-sidecars.js +65 -0
- package/dist/session/provider-cli/provider-cli.runtime.d.ts +9 -0
- package/dist/session/provider-cli/provider-cli.runtime.js +41 -0
- package/dist/session/provider-cli/provider-cli.service.d.ts +9 -53
- package/dist/session/provider-cli/provider-cli.service.js +182 -2536
- package/dist/session/provider-cli/provider-cli.types.d.ts +3 -0
- package/dist/session/provider-cli/provider-output-state.d.ts +20 -0
- package/dist/session/provider-cli/provider-output-state.js +445 -0
- package/dist/session/session-redaction.d.ts +3 -0
- package/dist/session/session-redaction.js +23 -0
- package/dist/session/session.base.d.ts +4 -0
- package/dist/session/session.service.d.ts +6 -1
- package/dist/session/session.service.js +202 -53
- package/dist/session/session.types.d.ts +123 -1
- package/dist/session/session.types.js +301 -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 +40 -0
- package/dist/shared/process/host-process-supervisor.js +195 -0
- package/dist/shared/process/windows-launch.d.ts +8 -0
- package/dist/shared/process/windows-launch.js +41 -0
- 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.js +39 -6
- package/dist/worktree/dependency-warmer.d.ts +11 -0
- package/dist/worktree/dependency-warmer.js +45 -1
- 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 +8 -3
- package/dist/worktree/worktree.service.js +89 -52
- package/dist/worktree/worktree.types.d.ts +3 -1
- package/package.json +6 -3
- package/runtime/windows-job-supervisor.ps1 +287 -0
- package/runtime/windows-listener-owner.ps1 +33 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type LaunchCommand } from "../../shared/process/windows-launch.js";
|
|
2
|
+
export type ProviderCliCommand = LaunchCommand;
|
|
3
|
+
export interface ProviderProcessRunRequest {
|
|
4
|
+
readonly command: string;
|
|
5
|
+
readonly args: readonly string[];
|
|
6
|
+
readonly cwd: string;
|
|
7
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
8
|
+
readonly stdin?: string;
|
|
9
|
+
readonly captureOutput?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ProviderProcessRunResult {
|
|
12
|
+
readonly exitCode: number;
|
|
13
|
+
readonly stdout: string;
|
|
14
|
+
readonly stderr: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ProviderProcessRunner {
|
|
17
|
+
run(request: ProviderProcessRunRequest, handlers?: ProviderProcessHandlers, signal?: AbortSignal): Promise<ProviderProcessRunResult>;
|
|
18
|
+
}
|
|
19
|
+
export interface ProviderProcessHandlers {
|
|
20
|
+
onStdoutLine?(line: string): Promise<void> | void;
|
|
21
|
+
onStderrLine?(line: string): Promise<void> | void;
|
|
22
|
+
}
|
|
23
|
+
interface ProviderChildEnvironmentOptions {
|
|
24
|
+
readonly parentEnv?: NodeJS.ProcessEnv;
|
|
25
|
+
readonly platform?: NodeJS.Platform;
|
|
26
|
+
readonly homeDir?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function buildProviderChildEnvironment(requestEnv?: Readonly<Record<string, string>>, options?: ProviderChildEnvironmentOptions): NodeJS.ProcessEnv;
|
|
29
|
+
export declare class StreamingProviderProcessRunner implements ProviderProcessRunner {
|
|
30
|
+
run(request: ProviderProcessRunRequest, handlers?: ProviderProcessHandlers, signal?: AbortSignal): Promise<ProviderProcessRunResult>;
|
|
31
|
+
}
|
|
32
|
+
export declare function resolveCodexNpmDirectLaunch(commandPath: string, args: readonly string[]): LaunchCommand | null;
|
|
33
|
+
export declare function chooseWindowsCommandCandidate(candidates: readonly string[]): string | null;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import readline from "node:readline";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { resolveCursorAgentDirectLaunch } from "../../shared/cursor-agent/cursor-agent.launch.js";
|
|
8
|
+
import { persistHostProcessSupervisorMetadata, resolveHostProcessSupervisedLaunch, terminateHostProcessTree, } from "../../shared/process/host-process-supervisor.js";
|
|
9
|
+
import { buildWindowsLaunchCommand } from "../../shared/process/windows-launch.js";
|
|
10
|
+
const execFileAsync = promisify(execFile);
|
|
11
|
+
const allowedProviderParentEnvNames = [
|
|
12
|
+
"PATH",
|
|
13
|
+
"HOME",
|
|
14
|
+
"USERPROFILE",
|
|
15
|
+
"TMPDIR",
|
|
16
|
+
"TEMP",
|
|
17
|
+
"TMP",
|
|
18
|
+
"LANG"
|
|
19
|
+
];
|
|
20
|
+
const windowsAllowedProviderParentEnvNames = [
|
|
21
|
+
"SystemRoot",
|
|
22
|
+
"SystemDrive",
|
|
23
|
+
"ComSpec",
|
|
24
|
+
"PATHEXT",
|
|
25
|
+
"APPDATA",
|
|
26
|
+
"LOCALAPPDATA",
|
|
27
|
+
"USERNAME",
|
|
28
|
+
"USERDOMAIN",
|
|
29
|
+
"HOMEDRIVE",
|
|
30
|
+
"HOMEPATH",
|
|
31
|
+
"ProgramData",
|
|
32
|
+
"ProgramFiles",
|
|
33
|
+
"ProgramFiles(x86)",
|
|
34
|
+
"ProgramW6432",
|
|
35
|
+
"DOTNET_ROOT",
|
|
36
|
+
"DOTNET_ROOT(x86)",
|
|
37
|
+
"DOTNET_CLI_HOME",
|
|
38
|
+
"NUGET_PACKAGES",
|
|
39
|
+
"NUGET_HTTP_CACHE_PATH"
|
|
40
|
+
];
|
|
41
|
+
export function buildProviderChildEnvironment(requestEnv, options = {}) {
|
|
42
|
+
const parentEnv = options.parentEnv ?? process.env;
|
|
43
|
+
const platform = options.platform ?? process.platform;
|
|
44
|
+
const env = {};
|
|
45
|
+
for (const [key, value] of Object.entries(parentEnv)) {
|
|
46
|
+
if (typeof value === "string" && isAllowedProviderParentEnv(key, platform)) {
|
|
47
|
+
env[key] = value;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (requestEnv) {
|
|
51
|
+
for (const [key, value] of Object.entries(requestEnv)) {
|
|
52
|
+
const trimmedKey = key.trim();
|
|
53
|
+
if (trimmedKey.length > 0) {
|
|
54
|
+
env[trimmedKey] = value;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (platform === "win32") {
|
|
59
|
+
normalizeWindowsDotNetEnvironment(env, parentEnv, options.homeDir ?? os.homedir());
|
|
60
|
+
}
|
|
61
|
+
return env;
|
|
62
|
+
}
|
|
63
|
+
function isAllowedProviderParentEnv(key, platform = process.platform) {
|
|
64
|
+
return isAllowedProviderParentEnvName(key, allowedProviderParentEnvNames)
|
|
65
|
+
|| key.toUpperCase().startsWith("LC_")
|
|
66
|
+
|| (platform === "win32" && isAllowedProviderParentEnvName(key, windowsAllowedProviderParentEnvNames));
|
|
67
|
+
}
|
|
68
|
+
function isAllowedProviderParentEnvName(key, allowedNames) {
|
|
69
|
+
return allowedNames.some((allowed) => allowed.toLowerCase() === key.toLowerCase());
|
|
70
|
+
}
|
|
71
|
+
function normalizeWindowsDotNetEnvironment(env, parentEnv, homeDir) {
|
|
72
|
+
const systemRoot = readEnvironmentValue(env, "SystemRoot") ?? readEnvironmentValue(parentEnv, "SystemRoot") ?? "C:\\Windows";
|
|
73
|
+
const systemDrive = path.win32.parse(systemRoot).root.replace(/\\$/, "") || "C:";
|
|
74
|
+
setEnvironmentValueIfMissing(env, "SystemRoot", systemRoot);
|
|
75
|
+
setEnvironmentValueIfMissing(env, "SystemDrive", readEnvironmentValue(parentEnv, "SystemDrive") ?? systemDrive);
|
|
76
|
+
setEnvironmentValueIfMissing(env, "ComSpec", readEnvironmentValue(parentEnv, "ComSpec") ?? path.win32.join(systemRoot, "System32", "cmd.exe"));
|
|
77
|
+
setEnvironmentValueIfMissing(env, "PATHEXT", readEnvironmentValue(parentEnv, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL");
|
|
78
|
+
const userProfile = resolveWindowsUserProfile(env, parentEnv, homeDir);
|
|
79
|
+
if (userProfile) {
|
|
80
|
+
setEnvironmentValueIfMissing(env, "USERPROFILE", userProfile);
|
|
81
|
+
setEnvironmentValueIfMissing(env, "HOME", userProfile);
|
|
82
|
+
setEnvironmentValueIfMissing(env, "DOTNET_CLI_HOME", userProfile);
|
|
83
|
+
setEnvironmentValueIfMissing(env, "NUGET_PACKAGES", path.win32.join(userProfile, ".nuget", "packages"));
|
|
84
|
+
const parsed = path.win32.parse(userProfile);
|
|
85
|
+
if (parsed.root) {
|
|
86
|
+
setEnvironmentValueIfMissing(env, "HOMEDRIVE", parsed.root.replace(/\\$/, ""));
|
|
87
|
+
setEnvironmentValueIfMissing(env, "HOMEPATH", userProfile.slice(parsed.root.length - (parsed.root.endsWith("\\") ? 1 : 0)) || "\\");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const appData = readEnvironmentValue(env, "APPDATA")
|
|
91
|
+
?? readEnvironmentValue(parentEnv, "APPDATA")
|
|
92
|
+
?? (userProfile ? path.win32.join(userProfile, "AppData", "Roaming") : undefined);
|
|
93
|
+
const localAppData = readEnvironmentValue(env, "LOCALAPPDATA")
|
|
94
|
+
?? readEnvironmentValue(parentEnv, "LOCALAPPDATA")
|
|
95
|
+
?? (userProfile ? path.win32.join(userProfile, "AppData", "Local") : undefined);
|
|
96
|
+
if (appData) {
|
|
97
|
+
setEnvironmentValueIfMissing(env, "APPDATA", appData);
|
|
98
|
+
}
|
|
99
|
+
if (localAppData) {
|
|
100
|
+
setEnvironmentValueIfMissing(env, "LOCALAPPDATA", localAppData);
|
|
101
|
+
setEnvironmentValueIfMissing(env, "NUGET_HTTP_CACHE_PATH", path.win32.join(localAppData, "NuGet", "v3-cache"));
|
|
102
|
+
}
|
|
103
|
+
setEnvironmentValueIfMissing(env, "DOTNET_NOLOGO", "1");
|
|
104
|
+
setEnvironmentValueIfMissing(env, "DOTNET_CLI_TELEMETRY_OPTOUT", "1");
|
|
105
|
+
setEnvironmentValueIfMissing(env, "DOTNET_SKIP_FIRST_TIME_EXPERIENCE", "1");
|
|
106
|
+
setEnvironmentValueIfMissing(env, "NUGET_XMLDOC_MODE", "skip");
|
|
107
|
+
}
|
|
108
|
+
function resolveWindowsUserProfile(env, parentEnv, homeDir) {
|
|
109
|
+
const existing = readEnvironmentValue(env, "USERPROFILE") ?? readEnvironmentValue(parentEnv, "USERPROFILE");
|
|
110
|
+
if (existing) {
|
|
111
|
+
return existing;
|
|
112
|
+
}
|
|
113
|
+
const home = readEnvironmentValue(env, "HOME") ?? readEnvironmentValue(parentEnv, "HOME");
|
|
114
|
+
if (home && path.win32.isAbsolute(home)) {
|
|
115
|
+
return home;
|
|
116
|
+
}
|
|
117
|
+
const homeDrive = readEnvironmentValue(env, "HOMEDRIVE") ?? readEnvironmentValue(parentEnv, "HOMEDRIVE");
|
|
118
|
+
const homePath = readEnvironmentValue(env, "HOMEPATH") ?? readEnvironmentValue(parentEnv, "HOMEPATH");
|
|
119
|
+
if (homeDrive && homePath) {
|
|
120
|
+
return `${homeDrive}${homePath}`;
|
|
121
|
+
}
|
|
122
|
+
if (homeDir && path.win32.isAbsolute(homeDir)) {
|
|
123
|
+
return homeDir;
|
|
124
|
+
}
|
|
125
|
+
const systemDrive = readEnvironmentValue(env, "SystemDrive") ?? readEnvironmentValue(parentEnv, "SystemDrive") ?? "C:";
|
|
126
|
+
const username = readEnvironmentValue(env, "USERNAME") ?? readEnvironmentValue(parentEnv, "USERNAME");
|
|
127
|
+
return username ? path.win32.join(systemDrive, "Users", username) : undefined;
|
|
128
|
+
}
|
|
129
|
+
function readEnvironmentValue(env, name) {
|
|
130
|
+
const entry = Object.entries(env).find(([key]) => key.toLowerCase() === name.toLowerCase());
|
|
131
|
+
const value = entry?.[1];
|
|
132
|
+
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
133
|
+
}
|
|
134
|
+
function setEnvironmentValueIfMissing(env, name, value) {
|
|
135
|
+
if (readEnvironmentValue(env, name)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
env[name] = value;
|
|
139
|
+
}
|
|
140
|
+
export class StreamingProviderProcessRunner {
|
|
141
|
+
async run(request, handlers = {}, signal) {
|
|
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 };
|
|
145
|
+
return await new Promise((resolve, reject) => {
|
|
146
|
+
const rootCreatedAt = new Date().toISOString();
|
|
147
|
+
const child = spawn(launch.command, launch.args, {
|
|
148
|
+
cwd: request.cwd,
|
|
149
|
+
env: buildProviderChildEnvironment(request.env),
|
|
150
|
+
stdio: [request.stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
|
|
151
|
+
windowsHide: true,
|
|
152
|
+
detached: launch.detached,
|
|
153
|
+
});
|
|
154
|
+
let termination = null;
|
|
155
|
+
const terminate = () => {
|
|
156
|
+
termination ??= terminateHostProcessTree(child, supervisedLaunch);
|
|
157
|
+
return termination;
|
|
158
|
+
};
|
|
159
|
+
const childStdout = child.stdout;
|
|
160
|
+
const childStderr = child.stderr;
|
|
161
|
+
if (!childStdout || !childStderr) {
|
|
162
|
+
void terminate();
|
|
163
|
+
reject(new Error("Provider process stdout/stderr streams were not piped."));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
if (supervisedLaunch) {
|
|
168
|
+
persistHostProcessSupervisorMetadata(supervisedLaunch, request, child.pid ?? 0, rootCreatedAt);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
void terminate();
|
|
173
|
+
reject(error);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let stdout = "";
|
|
177
|
+
let stderr = "";
|
|
178
|
+
let settled = false;
|
|
179
|
+
const cleanup = () => {
|
|
180
|
+
signal?.removeEventListener("abort", abort);
|
|
181
|
+
};
|
|
182
|
+
const fail = (error) => {
|
|
183
|
+
if (settled) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
settled = true;
|
|
187
|
+
cleanup();
|
|
188
|
+
void terminate();
|
|
189
|
+
reject(error);
|
|
190
|
+
};
|
|
191
|
+
const abort = () => {
|
|
192
|
+
void terminate();
|
|
193
|
+
};
|
|
194
|
+
if (signal?.aborted) {
|
|
195
|
+
abort();
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
199
|
+
}
|
|
200
|
+
child.on("error", fail);
|
|
201
|
+
if (request.stdin !== undefined) {
|
|
202
|
+
if (!child.stdin) {
|
|
203
|
+
void terminate();
|
|
204
|
+
fail(new Error("Provider process stdin stream was not piped."));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
child.stdin.on("error", (error) => {
|
|
208
|
+
void terminate();
|
|
209
|
+
fail(error);
|
|
210
|
+
});
|
|
211
|
+
child.stdin.end(request.stdin, "utf8");
|
|
212
|
+
}
|
|
213
|
+
const readers = [
|
|
214
|
+
readProcessLines(childStdout, (line) => {
|
|
215
|
+
if (request.captureOutput !== false)
|
|
216
|
+
stdout += `${line}\n`;
|
|
217
|
+
return handlers.onStdoutLine?.(line);
|
|
218
|
+
}),
|
|
219
|
+
readProcessLines(childStderr, (line) => {
|
|
220
|
+
if (request.captureOutput !== false)
|
|
221
|
+
stderr += `${line}\n`;
|
|
222
|
+
return handlers.onStderrLine?.(line);
|
|
223
|
+
})
|
|
224
|
+
];
|
|
225
|
+
child.on("close", (code) => {
|
|
226
|
+
Promise.allSettled(readers).then(async (readerResults) => {
|
|
227
|
+
const rejected = readerResults.find((result) => result.status === "rejected");
|
|
228
|
+
if (rejected?.status === "rejected") {
|
|
229
|
+
fail(rejected.reason);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (settled) {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (supervisedLaunch?.strategy === "unix_process_group") {
|
|
236
|
+
await terminate();
|
|
237
|
+
}
|
|
238
|
+
else if (termination) {
|
|
239
|
+
await termination;
|
|
240
|
+
}
|
|
241
|
+
settled = true;
|
|
242
|
+
cleanup();
|
|
243
|
+
resolve({
|
|
244
|
+
exitCode: code ?? 1,
|
|
245
|
+
stdout,
|
|
246
|
+
stderr
|
|
247
|
+
});
|
|
248
|
+
}).catch(fail);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
async function resolveProviderProcessLaunch(command, args) {
|
|
254
|
+
if (process.platform !== "win32") {
|
|
255
|
+
return { command, args };
|
|
256
|
+
}
|
|
257
|
+
const cursorDirect = await resolveCursorAgentDirectLaunch(command, args);
|
|
258
|
+
if (cursorDirect) {
|
|
259
|
+
return cursorDirect;
|
|
260
|
+
}
|
|
261
|
+
const resolved = await resolveWindowsCommand(command);
|
|
262
|
+
if (!resolved) {
|
|
263
|
+
return { command, args };
|
|
264
|
+
}
|
|
265
|
+
return resolveCodexNpmDirectLaunch(resolved, args) ?? buildWindowsLaunchCommand(resolved, args);
|
|
266
|
+
}
|
|
267
|
+
export function resolveCodexNpmDirectLaunch(commandPath, args) {
|
|
268
|
+
const extension = path.extname(commandPath).toLowerCase();
|
|
269
|
+
if ((extension !== ".cmd" && extension !== ".ps1")
|
|
270
|
+
|| path.basename(commandPath, extension).toLowerCase() !== "codex") {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
const entryPoint = path.join(path.dirname(commandPath), "node_modules", "@openai", "codex", "bin", "codex.js");
|
|
274
|
+
return fs.existsSync(entryPoint)
|
|
275
|
+
? { command: process.execPath, args: [entryPoint, ...args] }
|
|
276
|
+
: null;
|
|
277
|
+
}
|
|
278
|
+
async function resolveWindowsCommand(command) {
|
|
279
|
+
if (path.isAbsolute(command)) {
|
|
280
|
+
return command;
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
const result = await execFileAsync("where.exe", [command], { timeout: 2000 });
|
|
284
|
+
return chooseWindowsCommandCandidate(result.stdout.split(/\r?\n/));
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
export function chooseWindowsCommandCandidate(candidates) {
|
|
291
|
+
const normalized = candidates
|
|
292
|
+
.map((candidate) => candidate.trim())
|
|
293
|
+
.filter((candidate) => candidate.length > 0);
|
|
294
|
+
if (normalized.length === 0) {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
const preferredExtensions = [".exe", ".ps1", ".cmd", ".bat", ""];
|
|
298
|
+
for (const extension of preferredExtensions) {
|
|
299
|
+
const candidate = normalized.find((entry) => path.extname(entry).toLowerCase() === extension);
|
|
300
|
+
if (candidate) {
|
|
301
|
+
return candidate;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return normalized[0];
|
|
305
|
+
}
|
|
306
|
+
async function readProcessLines(stream, onLine) {
|
|
307
|
+
const reader = readline.createInterface({ input: stream });
|
|
308
|
+
try {
|
|
309
|
+
for await (const line of reader) {
|
|
310
|
+
await onLine(line);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
reader.close();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { completionPhaseFromDispatch, type CompletionToolRuntime } from "../phase-completion.js";
|
|
2
|
+
import type { RunOnceDispatchPacket } from "../session.types.js";
|
|
3
|
+
import type { ProviderCliCommand } from "./provider-cli.process.js";
|
|
4
|
+
export declare function buildDraftSpec(dispatch: RunOnceDispatchPacket): string;
|
|
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"];
|
|
13
|
+
export declare function isDecomposeDraftKind(kind: string | null | undefined): boolean;
|
|
14
|
+
export declare function isDecomposeDraftDispatch(dispatch: RunOnceDispatchPacket): boolean;
|
|
15
|
+
export declare function formatProviderCliCommand(command: ProviderCliCommand): string;
|
|
16
|
+
export declare function formatProviderCliCommandForCheckpoint(command: ProviderCliCommand): string;
|
|
17
|
+
export declare function singleLine(value: string): string;
|
|
18
|
+
export declare function buildProviderCliCommand(dispatch: RunOnceDispatchPacket, run?: {
|
|
19
|
+
readonly prompt?: string;
|
|
20
|
+
readonly promptFromStdin?: boolean;
|
|
21
|
+
readonly worktreePath?: string;
|
|
22
|
+
readonly completionTools?: CompletionToolRuntime;
|
|
23
|
+
readonly skipGitRepoCheck?: boolean;
|
|
24
|
+
readonly imagePaths?: readonly string[];
|
|
25
|
+
readonly runtimeEnvironment?: Readonly<Record<string, string>>;
|
|
26
|
+
}): ProviderCliCommand;
|
|
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";
|
|
29
|
+
export declare function buildArchitectPrompt(dispatch: RunOnceDispatchPacket): string;
|
|
30
|
+
export declare function architectDependencyInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
31
|
+
export declare function designerRefInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
32
|
+
export declare function architectRevisionInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
33
|
+
export declare function buildImplementationPrompt(dispatch: RunOnceDispatchPacket, phase?: import("../phase-completion.js").CompletionPhase): string;
|
|
34
|
+
export declare function buildDevelopCyclePrompt(dispatch: RunOnceDispatchPacket, phase?: import("../phase-completion.js").CompletionPhase): string;
|
|
35
|
+
export declare function buildDebugCyclePrompt(dispatch: RunOnceDispatchPacket, phase?: import("../phase-completion.js").CompletionPhase): string;
|
|
36
|
+
export declare function qaReworkImplementationInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
37
|
+
export declare function debugQaReworkInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
38
|
+
export declare function qaReworkRetestInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
39
|
+
export declare function phaseWorkInstruction(phase: ReturnType<typeof completionPhaseFromDispatch>): string;
|
|
40
|
+
export declare function qaBrowserInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
41
|
+
export declare function storyQaInstruction(dispatch: RunOnceDispatchPacket): string;
|
|
42
|
+
export declare function buildQaPrompt(dispatch: RunOnceDispatchPacket, laneSpec: string): string;
|
|
43
|
+
export declare function buildConflictResolvePrompt(dispatch: RunOnceDispatchPacket, branchName: string): string;
|
|
44
|
+
export declare function buildPullRequestCheckRepairPrompt(dispatch: RunOnceDispatchPacket, branchName: string): string;
|
|
45
|
+
export declare function buildPullRequestCommentsPrompt(dispatch: RunOnceDispatchPacket, branchName: string): string;
|
|
46
|
+
export declare function isPullRequestCheckRepairDispatch(dispatch: RunOnceDispatchPacket): boolean;
|
|
47
|
+
export declare function isPullRequestCommentsDispatch(dispatch: RunOnceDispatchPacket): boolean;
|