acpx 0.19.0 → 0.19.1
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/dist/{agent-registry-Ct2yWPW7.js → agent-registry-DWlx5BQ4.js} +3 -2
- package/dist/agent-registry-DWlx5BQ4.js.map +1 -0
- package/dist/agent-registry.js +1 -1
- package/dist/{cli-Bmki9cj5.js → cli-BerngYEz.js} +5 -5
- package/dist/{cli-Bmki9cj5.js.map → cli-BerngYEz.js.map} +1 -1
- package/dist/cli.js +31 -15
- package/dist/cli.js.map +1 -1
- package/dist/{client-DzaUKazo.d.ts → client-BchvQRpz.d.ts} +8 -1
- package/dist/client-BchvQRpz.d.ts.map +1 -0
- package/dist/{flows--Ewxn_fQ.js → flows-DimX0it5.js} +33 -20
- package/dist/flows-DimX0it5.js.map +1 -0
- package/dist/flows.d.ts +2 -1
- package/dist/flows.d.ts.map +1 -1
- package/dist/flows.js +1 -1
- package/dist/{invocation-options-DRzxHZmr.js → invocation-options-vobVApfO.js} +5 -5
- package/dist/{invocation-options-DRzxHZmr.js.map → invocation-options-vobVApfO.js.map} +1 -1
- package/dist/{ipc-fMgj5vrO.js → ipc-DAApJ5mi.js} +536 -57
- package/dist/ipc-DAApJ5mi.js.map +1 -0
- package/dist/{output-D6kDs8BN.js → output-Cnuji8Bo.js} +20 -12
- package/dist/output-Cnuji8Bo.js.map +1 -0
- package/dist/{queue-owner-runtime-CLwjMYNL.js → queue-owner-runtime-C4OOosbo.js} +253 -240
- package/dist/queue-owner-runtime-C4OOosbo.js.map +1 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +5 -5
- package/dist/runtime.js.map +1 -1
- package/dist/{session-watch-BfdIo-n4.js → session-watch-Bj9LoYUq.js} +4 -4
- package/dist/{session-watch-BfdIo-n4.js.map → session-watch-Bj9LoYUq.js.map} +1 -1
- package/dist/{watch-DH-zXQH2.js → watch-Cz6jbrRs.js} +2 -2
- package/dist/{watch-DH-zXQH2.js.map → watch-Cz6jbrRs.js.map} +1 -1
- package/package.json +1 -1
- package/skills/acpx/SKILL.md +2 -0
- package/dist/agent-registry-Ct2yWPW7.js.map +0 -1
- package/dist/client-DzaUKazo.d.ts.map +0 -1
- package/dist/flows--Ewxn_fQ.js.map +0 -1
- package/dist/ipc-fMgj5vrO.js.map +0 -1
- package/dist/output-D6kDs8BN.js.map +0 -1
- package/dist/queue-owner-runtime-CLwjMYNL.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as measurePerf, A as findGitRepositoryRoot, B as writeSessionRecord, Bt as PermissionDeniedError, C as getUnsupportedPromptContentMessage, D as textPrompt, Dt as OUTPUT_ERROR_ORIGINS, E as promptToDisplayText, Et as OUTPUT_ERROR_CODES, Ft as AgentStartupError, G as normalizeAgentSessionId, Gt as SessionModelReplayError, Ht as QueueConnectionError, I as normalizeName, It as AuthPolicyError, Jt as UnsupportedPromptContentError, K as SESSION_JOURNAL_SCHEMA, Lt as ClaudeAcpSessionCreateTimeoutError, M as findSessionByDirectoryWalk, Mt as AcpxOperationalError, N as isoNow$1, Nt as AgentDisconnectedError, Pt as AgentSpawnError, Q as incrementPerfCounter, Rt as CopilotAcpUnsupportedError, St as isAcpResourceNotFoundError, Ut as SessionConfigOptionReplayError, Vt as PermissionPromptUnavailableError, W as extractAgentSessionId, Wt as SessionModeReplayError, X as formatPerfMetric, Z as getPerfMetricsSnapshot, _ as waitMs$1, a as trySetModelOnRunningOwner, at as isAcpJsonRpcMessage, b as lockOwnerPid, bt as extractAcpError, c as queueRequestExceedsLimit, et as recordPerfDuration, f as refreshQueueOwnerLease, ft as defaultSessionEventLog, g as tryAcquireQueueOwnerLease, gt as sessionEventSegmentPath, h as terminateQueueOwnerForSession, ht as sessionEventLockPath, i as trySetModeOnRunningOwner, k as absolutePath, l as parseQueueRequest, m as terminateProcess, mt as sessionEventActivePath, n as tryCloseSessionOnRunningOwner, nt as setPerfGauge, o as trySubmitToRunningOwner, ot as isAcpMessageObject, p as releaseQueueOwnerLease, pt as sessionBaseDir, q as SessionJournalReader, qt as SessionResumeRequiredError, r as trySetConfigOptionOnRunningOwner, rt as startPerfTimer, s as queueRequestByteLimit, st as isSessionUpdateNotification, t as tryCancelOnRunningOwner, tt as resetPerfMetrics, v as QueueLeaseGuardSettlementError, wt as EXIT_CODES, x as
|
|
2
|
-
import { A as
|
|
1
|
+
import { $ as measurePerf, A as findGitRepositoryRoot, B as writeSessionRecord, Bt as PermissionDeniedError, C as getUnsupportedPromptContentMessage, D as textPrompt, Dt as OUTPUT_ERROR_ORIGINS, E as promptToDisplayText, Et as OUTPUT_ERROR_CODES, Ft as AgentStartupError, G as normalizeAgentSessionId, Gt as SessionModelReplayError, Ht as QueueConnectionError, I as normalizeName, It as AuthPolicyError, Jt as UnsupportedPromptContentError, K as SESSION_JOURNAL_SCHEMA, Lt as ClaudeAcpSessionCreateTimeoutError, M as findSessionByDirectoryWalk, Mt as AcpxOperationalError, N as isoNow$1, Nt as AgentDisconnectedError, Pt as AgentSpawnError, Q as incrementPerfCounter, Rt as CopilotAcpUnsupportedError, St as isAcpResourceNotFoundError, Ut as SessionConfigOptionReplayError, Vt as PermissionPromptUnavailableError, W as extractAgentSessionId, Wt as SessionModeReplayError, X as formatPerfMetric, Z as getPerfMetricsSnapshot, _ as waitMs$1, a as trySetModelOnRunningOwner, at as isAcpJsonRpcMessage, b as lockOwnerPid, bt as extractAcpError, c as queueRequestExceedsLimit, et as recordPerfDuration, f as refreshQueueOwnerLease, ft as defaultSessionEventLog, g as tryAcquireQueueOwnerLease, gt as sessionEventSegmentPath, h as terminateQueueOwnerForSession, ht as sessionEventLockPath, i as trySetModeOnRunningOwner, k as absolutePath, l as parseQueueRequest, m as terminateProcess, mt as sessionEventActivePath, n as tryCloseSessionOnRunningOwner, nt as setPerfGauge, o as trySubmitToRunningOwner, ot as isAcpMessageObject, p as releaseQueueOwnerLease, pt as sessionBaseDir, q as SessionJournalReader, qt as SessionResumeRequiredError, r as trySetConfigOptionOnRunningOwner, rt as startPerfTimer, s as queueRequestByteLimit, st as isSessionUpdateNotification, t as tryCancelOnRunningOwner, tt as resetPerfMetrics, v as QueueLeaseGuardSettlementError, wt as EXIT_CODES, x as ProcessDescendants, xt as formatUnknownErrorMessage, y as createLockOwner, yt as isProcessAlive, z as resolveSessionRecord, zt as GeminiAcpStartupTimeoutError } from "./ipc-DAApJ5mi.js";
|
|
2
|
+
import { A as requireAgentStdio, C as PROCESS_HELPER_TIMEOUT_MS, D as isoNow$2, E as isChildProcessRunning, F as waitForChildExit, I as waitForSpawn, M as resolveAgentSessionCwd, N as runTimedExecFile, P as splitCommandLine, T as basenameToken, _ as buildSpawnCommandOptions, b as readWindowsEnvValue, f as resolveBuiltInAgentLaunch, g as buildAgentSpawnCommand, j as resolveAgentCommandParts, v as buildTerminalShellSpawnCommand, w as asAbsoluteCwd, x as resolveWindowsExecutablePath, y as buildTerminalSpawnCommand } from "./agent-registry-DWlx5BQ4.js";
|
|
3
3
|
import fs, { readFileSync, realpathSync } from "node:fs";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import path from "node:path";
|
|
@@ -1080,63 +1080,22 @@ function compareVersionParts(left, right) {
|
|
|
1080
1080
|
}
|
|
1081
1081
|
return 0;
|
|
1082
1082
|
}
|
|
1083
|
-
async function detectGeminiVersion(command) {
|
|
1084
|
-
const versionLine = (await
|
|
1083
|
+
async function detectGeminiVersion(command, context, diagnostic = false) {
|
|
1084
|
+
const versionLine = (await context.readOutput(command, ["--version"], GEMINI_VERSION_TIMEOUT_MS, diagnostic))?.split(/\r?\n/).map((line) => line.trim()).find((line) => /\d+\.\d+\.\d+/.test(line));
|
|
1085
1085
|
return parseGeminiVersion(versionLine);
|
|
1086
1086
|
}
|
|
1087
|
-
async function resolveGeminiCommandArgs(command, args) {
|
|
1087
|
+
async function resolveGeminiCommandArgs(command, args, context) {
|
|
1088
1088
|
if (basenameToken(command) !== "gemini" || !args.includes("--acp")) return [...args];
|
|
1089
|
-
const version = await detectGeminiVersion(command);
|
|
1089
|
+
const version = await detectGeminiVersion(command, context);
|
|
1090
1090
|
if (version && compareVersionParts(version.parts, GEMINI_ACP_FLAG_VERSION) < 0) return args.map((arg) => arg === "--acp" ? "--experimental-acp" : arg);
|
|
1091
1091
|
return [...args];
|
|
1092
1092
|
}
|
|
1093
|
-
async function
|
|
1094
|
-
return await new Promise((resolve) => {
|
|
1095
|
-
const child = spawn(command, [...args], buildSpawnCommandOptions(command, {
|
|
1096
|
-
stdio: [
|
|
1097
|
-
"ignore",
|
|
1098
|
-
"pipe",
|
|
1099
|
-
"pipe"
|
|
1100
|
-
],
|
|
1101
|
-
windowsHide: true
|
|
1102
|
-
}));
|
|
1103
|
-
let stdout = "";
|
|
1104
|
-
let stderr = "";
|
|
1105
|
-
let settled = false;
|
|
1106
|
-
const finish = (value) => {
|
|
1107
|
-
if (settled) return;
|
|
1108
|
-
settled = true;
|
|
1109
|
-
clearTimeout(timer);
|
|
1110
|
-
child.removeAllListeners();
|
|
1111
|
-
child.stdout?.removeAllListeners();
|
|
1112
|
-
child.stderr?.removeAllListeners();
|
|
1113
|
-
resolve(value);
|
|
1114
|
-
};
|
|
1115
|
-
const timer = setTimeout(() => {
|
|
1116
|
-
child.kill("SIGKILL");
|
|
1117
|
-
finish(void 0);
|
|
1118
|
-
}, timeoutMs);
|
|
1119
|
-
child.stdout?.setEncoding("utf8");
|
|
1120
|
-
child.stderr?.setEncoding("utf8");
|
|
1121
|
-
child.stdout?.on("data", (chunk) => {
|
|
1122
|
-
stdout += chunk;
|
|
1123
|
-
});
|
|
1124
|
-
child.stderr?.on("data", (chunk) => {
|
|
1125
|
-
stderr += chunk;
|
|
1126
|
-
});
|
|
1127
|
-
child.once("error", () => {
|
|
1128
|
-
finish(void 0);
|
|
1129
|
-
});
|
|
1130
|
-
child.once("close", () => {
|
|
1131
|
-
finish(`${stdout}\n${stderr}`);
|
|
1132
|
-
});
|
|
1133
|
-
});
|
|
1134
|
-
}
|
|
1135
|
-
async function buildGeminiAcpStartupTimeoutMessage(command) {
|
|
1093
|
+
async function buildGeminiAcpStartupTimeoutMessage(command, context) {
|
|
1136
1094
|
const parts = ["Gemini CLI ACP startup timed out before initialize completed.", "This usually means the local Gemini CLI is waiting on interactive OAuth or has incompatible ACP subprocess behavior."];
|
|
1137
|
-
const version = await detectGeminiVersion(command);
|
|
1095
|
+
const version = await detectGeminiVersion(command, context, true);
|
|
1138
1096
|
if (version) parts.push(`Detected Gemini CLI version: ${version.raw}.`);
|
|
1139
|
-
|
|
1097
|
+
const env = context.env;
|
|
1098
|
+
if (!env.GEMINI_API_KEY && !env.GOOGLE_API_KEY) parts.push("No GEMINI_API_KEY or GOOGLE_API_KEY was set for non-interactive auth.");
|
|
1140
1099
|
parts.push("Try upgrading Gemini CLI and using API-key-based auth for non-interactive ACP runs.");
|
|
1141
1100
|
return parts.join(" ");
|
|
1142
1101
|
}
|
|
@@ -1147,16 +1106,17 @@ function buildClaudeAcpSessionCreateTimeoutMessage() {
|
|
|
1147
1106
|
"In harnessed or non-interactive runs, prefer --approve-all with nonInteractivePermissions=deny, upgrade Claude Code and the Claude ACP adapter, or use acpx claude exec as a one-shot fallback."
|
|
1148
1107
|
].join(" ");
|
|
1149
1108
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1109
|
+
function buildCopilotAcpUnsupportedMessage() {
|
|
1110
|
+
return [
|
|
1111
|
+
"GitHub Copilot CLI ACP stdio mode is not available in the installed copilot binary.",
|
|
1112
|
+
"acpx copilot expects a Copilot CLI release that supports --acp --stdio.",
|
|
1113
|
+
"Detected copilot --help output without --acp support.",
|
|
1114
|
+
"Upgrade GitHub Copilot CLI to a release with ACP stdio support, or use --agent with another ACP-compatible adapter in the meantime."
|
|
1115
|
+
].join(" ");
|
|
1156
1116
|
}
|
|
1157
|
-
async function ensureCopilotAcpSupport(command) {
|
|
1158
|
-
const helpOutput = await
|
|
1159
|
-
if (typeof helpOutput === "string" && !helpOutput.includes("--acp")) throw new CopilotAcpUnsupportedError(
|
|
1117
|
+
async function ensureCopilotAcpSupport(command, context) {
|
|
1118
|
+
const helpOutput = await context.readOutput(command, ["--help"], COPILOT_HELP_TIMEOUT_MS);
|
|
1119
|
+
if (typeof helpOutput === "string" && !helpOutput.includes("--acp")) throw new CopilotAcpUnsupportedError(buildCopilotAcpUnsupportedMessage(), { retryable: false });
|
|
1160
1120
|
}
|
|
1161
1121
|
function buildClaudeCodeOptionsMeta(options, isolateUserSettings = false) {
|
|
1162
1122
|
const claudeCodeOptions = {};
|
|
@@ -1377,6 +1337,73 @@ function resolveClientCapabilities(params) {
|
|
|
1377
1337
|
};
|
|
1378
1338
|
}
|
|
1379
1339
|
//#endregion
|
|
1340
|
+
//#region src/acp/command-probe.ts
|
|
1341
|
+
var CommandProbeAdmissionError = class extends Error {
|
|
1342
|
+
reason;
|
|
1343
|
+
constructor(reason) {
|
|
1344
|
+
super("Agent command admission rejected", { cause: reason });
|
|
1345
|
+
this.reason = reason;
|
|
1346
|
+
this.name = "CommandProbeAdmissionError";
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
async function admitCommandProbe(admit) {
|
|
1350
|
+
try {
|
|
1351
|
+
return await admit();
|
|
1352
|
+
} catch (error) {
|
|
1353
|
+
throw new CommandProbeAdmissionError(error);
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
/** Collect only this short adapter command; its client owns process retirement. */
|
|
1357
|
+
function captureCommandProbeOutput(child, timeoutMs, retire) {
|
|
1358
|
+
let stdout = "";
|
|
1359
|
+
let stderr = "";
|
|
1360
|
+
let settled = false;
|
|
1361
|
+
let disposed = false;
|
|
1362
|
+
let timer;
|
|
1363
|
+
let resolveResult;
|
|
1364
|
+
const result = new Promise((resolve) => {
|
|
1365
|
+
resolveResult = resolve;
|
|
1366
|
+
});
|
|
1367
|
+
const finish = (value) => {
|
|
1368
|
+
if (settled) return;
|
|
1369
|
+
settled = true;
|
|
1370
|
+
clearTimeout(timer);
|
|
1371
|
+
resolveResult(value);
|
|
1372
|
+
};
|
|
1373
|
+
const fail = () => {
|
|
1374
|
+
if (disposed) return;
|
|
1375
|
+
finish(void 0);
|
|
1376
|
+
retire().catch(() => {});
|
|
1377
|
+
};
|
|
1378
|
+
const onStdout = (chunk) => {
|
|
1379
|
+
if (!settled) stdout += chunk;
|
|
1380
|
+
};
|
|
1381
|
+
const onStderr = (chunk) => {
|
|
1382
|
+
if (!settled) stderr += chunk;
|
|
1383
|
+
};
|
|
1384
|
+
const onClose = () => finish(`${stdout}\n${stderr}`);
|
|
1385
|
+
child.stdout?.setEncoding("utf8");
|
|
1386
|
+
child.stderr?.setEncoding("utf8");
|
|
1387
|
+
child.stdout?.on("data", onStdout);
|
|
1388
|
+
child.stderr?.on("data", onStderr);
|
|
1389
|
+
child.on("error", fail);
|
|
1390
|
+
child.stdout?.on("error", fail);
|
|
1391
|
+
child.stderr?.on("error", fail);
|
|
1392
|
+
child.once("close", onClose);
|
|
1393
|
+
timer = setTimeout(fail, timeoutMs);
|
|
1394
|
+
return {
|
|
1395
|
+
result,
|
|
1396
|
+
dispose: () => {
|
|
1397
|
+
disposed = true;
|
|
1398
|
+
finish(void 0);
|
|
1399
|
+
clearTimeout(timer);
|
|
1400
|
+
child.stdout?.off("data", onStdout);
|
|
1401
|
+
child.stderr?.off("data", onStderr);
|
|
1402
|
+
child.off("close", onClose);
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
//#endregion
|
|
1380
1407
|
//#region src/acp/model-support.ts
|
|
1381
1408
|
const REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE = "ACP_MODEL_UNSUPPORTED";
|
|
1382
1409
|
const REQUESTED_MODEL_UNSUPPORTED_REASONS = ["missing-capability", "unadvertised-model"];
|
|
@@ -1672,116 +1699,6 @@ function promptRequestOwner(message) {
|
|
|
1672
1699
|
} : void 0;
|
|
1673
1700
|
}
|
|
1674
1701
|
//#endregion
|
|
1675
|
-
//#region src/acp/process-descendants.ts
|
|
1676
|
-
function includeDescendants(table, owned) {
|
|
1677
|
-
let expanded;
|
|
1678
|
-
do {
|
|
1679
|
-
expanded = false;
|
|
1680
|
-
for (const identity of table.values()) {
|
|
1681
|
-
const parent = table.get(identity.parentPid);
|
|
1682
|
-
if (process.platform === "win32" && (!parent || parent.birth > identity.birth)) continue;
|
|
1683
|
-
if (owned.has(identity.parentPid) && !owned.has(identity.pid)) {
|
|
1684
|
-
owned.add(identity.pid);
|
|
1685
|
-
expanded = true;
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
|
-
} while (expanded);
|
|
1689
|
-
}
|
|
1690
|
-
/** Best-effort cleanup for descendants witnessed during this child launch. */
|
|
1691
|
-
var ProcessDescendants = class {
|
|
1692
|
-
child;
|
|
1693
|
-
identities = /* @__PURE__ */ new Map();
|
|
1694
|
-
rootBirth;
|
|
1695
|
-
pending;
|
|
1696
|
-
retired = false;
|
|
1697
|
-
ownProcessGroup;
|
|
1698
|
-
captureGroupAfterExit;
|
|
1699
|
-
groupExitedAt;
|
|
1700
|
-
onRootExit = () => {
|
|
1701
|
-
this.groupExitedAt = Date.now();
|
|
1702
|
-
};
|
|
1703
|
-
constructor(child, options = {}) {
|
|
1704
|
-
this.child = child;
|
|
1705
|
-
this.ownProcessGroup = process.platform !== "win32" && Boolean(options.ownProcessGroup);
|
|
1706
|
-
this.captureGroupAfterExit = this.ownProcessGroup && isChildProcessRunning(child);
|
|
1707
|
-
if (this.ownProcessGroup) child.once("exit", this.onRootExit);
|
|
1708
|
-
}
|
|
1709
|
-
capture(timeoutMs = PROCESS_HELPER_TIMEOUT_MS) {
|
|
1710
|
-
if (this.retired) return Promise.resolve(true);
|
|
1711
|
-
this.pending ??= this.readSnapshot(timeoutMs).finally(() => {
|
|
1712
|
-
this.pending = void 0;
|
|
1713
|
-
});
|
|
1714
|
-
return this.pending;
|
|
1715
|
-
}
|
|
1716
|
-
async readSnapshot(timeoutMs) {
|
|
1717
|
-
const deadline = performance.now() + timeoutMs;
|
|
1718
|
-
const rootWasRunning = isChildProcessRunning(this.child);
|
|
1719
|
-
const captureRootGroup = rootWasRunning || this.captureGroupAfterExit;
|
|
1720
|
-
if (!rootWasRunning) this.captureGroupAfterExit = false;
|
|
1721
|
-
try {
|
|
1722
|
-
const table = await readProcessTable(timeoutMs);
|
|
1723
|
-
if (!this.retired) {
|
|
1724
|
-
table.delete(1);
|
|
1725
|
-
table.delete(process.pid);
|
|
1726
|
-
this.refresh(table, captureRootGroup);
|
|
1727
|
-
if (this.captureGroupAfterExit && !isChildProcessRunning(this.child)) return await this.readSnapshot(Math.max(1, deadline - performance.now()));
|
|
1728
|
-
}
|
|
1729
|
-
return true;
|
|
1730
|
-
} catch {
|
|
1731
|
-
if (!isChildProcessRunning(this.child)) this.captureGroupAfterExit = false;
|
|
1732
|
-
return false;
|
|
1733
|
-
}
|
|
1734
|
-
}
|
|
1735
|
-
refresh(table, rootWasRunning) {
|
|
1736
|
-
const owned = /* @__PURE__ */ new Set();
|
|
1737
|
-
for (const [pid, identity] of this.identities) if (table.get(pid)?.birth === identity.birth) owned.add(pid);
|
|
1738
|
-
this.includeRoot(table, owned);
|
|
1739
|
-
if (this.ownProcessGroup) this.includeProcessGroup(table, owned, rootWasRunning);
|
|
1740
|
-
includeDescendants(table, owned);
|
|
1741
|
-
owned.delete(this.child.pid ?? 0);
|
|
1742
|
-
this.identities = new Map([...table].filter(([pid]) => owned.has(pid)));
|
|
1743
|
-
}
|
|
1744
|
-
includeRoot(table, owned) {
|
|
1745
|
-
const root = this.child.pid;
|
|
1746
|
-
const rootIdentity = root && table.get(root);
|
|
1747
|
-
if (rootIdentity && isChildProcessRunning(this.child)) {
|
|
1748
|
-
this.rootBirth ??= rootIdentity.birth;
|
|
1749
|
-
if (rootIdentity.birth === this.rootBirth) owned.add(rootIdentity.pid);
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
includeProcessGroup(table, owned, rootWasRunning) {
|
|
1753
|
-
const root = this.child.pid;
|
|
1754
|
-
if (root && (rootWasRunning || [...owned].some((pid) => table.get(pid)?.groupPid === root))) {
|
|
1755
|
-
for (const identity of table.values()) if (identity.groupPid === root && (this.groupExitedAt === void 0 || Date.parse(identity.birth) <= this.groupExitedAt)) owned.add(identity.pid);
|
|
1756
|
-
}
|
|
1757
|
-
}
|
|
1758
|
-
async signal(signal, timeoutMs) {
|
|
1759
|
-
if (!await this.capture(timeoutMs) || this.retired) return;
|
|
1760
|
-
for (const pid of this.identities.keys()) try {
|
|
1761
|
-
process.kill(pid, signal);
|
|
1762
|
-
} catch {
|
|
1763
|
-
this.identities.delete(pid);
|
|
1764
|
-
}
|
|
1765
|
-
}
|
|
1766
|
-
hasTrackedProcesses() {
|
|
1767
|
-
return this.identities.size > 0;
|
|
1768
|
-
}
|
|
1769
|
-
async waitForExit(timeoutMs) {
|
|
1770
|
-
const deadline = Date.now() + timeoutMs;
|
|
1771
|
-
do {
|
|
1772
|
-
if (!await this.capture(Math.max(1, deadline - Date.now()))) return false;
|
|
1773
|
-
if (this.identities.size === 0) return true;
|
|
1774
|
-
await setTimeout$1(Math.min(100, Math.max(0, deadline - Date.now())));
|
|
1775
|
-
} while (Date.now() < deadline);
|
|
1776
|
-
return false;
|
|
1777
|
-
}
|
|
1778
|
-
retire() {
|
|
1779
|
-
this.retired = true;
|
|
1780
|
-
this.child.off("exit", this.onRootExit);
|
|
1781
|
-
this.identities.clear();
|
|
1782
|
-
}
|
|
1783
|
-
};
|
|
1784
|
-
//#endregion
|
|
1785
1702
|
//#region src/acp/session-control-errors.ts
|
|
1786
1703
|
const SESSION_CONTROL_UNSUPPORTED_ACP_CODES = /* @__PURE__ */ new Set([-32601, -32602]);
|
|
1787
1704
|
function asRecord$1(value) {
|
|
@@ -2403,26 +2320,13 @@ function childProcessIsRunning(agent) {
|
|
|
2403
2320
|
function cancelledPermissionResponse() {
|
|
2404
2321
|
return { outcome: { outcome: "cancelled" } };
|
|
2405
2322
|
}
|
|
2406
|
-
function shouldSuppressSdkConsoleError(args) {
|
|
2407
|
-
if (args.length === 0) return false;
|
|
2408
|
-
return typeof args[0] === "string" && args[0] === "Error handling request";
|
|
2409
|
-
}
|
|
2410
|
-
function installSdkConsoleErrorSuppression() {
|
|
2411
|
-
const originalConsoleError = console.error;
|
|
2412
|
-
console.error = (...args) => {
|
|
2413
|
-
if (shouldSuppressSdkConsoleError(args)) return;
|
|
2414
|
-
originalConsoleError(...args);
|
|
2415
|
-
};
|
|
2416
|
-
return () => {
|
|
2417
|
-
console.error = originalConsoleError;
|
|
2418
|
-
};
|
|
2419
|
-
}
|
|
2420
2323
|
var AcpClient = class {
|
|
2421
2324
|
options;
|
|
2422
2325
|
connection;
|
|
2423
2326
|
agent;
|
|
2424
2327
|
agentDescendants = /* @__PURE__ */ new WeakMap();
|
|
2425
2328
|
agentCleanups = /* @__PURE__ */ new WeakMap();
|
|
2329
|
+
commandProbes = /* @__PURE__ */ new Set();
|
|
2426
2330
|
initResult;
|
|
2427
2331
|
loadedSessionId;
|
|
2428
2332
|
eventHandlers;
|
|
@@ -2569,11 +2473,11 @@ var AcpClient = class {
|
|
|
2569
2473
|
if (this.hasLiveConnection()) return;
|
|
2570
2474
|
const epoch = await this.waitForPreviousClose();
|
|
2571
2475
|
const maxMessageBytes = readMaxAcpMessageBytes();
|
|
2572
|
-
const launch = await this.resolveAgentLaunchPlan();
|
|
2573
|
-
|
|
2476
|
+
const launch = await this.resolveAgentLaunchPlan(epoch, authority);
|
|
2477
|
+
this.assertCommandProbeActive(epoch, authority);
|
|
2574
2478
|
this.logAgentLaunch(launch);
|
|
2575
2479
|
await this.ensureLaunchSupport(launch);
|
|
2576
|
-
|
|
2480
|
+
this.assertCommandProbeActive(epoch, authority);
|
|
2577
2481
|
const { child, process: startedProcess } = await this.spawnAgentProcess(launch, authority);
|
|
2578
2482
|
if (this.closeEpoch === epoch) {
|
|
2579
2483
|
this.agent = child;
|
|
@@ -2633,12 +2537,29 @@ var AcpClient = class {
|
|
|
2633
2537
|
if (this.closeEpoch !== epoch) throw new Error("ACP client was closed while the agent was starting");
|
|
2634
2538
|
return epoch;
|
|
2635
2539
|
}
|
|
2636
|
-
async resolveAgentLaunchPlan() {
|
|
2540
|
+
async resolveAgentLaunchPlan(epoch, authority) {
|
|
2637
2541
|
const configuredCommand = resolveAgentCommandParts(this.options.agentCommand, this.options.agentArgv);
|
|
2638
2542
|
const resolvedBuiltInLaunch = resolveBuiltInAgentLaunch(this.options.agentCommand);
|
|
2639
2543
|
const spawnCommand = resolvedBuiltInLaunch?.command ?? configuredCommand.command;
|
|
2544
|
+
const spawnOptions = buildAgentSpawnOptions(this.options.cwd, this.options.authCredentials, this.options.sessionOptions?.env, this.options.agentProcessEnv);
|
|
2545
|
+
const commandContext = {
|
|
2546
|
+
env: spawnOptions.env,
|
|
2547
|
+
readOutput: async (command, args, timeoutMs, diagnostic = false) => {
|
|
2548
|
+
try {
|
|
2549
|
+
const output = await this.readAgentCommandOutput(command, args, timeoutMs, spawnOptions, epoch, authority);
|
|
2550
|
+
await admitCommandProbe(() => this.assertCommandProbeActive(epoch, authority));
|
|
2551
|
+
return output;
|
|
2552
|
+
} catch (error) {
|
|
2553
|
+
if (error instanceof CommandProbeAdmissionError) {
|
|
2554
|
+
if (diagnostic) return;
|
|
2555
|
+
throw error.reason;
|
|
2556
|
+
}
|
|
2557
|
+
throw error;
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
};
|
|
2640
2561
|
let args = resolvedBuiltInLaunch?.args ?? configuredCommand.args;
|
|
2641
|
-
args = await resolveGeminiCommandArgs(spawnCommand, args);
|
|
2562
|
+
args = await resolveGeminiCommandArgs(spawnCommand, args, commandContext);
|
|
2642
2563
|
if (isQoderAcpCommand(spawnCommand, args)) args = buildQoderAcpCommandArgs(args, this.options);
|
|
2643
2564
|
return {
|
|
2644
2565
|
spawnCommand,
|
|
@@ -2648,7 +2569,8 @@ var AcpClient = class {
|
|
|
2648
2569
|
geminiAcp: isGeminiAcpCommand(spawnCommand, args),
|
|
2649
2570
|
copilotAcp: isCopilotAcpCommand(spawnCommand, args),
|
|
2650
2571
|
claudeAcp: isClaudeAcpCommand(spawnCommand, args),
|
|
2651
|
-
spawnOptions
|
|
2572
|
+
spawnOptions,
|
|
2573
|
+
commandContext
|
|
2652
2574
|
};
|
|
2653
2575
|
}
|
|
2654
2576
|
logAgentLaunch(plan) {
|
|
@@ -2664,7 +2586,7 @@ var AcpClient = class {
|
|
|
2664
2586
|
this.log(`spawning agent: ${plan.spawnCommand} ${plan.args.join(" ")}`);
|
|
2665
2587
|
}
|
|
2666
2588
|
async ensureLaunchSupport(plan) {
|
|
2667
|
-
if (plan.copilotAcp) await ensureCopilotAcpSupport(plan.spawnCommand);
|
|
2589
|
+
if (plan.copilotAcp) await ensureCopilotAcpSupport(plan.spawnCommand, plan.commandContext);
|
|
2668
2590
|
if (!plan.claudeAcp) return;
|
|
2669
2591
|
const claudeExe = resolveClaudeCodeExecutable(process.platform, plan.spawnOptions.env);
|
|
2670
2592
|
if (claudeExe) {
|
|
@@ -2672,22 +2594,36 @@ var AcpClient = class {
|
|
|
2672
2594
|
this.log(`resolved system Claude Code executable: ${claudeExe}`);
|
|
2673
2595
|
}
|
|
2674
2596
|
}
|
|
2675
|
-
|
|
2676
|
-
const
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2597
|
+
prepareProcessLaunch(command, args, options) {
|
|
2598
|
+
const resolved = buildAgentSpawnCommand(command, args, process.platform, options.env);
|
|
2599
|
+
return {
|
|
2600
|
+
launch: Object.freeze({
|
|
2601
|
+
launchId: randomUUID(),
|
|
2602
|
+
scope: snapshotProcessLaunchScope(this.options.processLaunchScope),
|
|
2603
|
+
command: resolved.command,
|
|
2604
|
+
args: Object.freeze([...resolved.args]),
|
|
2605
|
+
cwd: options.cwd
|
|
2606
|
+
}),
|
|
2607
|
+
windowsVerbatimArguments: resolved.windowsVerbatimArguments
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
startedProcess(launch, pid) {
|
|
2611
|
+
return Object.freeze({
|
|
2612
|
+
...launch,
|
|
2613
|
+
pid,
|
|
2614
|
+
startedAt: isoNow$2()
|
|
2683
2615
|
});
|
|
2616
|
+
}
|
|
2617
|
+
async spawnAgentProcess(plan, authority) {
|
|
2618
|
+
const prepared = this.prepareProcessLaunch(plan.spawnCommand, plan.args, plan.spawnOptions);
|
|
2619
|
+
const { launch } = prepared;
|
|
2684
2620
|
await this.options.processLifecycle?.onBeforeSpawn?.(launch);
|
|
2685
2621
|
assertControlAuthority(authority);
|
|
2686
2622
|
let spawnedChild;
|
|
2687
2623
|
try {
|
|
2688
|
-
spawnedChild = spawn(
|
|
2624
|
+
spawnedChild = spawn(launch.command, [...launch.args], {
|
|
2689
2625
|
...plan.spawnOptions,
|
|
2690
|
-
windowsVerbatimArguments:
|
|
2626
|
+
windowsVerbatimArguments: prepared.windowsVerbatimArguments
|
|
2691
2627
|
});
|
|
2692
2628
|
await waitForSpawn(spawnedChild);
|
|
2693
2629
|
} catch (error) {
|
|
@@ -2706,21 +2642,86 @@ var AcpClient = class {
|
|
|
2706
2642
|
}
|
|
2707
2643
|
return {
|
|
2708
2644
|
child,
|
|
2709
|
-
process:
|
|
2710
|
-
...launch,
|
|
2711
|
-
pid,
|
|
2712
|
-
startedAt: isoNow$2()
|
|
2713
|
-
})
|
|
2645
|
+
process: this.startedProcess(launch, pid)
|
|
2714
2646
|
};
|
|
2715
2647
|
}
|
|
2648
|
+
assertCommandProbeActive(epoch, authority) {
|
|
2649
|
+
assertControlAuthority(authority);
|
|
2650
|
+
if (this.closeEpoch !== epoch) throw new Error("ACP client was closed while the agent was starting");
|
|
2651
|
+
}
|
|
2652
|
+
async readAgentCommandOutput(command, args, timeoutMs, options, epoch, authority) {
|
|
2653
|
+
const prepared = this.prepareProcessLaunch(command, args, options);
|
|
2654
|
+
const { launch } = prepared;
|
|
2655
|
+
await admitCommandProbe(async () => {
|
|
2656
|
+
this.assertCommandProbeActive(epoch, authority);
|
|
2657
|
+
await this.options.processLifecycle?.onBeforeSpawn?.(launch);
|
|
2658
|
+
});
|
|
2659
|
+
try {
|
|
2660
|
+
this.assertCommandProbeActive(epoch, authority);
|
|
2661
|
+
} catch (error) {
|
|
2662
|
+
throw new CommandProbeAdmissionError(error);
|
|
2663
|
+
}
|
|
2664
|
+
let child;
|
|
2665
|
+
try {
|
|
2666
|
+
child = spawn(launch.command, [...launch.args], {
|
|
2667
|
+
cwd: options.cwd,
|
|
2668
|
+
env: options.env,
|
|
2669
|
+
stdio: [
|
|
2670
|
+
"ignore",
|
|
2671
|
+
"pipe",
|
|
2672
|
+
"pipe"
|
|
2673
|
+
],
|
|
2674
|
+
windowsHide: true,
|
|
2675
|
+
windowsVerbatimArguments: prepared.windowsVerbatimArguments,
|
|
2676
|
+
detached: process.platform !== "win32"
|
|
2677
|
+
});
|
|
2678
|
+
} catch (error) {
|
|
2679
|
+
this.notifyProcessSpawnFailure(launch, new AgentSpawnError(command, error));
|
|
2680
|
+
return;
|
|
2681
|
+
}
|
|
2682
|
+
this.commandProbes.add(child);
|
|
2683
|
+
this.agentDescendants.set(child, new ProcessDescendants(child, { ownProcessGroup: true }));
|
|
2684
|
+
const capture = captureCommandProbeOutput(child, timeoutMs, () => this.terminateAgentProcess(child));
|
|
2685
|
+
try {
|
|
2686
|
+
try {
|
|
2687
|
+
await waitForSpawn(child);
|
|
2688
|
+
} catch (error) {
|
|
2689
|
+
this.notifyProcessSpawnFailure(launch, new AgentSpawnError(command, error));
|
|
2690
|
+
return;
|
|
2691
|
+
}
|
|
2692
|
+
if (child.pid === void 0) {
|
|
2693
|
+
this.notifyProcessSpawnFailure(launch, new AgentSpawnError(command, /* @__PURE__ */ new Error("spawned probe did not expose a PID")));
|
|
2694
|
+
return;
|
|
2695
|
+
}
|
|
2696
|
+
const started = this.startedProcess(launch, child.pid);
|
|
2697
|
+
await this.admitSpawnedProcess(child, (barrier) => this.attachProcessExitObserver(child, started, barrier), () => admitCommandProbe(async () => {
|
|
2698
|
+
await this.options.processLifecycle?.onSpawned?.(started);
|
|
2699
|
+
this.assertCommandProbeActive(epoch, authority);
|
|
2700
|
+
}));
|
|
2701
|
+
const output = await capture.result;
|
|
2702
|
+
await admitCommandProbe(() => this.assertCommandProbeActive(epoch, authority));
|
|
2703
|
+
return output;
|
|
2704
|
+
} finally {
|
|
2705
|
+
try {
|
|
2706
|
+
await this.terminateAgentProcess(child);
|
|
2707
|
+
} finally {
|
|
2708
|
+
capture.dispose();
|
|
2709
|
+
this.commandProbes.delete(child);
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
}
|
|
2716
2713
|
async admitAndObserveSpawnedProcess(child, process) {
|
|
2714
|
+
await this.admitSpawnedProcess(child, (barrier) => this.attachAgentLifecycleObservers(child, process, barrier), async () => {
|
|
2715
|
+
await this.options.processLifecycle?.onSpawned?.(process);
|
|
2716
|
+
});
|
|
2717
|
+
}
|
|
2718
|
+
async admitSpawnedProcess(child, observe, admit) {
|
|
2717
2719
|
let releaseExitNotification = () => {};
|
|
2718
|
-
|
|
2720
|
+
observe(new Promise((resolve) => {
|
|
2719
2721
|
releaseExitNotification = resolve;
|
|
2720
|
-
});
|
|
2721
|
-
this.attachAgentLifecycleObservers(child, process, exitNotificationBarrier);
|
|
2722
|
+
}));
|
|
2722
2723
|
try {
|
|
2723
|
-
await
|
|
2724
|
+
await admit();
|
|
2724
2725
|
} catch (error) {
|
|
2725
2726
|
await this.terminateAgentProcess(child);
|
|
2726
2727
|
throw error;
|
|
@@ -2786,7 +2787,7 @@ var AcpClient = class {
|
|
|
2786
2787
|
await this.captureAgentDescendants(params.child);
|
|
2787
2788
|
const normalizedError = error instanceof AcpMessageLimitError ? error : await this.normalizeInitializeError(error, params.child, params.startupStderr);
|
|
2788
2789
|
await this.terminateAgentProcess(params.child);
|
|
2789
|
-
if (params.launch.geminiAcp && error instanceof TimeoutError) throw new GeminiAcpStartupTimeoutError(await buildGeminiAcpStartupTimeoutMessage(params.launch.spawnCommand), {
|
|
2790
|
+
if (params.launch.geminiAcp && error instanceof TimeoutError) throw new GeminiAcpStartupTimeoutError(await buildGeminiAcpStartupTimeoutMessage(params.launch.spawnCommand, params.launch.commandContext), {
|
|
2790
2791
|
cause: error,
|
|
2791
2792
|
retryable: true
|
|
2792
2793
|
});
|
|
@@ -2896,7 +2897,6 @@ var AcpClient = class {
|
|
|
2896
2897
|
async prompt(sessionId, prompt, onRequestWritten, onElicitation, onPermissionRequest, authority) {
|
|
2897
2898
|
const connection = this.getConnection();
|
|
2898
2899
|
const normalizedPrompt = this.normalizePromptForAgent(prompt);
|
|
2899
|
-
const restoreConsoleError = this.options.suppressSdkConsoleErrors ? installSdkConsoleErrorSuppression() : void 0;
|
|
2900
2900
|
const previousActivePrompt = this.activePrompt;
|
|
2901
2901
|
const replacedOwners = this.pendingPromptOwners.filter((owner) => owner.sessionId === sessionId);
|
|
2902
2902
|
const activePrompt = this.beginActivePrompt(sessionId, onRequestWritten, onElicitation, onPermissionRequest, authority);
|
|
@@ -2914,7 +2914,6 @@ var AcpClient = class {
|
|
|
2914
2914
|
this.throwPromptPermissionFailureIfPresent(sessionId);
|
|
2915
2915
|
throw error;
|
|
2916
2916
|
} finally {
|
|
2917
|
-
restoreConsoleError?.();
|
|
2918
2917
|
this.clearActivePrompt(activePrompt);
|
|
2919
2918
|
}
|
|
2920
2919
|
}
|
|
@@ -3133,18 +3132,15 @@ var AcpClient = class {
|
|
|
3133
3132
|
this.agent = void 0;
|
|
3134
3133
|
}
|
|
3135
3134
|
async retireNativeResources() {
|
|
3136
|
-
const
|
|
3135
|
+
const owned = [...this.commandProbes, ...this.agent ? [this.agent] : []];
|
|
3137
3136
|
const failures = [];
|
|
3138
3137
|
try {
|
|
3139
3138
|
await this.terminalManager.shutdown();
|
|
3140
3139
|
} catch (error) {
|
|
3141
3140
|
failures.push(error);
|
|
3142
3141
|
}
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
} catch (error) {
|
|
3146
|
-
failures.push(error);
|
|
3147
|
-
}
|
|
3142
|
+
const retired = await Promise.allSettled(owned.map((child) => this.terminateAgentProcess(child)));
|
|
3143
|
+
for (const result of retired) if (result.status === "rejected") failures.push(result.reason);
|
|
3148
3144
|
try {
|
|
3149
3145
|
this.closeConnection();
|
|
3150
3146
|
} finally {
|
|
@@ -3170,6 +3166,11 @@ var AcpClient = class {
|
|
|
3170
3166
|
if (descendants && !await descendants.capture()) this.log("could not verify agent descendants; skipping unverified process cleanup");
|
|
3171
3167
|
}
|
|
3172
3168
|
terminateAgentProcess(child) {
|
|
3169
|
+
if (child.pid === void 0) {
|
|
3170
|
+
this.agentDescendants.get(child)?.retire();
|
|
3171
|
+
this.detachAgentHandles(child, true);
|
|
3172
|
+
return Promise.resolve();
|
|
3173
|
+
}
|
|
3173
3174
|
let cleanup = this.agentCleanups.get(child);
|
|
3174
3175
|
if (!cleanup) {
|
|
3175
3176
|
cleanup = Promise.resolve().then(() => this.cleanupAgentProcess(child));
|
|
@@ -3179,12 +3180,12 @@ var AcpClient = class {
|
|
|
3179
3180
|
}
|
|
3180
3181
|
async cleanupAgentProcess(child) {
|
|
3181
3182
|
const descendants = this.agentDescendants.get(child);
|
|
3182
|
-
const deadline =
|
|
3183
|
+
const deadline = performance.now() + AGENT_CLEANUP_BUDGET_MS;
|
|
3183
3184
|
const stdinCloseGraceMs = resolveAgentCloseAfterStdinEndMs(this.options.agentCommand);
|
|
3184
3185
|
try {
|
|
3185
|
-
if (descendants) await descendants.capture(Math.max(1, deadline -
|
|
3186
|
+
if (descendants) await descendants.capture(Math.max(1, deadline - performance.now()));
|
|
3186
3187
|
this.endAgentStdin(child);
|
|
3187
|
-
await waitForChildExit(child, Math.min(stdinCloseGraceMs, Math.max(0, deadline -
|
|
3188
|
+
await waitForChildExit(child, Math.min(stdinCloseGraceMs, Math.max(0, deadline - performance.now())));
|
|
3188
3189
|
if (!await this.signalAgentAndDescendants(child, "SIGTERM", AGENT_CLOSE_TERM_GRACE_MS, deadline)) {
|
|
3189
3190
|
this.log("agent processes did not exit after SIGTERM; forcing SIGKILL");
|
|
3190
3191
|
await this.signalAgentAndDescendants(child, "SIGKILL", AGENT_CLOSE_KILL_GRACE_MS, deadline);
|
|
@@ -3195,18 +3196,18 @@ var AcpClient = class {
|
|
|
3195
3196
|
}
|
|
3196
3197
|
}
|
|
3197
3198
|
endAgentStdin(child) {
|
|
3198
|
-
if (child.stdin.destroyed) return;
|
|
3199
|
+
if (!child.stdin || child.stdin.destroyed) return;
|
|
3199
3200
|
try {
|
|
3200
3201
|
child.stdin.end();
|
|
3201
3202
|
} catch {}
|
|
3202
3203
|
}
|
|
3203
3204
|
async signalAgentAndDescendants(child, signal, waitMs, deadline) {
|
|
3204
3205
|
const descendants = this.agentDescendants.get(child);
|
|
3205
|
-
if (descendants &&
|
|
3206
|
+
if (descendants && performance.now() < deadline) await descendants.signal(signal, deadline - performance.now());
|
|
3206
3207
|
if (isChildProcessRunning(child)) try {
|
|
3207
3208
|
child.kill(signal);
|
|
3208
3209
|
} catch {}
|
|
3209
|
-
const remaining = Math.min(waitMs, Math.max(0, deadline -
|
|
3210
|
+
const remaining = Math.min(waitMs, Math.max(0, deadline - performance.now()));
|
|
3210
3211
|
const [exited, descendantsExited] = await Promise.all([waitForChildExit(child, remaining), descendants ? descendants.waitForExit(remaining) : Promise.resolve(true)]);
|
|
3211
3212
|
return exited && descendantsExited;
|
|
3212
3213
|
}
|
|
@@ -3516,19 +3517,10 @@ var AcpClient = class {
|
|
|
3516
3517
|
return cancelledPermissionResponse();
|
|
3517
3518
|
}
|
|
3518
3519
|
attachAgentLifecycleObservers(child, startedProcess, exitNotificationBarrier) {
|
|
3519
|
-
|
|
3520
|
-
const exitedAt = isoNow$2();
|
|
3520
|
+
this.attachProcessExitObserver(child, startedProcess, exitNotificationBarrier, (exitCode, signal) => {
|
|
3521
3521
|
this.handleAgentDisconnect(child, "process_exit", exitCode, signal);
|
|
3522
3522
|
this.terminateAgentProcess(child);
|
|
3523
|
-
|
|
3524
|
-
this.notifyProcessExit(startedProcess, exitCode, signal, exitedAt);
|
|
3525
|
-
});
|
|
3526
|
-
};
|
|
3527
|
-
child.once("exit", onExit);
|
|
3528
|
-
if (child.exitCode !== null || child.signalCode !== null) {
|
|
3529
|
-
child.off("exit", onExit);
|
|
3530
|
-
onExit(child.exitCode, child.signalCode);
|
|
3531
|
-
}
|
|
3523
|
+
});
|
|
3532
3524
|
child.once("close", (exitCode, signal) => {
|
|
3533
3525
|
this.handleAgentDisconnect(child, "process_close", exitCode, signal);
|
|
3534
3526
|
});
|
|
@@ -3536,6 +3528,18 @@ var AcpClient = class {
|
|
|
3536
3528
|
this.handleAgentDisconnect(child, "pipe_close", child.exitCode ?? null, child.signalCode ?? null);
|
|
3537
3529
|
});
|
|
3538
3530
|
}
|
|
3531
|
+
attachProcessExitObserver(child, started, barrier, onProcessExit) {
|
|
3532
|
+
const onExit = (exitCode, signal) => {
|
|
3533
|
+
const exitedAt = isoNow$2();
|
|
3534
|
+
onProcessExit?.(exitCode, signal);
|
|
3535
|
+
barrier.then(() => this.notifyProcessExit(started, exitCode, signal, exitedAt));
|
|
3536
|
+
};
|
|
3537
|
+
child.once("exit", onExit);
|
|
3538
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
3539
|
+
child.off("exit", onExit);
|
|
3540
|
+
onExit(child.exitCode, child.signalCode);
|
|
3541
|
+
}
|
|
3542
|
+
}
|
|
3539
3543
|
handleAgentDisconnect(child, reason, exitCode, signal) {
|
|
3540
3544
|
this.recordAgentExit(child, reason, exitCode, signal);
|
|
3541
3545
|
if (this.agent !== child || this.closing || !this.connection) return;
|
|
@@ -4353,6 +4357,11 @@ function mergeSessionOptions(preferred, fallback) {
|
|
|
4353
4357
|
assignDefinedOption(merged, "env", mergeEnvRecords(fallback?.env, preferred?.env));
|
|
4354
4358
|
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
4355
4359
|
}
|
|
4360
|
+
function normalizeSessionOptionShape(options) {
|
|
4361
|
+
const normalized = mergeSessionOptions(options, void 0);
|
|
4362
|
+
if (normalized?.env !== void 0 && Object.keys(normalized.env).length === 0) delete normalized.env;
|
|
4363
|
+
return normalized && Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
4364
|
+
}
|
|
4356
4365
|
function mergeEnvRecords(fallback, preferred) {
|
|
4357
4366
|
if (!fallback && !preferred) return;
|
|
4358
4367
|
return {
|
|
@@ -6964,10 +6973,11 @@ var QueueTaskOutputFormatter = class {
|
|
|
6964
6973
|
this.send = task.send;
|
|
6965
6974
|
}
|
|
6966
6975
|
setContext(_context) {}
|
|
6967
|
-
onAcpMessage(message) {
|
|
6976
|
+
onAcpMessage(message, direction) {
|
|
6968
6977
|
this.send({
|
|
6969
6978
|
type: "event",
|
|
6970
6979
|
requestId: this.requestId,
|
|
6980
|
+
...direction === void 0 ? {} : { direction },
|
|
6971
6981
|
message
|
|
6972
6982
|
});
|
|
6973
6983
|
}
|
|
@@ -7024,7 +7034,7 @@ var AcpErrorTracker = class {
|
|
|
7024
7034
|
this.outbound.length = 0;
|
|
7025
7035
|
}
|
|
7026
7036
|
observe(output, direction, message) {
|
|
7027
|
-
output.onAcpMessage(message);
|
|
7037
|
+
output.onAcpMessage(message, direction);
|
|
7028
7038
|
const acp = extractAcpError(message);
|
|
7029
7039
|
if (!acp) return;
|
|
7030
7040
|
if (direction === "inbound") {
|
|
@@ -7852,6 +7862,9 @@ async function runOnce(options, control) {
|
|
|
7852
7862
|
try {
|
|
7853
7863
|
await closeOwnedClient();
|
|
7854
7864
|
} finally {
|
|
7865
|
+
try {
|
|
7866
|
+
options.onPermissionStats?.(client.getPermissionStats());
|
|
7867
|
+
} catch {}
|
|
7855
7868
|
output.flush();
|
|
7856
7869
|
}
|
|
7857
7870
|
}
|
|
@@ -8291,6 +8304,6 @@ async function sendSession(options) {
|
|
|
8291
8304
|
}
|
|
8292
8305
|
const queueOwnerRuntimeTestInternals = { queueOwnerExitIsFatal };
|
|
8293
8306
|
//#endregion
|
|
8294
|
-
export {
|
|
8307
|
+
export { isRequestedModelUnsupportedError as $, applyInitialModelSelection as A, reconcileAgentSessionId as B, setSessionModeOnOwner as C, connectAndLoadSession as D, withConnectedSession as E, persistSessionOptions as F, recordPromptSubmission as G, cloneSessionConversation as H, sessionOptionsFromRecord as I, advertisedModelState as J, recordSessionUpdate as K, applyConversation as L, applyRequestedModelIfAdvertised as M, setDesiredModeId as N, applyConfigOptionSelection as O, normalizeSessionOptionShape as P, RequestedModelUnsupportedError as Q, applyLifecycleSnapshotToRecord as R, setSessionMode as S, setSessionModelOnOwner as T, createSessionConversation as U, cloneSessionAcpxState as V, recordClientOperation as W, REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE as X, AcpClient as Y, REQUESTED_MODEL_UNSUPPORTED_REASONS as Z, cancelSessionPrompt as _, runQueuedTask as a, isLegacyZedCodexAcpInvocation as at, setSessionConfigOption as b, LiveSessionCheckpoint as c, assertControlAuthority as ct, flushPerfMetricsCapture as d, exitCodeForOutputErrorCode as dt, getAcpxVersion as et, installPerfMetricsCapture as f, normalizeOutputError as ft, listAgentSessions as g, ensureSession as h, runOnce as i, listSessionEvents as it, applyModelSelection as j, applyConfigOptionsToRecord as k, runPromptTurn as l, withInterrupt as lt, createSessionWithClient as m, runSessionQueueOwner as n, DEFAULT_QUEUE_OWNER_TTL_MS as nt, sendSessionDirect as o, InterruptedError as ot, createSession as p, trimConversationForRuntime as q, sendSession as r, normalizeQueueOwnerTtlMs as rt, DISCARD_OUTPUT_FORMATTER as s, TimeoutError as st, queueOwnerRuntimeTestInternals as t, permissionModeSatisfies as tt, buildQueueOwnerArgOverride as u, withTimeout as ut, closeSession as v, setSessionModel as w, setSessionConfigOptionOnOwner as x, sessionControlTestInternals as y, createInitialSessionRecord as z };
|
|
8295
8308
|
|
|
8296
|
-
//# sourceMappingURL=queue-owner-runtime-
|
|
8309
|
+
//# sourceMappingURL=queue-owner-runtime-C4OOosbo.js.map
|