acpx 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -4
- package/dist/{cli-ChWsO-bb.js → cli-rGyZlX2p.js} +4 -4
- package/dist/{cli-ChWsO-bb.js.map → cli-rGyZlX2p.js.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +100 -24
- package/dist/cli.js.map +1 -1
- package/dist/{client-D-4_aZf2.d.ts → client-2fTFutRH.d.ts} +4 -2
- package/dist/client-2fTFutRH.d.ts.map +1 -0
- package/dist/{flags-ceSqz2T6.js → flags-DG-3Vfgg.js} +25 -6
- package/dist/flags-DG-3Vfgg.js.map +1 -0
- package/dist/{flows-_KmnuUXd.js → flows-gbxyIf6o.js} +13 -6
- package/dist/flows-gbxyIf6o.js.map +1 -0
- package/dist/flows.d.ts +2 -8
- package/dist/flows.d.ts.map +1 -1
- package/dist/flows.js +1 -1
- package/dist/{ipc-BM335WFg.js → ipc-CkAW8Qvc.js} +51 -9
- package/dist/ipc-CkAW8Qvc.js.map +1 -0
- package/dist/{output-C4QhjpM6.js → output-DmHvT8vm.js} +141 -12
- package/dist/output-DmHvT8vm.js.map +1 -0
- package/dist/{perf-metrics-D0um6IR6.js → perf-metrics-DvT_gvUh.js} +12 -2
- package/dist/perf-metrics-DvT_gvUh.js.map +1 -0
- package/dist/{prompt-turn-CXMtXBl-.js → prompt-turn-BOoZaDEq.js} +221 -38
- package/dist/prompt-turn-BOoZaDEq.js.map +1 -0
- package/dist/{render-Br-kVPK_.js → render-CyodRDtK.js} +35 -3
- package/dist/{render-Br-kVPK_.js.map → render-CyodRDtK.js.map} +1 -1
- package/dist/runtime.d.ts +84 -10
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +425 -190
- package/dist/runtime.js.map +1 -1
- package/dist/{session-BtwAKtJ3.js → session-DcIse8N0.js} +66 -15
- package/dist/session-DcIse8N0.js.map +1 -0
- package/dist/session-options-pCbHn_n7.d.ts +13 -0
- package/dist/session-options-pCbHn_n7.d.ts.map +1 -0
- package/dist/{types-yxf-gcOE.d.ts → types-CVBeQyi3.d.ts} +9 -1
- package/dist/types-CVBeQyi3.d.ts.map +1 -0
- package/package.json +20 -20
- package/skills/acpx/SKILL.md +7 -2
- package/dist/client-D-4_aZf2.d.ts.map +0 -1
- package/dist/flags-ceSqz2T6.js.map +0 -1
- package/dist/flows-_KmnuUXd.js.map +0 -1
- package/dist/ipc-BM335WFg.js.map +0 -1
- package/dist/output-C4QhjpM6.js.map +0 -1
- package/dist/perf-metrics-D0um6IR6.js.map +0 -1
- package/dist/prompt-turn-CXMtXBl-.js.map +0 -1
- package/dist/session-BtwAKtJ3.js.map +0 -1
- package/dist/types-yxf-gcOE.d.ts.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { D as OUTPUT_ERROR_CODES, H as QueueProtocolError, O as OUTPUT_ERROR_ORIGINS, V as QueueConnectionError, a as recordPerfDuration, f as isPromptInput, g as textPrompt, i as measurePerf, r as incrementPerfCounter, x as normalizeOutputError } from "./perf-metrics-
|
|
1
|
+
import { D as OUTPUT_ERROR_CODES, H as QueueProtocolError, O as OUTPUT_ERROR_ORIGINS, V as QueueConnectionError, a as recordPerfDuration, f as isPromptInput, g as textPrompt, i as measurePerf, r as incrementPerfCounter, x as normalizeOutputError } from "./perf-metrics-DvT_gvUh.js";
|
|
2
2
|
import { n as isAcpJsonRpcMessage } from "./jsonrpc-DSxh2w5R.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import os from "node:os";
|
|
6
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
6
|
+
import { createHash, randomInt, randomUUID } from "node:crypto";
|
|
7
7
|
import net from "node:net";
|
|
8
8
|
//#region src/cli/queue/paths.ts
|
|
9
9
|
function shortHash(value, length) {
|
|
@@ -47,7 +47,7 @@ function parseQueueOwnerRecord(raw) {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
function createOwnerGeneration() {
|
|
50
|
-
return
|
|
50
|
+
return randomInt(1, 2 ** 48);
|
|
51
51
|
}
|
|
52
52
|
function nowIso() {
|
|
53
53
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -58,9 +58,20 @@ function isQueueOwnerHeartbeatStale(owner) {
|
|
|
58
58
|
return Date.now() - heartbeatMs > QUEUE_OWNER_STALE_HEARTBEAT_MS;
|
|
59
59
|
}
|
|
60
60
|
async function ensureQueueDir() {
|
|
61
|
-
|
|
61
|
+
const baseDir = queueBaseDir();
|
|
62
|
+
await fs.mkdir(baseDir, {
|
|
63
|
+
recursive: true,
|
|
64
|
+
mode: 448
|
|
65
|
+
});
|
|
66
|
+
await fs.chmod(baseDir, 448);
|
|
62
67
|
const socketDir = queueSocketBaseDir();
|
|
63
|
-
if (socketDir)
|
|
68
|
+
if (socketDir) {
|
|
69
|
+
await fs.mkdir(socketDir, {
|
|
70
|
+
recursive: true,
|
|
71
|
+
mode: 448
|
|
72
|
+
});
|
|
73
|
+
await fs.chmod(socketDir, 448);
|
|
74
|
+
}
|
|
64
75
|
}
|
|
65
76
|
async function removeSocketFile(socketPath) {
|
|
66
77
|
if (process.platform === "win32") return;
|
|
@@ -335,6 +346,33 @@ function parseAcpError(value) {
|
|
|
335
346
|
data: record.data
|
|
336
347
|
};
|
|
337
348
|
}
|
|
349
|
+
function parseSessionOptions(value) {
|
|
350
|
+
if (value == null) return;
|
|
351
|
+
const record = asRecord(value);
|
|
352
|
+
if (!record) return null;
|
|
353
|
+
const sessionOptions = {};
|
|
354
|
+
if (record.model != null) {
|
|
355
|
+
if (typeof record.model !== "string" || record.model.trim().length === 0) return null;
|
|
356
|
+
sessionOptions.model = record.model;
|
|
357
|
+
}
|
|
358
|
+
if (record.allowedTools != null) {
|
|
359
|
+
if (!Array.isArray(record.allowedTools)) return null;
|
|
360
|
+
const allowedTools = record.allowedTools.filter((tool) => typeof tool === "string");
|
|
361
|
+
if (allowedTools.length !== record.allowedTools.length) return null;
|
|
362
|
+
sessionOptions.allowedTools = allowedTools;
|
|
363
|
+
}
|
|
364
|
+
if (record.maxTurns != null) {
|
|
365
|
+
if (typeof record.maxTurns !== "number" || !Number.isFinite(record.maxTurns)) return null;
|
|
366
|
+
sessionOptions.maxTurns = Math.max(1, Math.round(record.maxTurns));
|
|
367
|
+
}
|
|
368
|
+
if (record.systemPrompt != null) if (typeof record.systemPrompt === "string") sessionOptions.systemPrompt = record.systemPrompt;
|
|
369
|
+
else {
|
|
370
|
+
const systemPrompt = asRecord(record.systemPrompt);
|
|
371
|
+
if (!systemPrompt || typeof systemPrompt.append !== "string") return null;
|
|
372
|
+
sessionOptions.systemPrompt = { append: systemPrompt.append };
|
|
373
|
+
}
|
|
374
|
+
return sessionOptions;
|
|
375
|
+
}
|
|
338
376
|
function parseOwnerGeneration(value) {
|
|
339
377
|
if (value == null) return;
|
|
340
378
|
if (typeof value !== "number" || !Number.isInteger(value) || value <= 0) return null;
|
|
@@ -352,8 +390,9 @@ function parseQueueRequest(raw) {
|
|
|
352
390
|
const resumePolicy = request.resumePolicy == null ? void 0 : isSessionResumePolicy(request.resumePolicy) ? request.resumePolicy : null;
|
|
353
391
|
const nonInteractivePermissions = request.nonInteractivePermissions == null ? void 0 : isNonInteractivePermissionPolicy(request.nonInteractivePermissions) ? request.nonInteractivePermissions : null;
|
|
354
392
|
const suppressSdkConsoleErrors = request.suppressSdkConsoleErrors == null ? void 0 : typeof request.suppressSdkConsoleErrors === "boolean" ? request.suppressSdkConsoleErrors : null;
|
|
393
|
+
const sessionOptions = parseSessionOptions(request.sessionOptions);
|
|
355
394
|
const prompt = request.prompt == null ? void 0 : isPromptInput(request.prompt) ? request.prompt : null;
|
|
356
|
-
if (typeof request.message !== "string" || !isPermissionMode(request.permissionMode) || resumePolicy === null || prompt === null || nonInteractivePermissions === null || suppressSdkConsoleErrors === null || typeof request.waitForCompletion !== "boolean") return null;
|
|
395
|
+
if (typeof request.message !== "string" || !isPermissionMode(request.permissionMode) || resumePolicy === null || prompt === null || nonInteractivePermissions === null || suppressSdkConsoleErrors === null || sessionOptions === null || typeof request.waitForCompletion !== "boolean") return null;
|
|
357
396
|
return {
|
|
358
397
|
type: "submit_prompt",
|
|
359
398
|
requestId: request.requestId,
|
|
@@ -365,7 +404,8 @@ function parseQueueRequest(raw) {
|
|
|
365
404
|
nonInteractivePermissions,
|
|
366
405
|
timeoutMs,
|
|
367
406
|
...suppressSdkConsoleErrors !== void 0 ? { suppressSdkConsoleErrors } : {},
|
|
368
|
-
waitForCompletion: request.waitForCompletion
|
|
407
|
+
waitForCompletion: request.waitForCompletion,
|
|
408
|
+
...sessionOptions !== void 0 ? { sessionOptions } : {}
|
|
369
409
|
};
|
|
370
410
|
}
|
|
371
411
|
if (request.type === "cancel_prompt") return {
|
|
@@ -758,6 +798,7 @@ var SessionQueueOwner = class SessionQueueOwner {
|
|
|
758
798
|
nonInteractivePermissions: request.nonInteractivePermissions,
|
|
759
799
|
timeoutMs: request.timeoutMs,
|
|
760
800
|
suppressSdkConsoleErrors: request.suppressSdkConsoleErrors,
|
|
801
|
+
sessionOptions: request.sessionOptions,
|
|
761
802
|
waitForCompletion: request.waitForCompletion,
|
|
762
803
|
enqueuedAt: Date.now(),
|
|
763
804
|
send: (message) => {
|
|
@@ -916,7 +957,8 @@ async function submitToQueueOwner(owner, options) {
|
|
|
916
957
|
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
917
958
|
timeoutMs: options.timeoutMs,
|
|
918
959
|
suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,
|
|
919
|
-
waitForCompletion: options.waitForCompletion
|
|
960
|
+
waitForCompletion: options.waitForCompletion,
|
|
961
|
+
sessionOptions: options.sessionOptions
|
|
920
962
|
};
|
|
921
963
|
options.outputFormatter.setContext({ sessionId: options.sessionId });
|
|
922
964
|
return await runQueueOwnerRequest({
|
|
@@ -1207,4 +1249,4 @@ async function trySetConfigOptionOnRunningOwner(sessionId, configId, value, time
|
|
|
1207
1249
|
//#endregion
|
|
1208
1250
|
export { trySubmitToRunningOwner as a, isProcessAlive as c, terminateProcess as d, terminateQueueOwnerForSession as f, trySetModelOnRunningOwner as i, refreshQueueOwnerLease as l, waitMs as m, trySetConfigOptionOnRunningOwner as n, SessionQueueOwner as o, tryAcquireQueueOwnerLease as p, trySetModeOnRunningOwner as r, probeQueueOwnerHealth as s, tryCancelOnRunningOwner as t, releaseQueueOwnerLease as u };
|
|
1209
1251
|
|
|
1210
|
-
//# sourceMappingURL=ipc-
|
|
1252
|
+
//# sourceMappingURL=ipc-CkAW8Qvc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc-CkAW8Qvc.js","names":[],"sources":["../src/cli/queue/paths.ts","../src/cli/queue/lease-store.ts","../src/cli/queue/ipc-transport.ts","../src/cli/queue/ipc-health.ts","../src/cli/queue/messages.ts","../src/cli/queue/ipc-server.ts","../src/cli/queue/ipc.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nfunction shortHash(value: string, length: number): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, length);\n}\n\nexport function queueKeyForSession(sessionId: string): string {\n return shortHash(sessionId, 24);\n}\n\nexport function queueBaseDir(homeDir: string = os.homedir()): string {\n return path.join(homeDir, \".acpx\", \"queues\");\n}\n\nexport function queueSocketBaseDir(homeDir: string = os.homedir()): string | undefined {\n if (process.platform === \"win32\") {\n return undefined;\n }\n return path.join(\"/tmp\", `acpx-${shortHash(homeDir, 10)}`);\n}\n\nexport function queueLockFilePath(sessionId: string, homeDir: string = os.homedir()): string {\n return path.join(queueBaseDir(homeDir), `${queueKeyForSession(sessionId)}.lock`);\n}\n\nexport function queueSocketPath(sessionId: string, homeDir: string = os.homedir()): string {\n const key = queueKeyForSession(sessionId);\n if (process.platform === \"win32\") {\n return `\\\\\\\\.\\\\pipe\\\\acpx-${key}`;\n }\n return path.join(queueSocketBaseDir(homeDir) ?? \"/tmp\", `${key}.sock`);\n}\n","import { randomInt } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport { queueBaseDir, queueLockFilePath, queueSocketBaseDir, queueSocketPath } from \"./paths.js\";\n\nconst PROCESS_EXIT_GRACE_MS = 1_500;\nconst PROCESS_POLL_MS = 50;\nconst QUEUE_OWNER_STALE_HEARTBEAT_MS = 15_000;\n\nexport type QueueOwnerRecord = {\n pid: number;\n sessionId: string;\n socketPath: string;\n createdAt: string;\n heartbeatAt: string;\n ownerGeneration: number;\n queueDepth: number;\n};\n\nexport type QueueOwnerLease = {\n sessionId: string;\n lockPath: string;\n socketPath: string;\n createdAt: string;\n ownerGeneration: number;\n};\n\nexport type QueueOwnerStatus = {\n pid: number;\n socketPath: string;\n heartbeatAt: string;\n ownerGeneration: number;\n queueDepth: number;\n alive: boolean;\n stale: boolean;\n};\n\nfunction parseQueueOwnerRecord(raw: unknown): QueueOwnerRecord | null {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) {\n return null;\n }\n const record = raw as Record<string, unknown>;\n\n if (\n !Number.isInteger(record.pid) ||\n (record.pid as number) <= 0 ||\n typeof record.sessionId !== \"string\" ||\n typeof record.socketPath !== \"string\" ||\n typeof record.createdAt !== \"string\" ||\n typeof record.heartbeatAt !== \"string\" ||\n !Number.isInteger(record.ownerGeneration) ||\n (record.ownerGeneration as number) <= 0 ||\n !Number.isInteger(record.queueDepth) ||\n (record.queueDepth as number) < 0\n ) {\n return null;\n }\n\n return {\n pid: record.pid as number,\n sessionId: record.sessionId,\n socketPath: record.socketPath,\n createdAt: record.createdAt,\n heartbeatAt: record.heartbeatAt,\n ownerGeneration: record.ownerGeneration as number,\n queueDepth: record.queueDepth as number,\n };\n}\n\nfunction createOwnerGeneration(): number {\n return randomInt(1, 2 ** 48);\n}\n\nfunction nowIso(): string {\n return new Date().toISOString();\n}\n\nfunction isQueueOwnerHeartbeatStale(owner: QueueOwnerRecord): boolean {\n const heartbeatMs = Date.parse(owner.heartbeatAt);\n if (!Number.isFinite(heartbeatMs)) {\n return true;\n }\n return Date.now() - heartbeatMs > QUEUE_OWNER_STALE_HEARTBEAT_MS;\n}\n\nasync function ensureQueueDir(): Promise<void> {\n const baseDir = queueBaseDir();\n await fs.mkdir(baseDir, { recursive: true, mode: 0o700 });\n await fs.chmod(baseDir, 0o700);\n const socketDir = queueSocketBaseDir();\n if (socketDir) {\n await fs.mkdir(socketDir, { recursive: true, mode: 0o700 });\n await fs.chmod(socketDir, 0o700);\n }\n}\n\nasync function removeSocketFile(socketPath: string): Promise<void> {\n if (process.platform === \"win32\") {\n return;\n }\n\n try {\n await fs.unlink(socketPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n}\n\nasync function waitForProcessExit(pid: number, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + Math.max(0, timeoutMs);\n while (Date.now() <= deadline) {\n if (!isProcessAlive(pid)) {\n return true;\n }\n await waitMs(PROCESS_POLL_MS);\n }\n\n return !isProcessAlive(pid);\n}\n\nasync function cleanupStaleQueueOwner(\n sessionId: string,\n owner: QueueOwnerRecord | undefined,\n): Promise<void> {\n const lockPath = queueLockFilePath(sessionId);\n const socketPath = owner?.socketPath ?? queueSocketPath(sessionId);\n\n await removeSocketFile(socketPath).catch(() => {\n // ignore stale socket cleanup failures\n });\n\n await fs.unlink(lockPath).catch((error) => {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n });\n}\n\nexport async function readQueueOwnerRecord(\n sessionId: string,\n): Promise<QueueOwnerRecord | undefined> {\n const lockPath = queueLockFilePath(sessionId);\n try {\n const payload = await fs.readFile(lockPath, \"utf8\");\n const parsed = parseQueueOwnerRecord(JSON.parse(payload));\n return parsed ?? undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function isProcessAlive(pid: number | undefined): boolean {\n if (!pid || !Number.isInteger(pid) || pid <= 0 || pid === process.pid) {\n return false;\n }\n\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function terminateProcess(pid: number): Promise<boolean> {\n if (!isProcessAlive(pid)) {\n return false;\n }\n\n try {\n process.kill(pid, \"SIGTERM\");\n } catch {\n return false;\n }\n\n if (await waitForProcessExit(pid, PROCESS_EXIT_GRACE_MS)) {\n return true;\n }\n\n try {\n process.kill(pid, \"SIGKILL\");\n } catch {\n return false;\n }\n\n await waitForProcessExit(pid, PROCESS_EXIT_GRACE_MS);\n return true;\n}\n\nexport async function ensureOwnerIsUsable(\n sessionId: string,\n owner: QueueOwnerRecord,\n): Promise<boolean> {\n const alive = isProcessAlive(owner.pid);\n const stale = isQueueOwnerHeartbeatStale(owner);\n if (alive && !stale) {\n return true;\n }\n\n if (alive) {\n await terminateProcess(owner.pid).catch(() => {\n // best effort stale owner termination\n });\n }\n await cleanupStaleQueueOwner(sessionId, owner);\n return false;\n}\n\nexport async function readQueueOwnerStatus(\n sessionId: string,\n): Promise<QueueOwnerStatus | undefined> {\n const owner = await readQueueOwnerRecord(sessionId);\n if (!owner) {\n return undefined;\n }\n\n const alive = await ensureOwnerIsUsable(sessionId, owner);\n if (!alive) {\n return undefined;\n }\n\n return {\n pid: owner.pid,\n socketPath: owner.socketPath,\n heartbeatAt: owner.heartbeatAt,\n ownerGeneration: owner.ownerGeneration,\n queueDepth: owner.queueDepth,\n alive,\n stale: isQueueOwnerHeartbeatStale(owner),\n };\n}\n\nexport async function tryAcquireQueueOwnerLease(\n sessionId: string,\n nowIsoFactory: () => string = nowIso,\n): Promise<QueueOwnerLease | undefined> {\n await ensureQueueDir();\n const lockPath = queueLockFilePath(sessionId);\n const socketPath = queueSocketPath(sessionId);\n const createdAt = nowIsoFactory();\n const ownerGeneration = createOwnerGeneration();\n const payload = JSON.stringify(\n {\n pid: process.pid,\n sessionId,\n socketPath,\n createdAt,\n heartbeatAt: createdAt,\n ownerGeneration,\n queueDepth: 0,\n },\n null,\n 2,\n );\n\n try {\n await fs.writeFile(lockPath, `${payload}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n await removeSocketFile(socketPath).catch(() => {\n // best-effort stale socket cleanup after ownership is acquired\n });\n return {\n sessionId,\n lockPath,\n socketPath,\n createdAt,\n ownerGeneration,\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw error;\n }\n\n const owner = await readQueueOwnerRecord(sessionId);\n if (!owner) {\n await cleanupStaleQueueOwner(sessionId, owner);\n return undefined;\n }\n\n if (!isProcessAlive(owner.pid) || isQueueOwnerHeartbeatStale(owner)) {\n if (isProcessAlive(owner.pid)) {\n await terminateProcess(owner.pid).catch(() => {\n // best effort stale owner termination\n });\n }\n await cleanupStaleQueueOwner(sessionId, owner);\n }\n return undefined;\n }\n}\n\nexport async function refreshQueueOwnerLease(\n lease: QueueOwnerLease,\n options: {\n queueDepth: number;\n },\n nowIsoFactory: () => string = nowIso,\n): Promise<void> {\n const payload = JSON.stringify(\n {\n pid: process.pid,\n sessionId: lease.sessionId,\n socketPath: lease.socketPath,\n createdAt: lease.createdAt,\n heartbeatAt: nowIsoFactory(),\n ownerGeneration: lease.ownerGeneration,\n queueDepth: Math.max(0, Math.round(options.queueDepth)),\n },\n null,\n 2,\n );\n await fs.writeFile(lease.lockPath, `${payload}\\n`, {\n encoding: \"utf8\",\n });\n}\n\nexport async function releaseQueueOwnerLease(lease: QueueOwnerLease): Promise<void> {\n await removeSocketFile(lease.socketPath).catch(() => {\n // ignore best-effort cleanup failures\n });\n\n await fs.unlink(lease.lockPath).catch((error) => {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n });\n}\n\nexport async function terminateQueueOwnerForSession(sessionId: string): Promise<void> {\n const owner = await readQueueOwnerRecord(sessionId);\n if (!owner) {\n return;\n }\n\n if (isProcessAlive(owner.pid)) {\n await terminateProcess(owner.pid);\n }\n\n await cleanupStaleQueueOwner(sessionId, owner);\n}\n\nexport async function waitMs(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n}\n","import net from \"node:net\";\nimport { measurePerf } from \"../../perf-metrics.js\";\nimport { type QueueOwnerRecord, waitMs } from \"./lease-store.js\";\n\nconst QUEUE_CONNECT_ATTEMPTS = 40;\nexport const QUEUE_CONNECT_RETRY_MS = 50;\nexport const SOCKET_CONNECTION_TIMEOUT_MS = 5000;\n\nfunction shouldRetryQueueConnect(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException).code;\n return code === \"ENOENT\" || code === \"ECONNREFUSED\";\n}\n\nasync function connectToSocket(\n socketPath: string,\n timeoutMs = SOCKET_CONNECTION_TIMEOUT_MS,\n): Promise<net.Socket> {\n return await new Promise<net.Socket>((resolve, reject) => {\n const socket = net.createConnection(socketPath);\n let settled = false;\n\n const timeout = setTimeout(() => {\n if (settled) {\n return;\n }\n settled = true;\n socket.destroy();\n reject(new Error(`Connection to ${socketPath} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n const onConnect = () => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timeout);\n socket.off(\"error\", onError);\n resolve(socket);\n };\n const onError = (error: Error) => {\n if (settled) {\n return;\n }\n settled = true;\n clearTimeout(timeout);\n socket.off(\"connect\", onConnect);\n reject(error);\n };\n\n socket.once(\"connect\", onConnect);\n socket.once(\"error\", onError);\n });\n}\n\nexport async function connectToQueueOwner(\n owner: QueueOwnerRecord,\n maxAttempts = QUEUE_CONNECT_ATTEMPTS,\n): Promise<net.Socket | undefined> {\n let lastError: unknown;\n\n const attempts = Math.max(1, Math.trunc(maxAttempts));\n for (let attempt = 0; attempt < attempts; attempt += 1) {\n try {\n return await measurePerf(\n \"queue.connect\",\n async () => await connectToSocket(owner.socketPath),\n );\n } catch (error) {\n lastError = error;\n if (!shouldRetryQueueConnect(error)) {\n throw error;\n }\n await waitMs(QUEUE_CONNECT_RETRY_MS);\n }\n }\n\n if (lastError && !shouldRetryQueueConnect(lastError)) {\n throw lastError;\n }\n\n return undefined;\n}\n","import { connectToQueueOwner } from \"./ipc-transport.js\";\nimport { readQueueOwnerRecord, readQueueOwnerStatus } from \"./lease-store.js\";\n\nexport type QueueOwnerHealth = {\n sessionId: string;\n hasLease: boolean;\n healthy: boolean;\n socketReachable: boolean;\n pidAlive: boolean;\n pid?: number;\n socketPath?: string;\n ownerGeneration?: number;\n queueDepth?: number;\n};\n\nexport async function probeQueueOwnerHealth(sessionId: string): Promise<QueueOwnerHealth> {\n const ownerRecord = await readQueueOwnerRecord(sessionId);\n if (!ownerRecord) {\n return {\n sessionId,\n hasLease: false,\n healthy: false,\n socketReachable: false,\n pidAlive: false,\n };\n }\n\n const owner = await readQueueOwnerStatus(sessionId);\n if (!owner) {\n return {\n sessionId,\n hasLease: false,\n healthy: false,\n socketReachable: false,\n pidAlive: false,\n };\n }\n\n const pidAlive = owner.alive;\n let socketReachable = false;\n try {\n const socket = await connectToQueueOwner(ownerRecord, 2);\n if (socket) {\n socketReachable = true;\n if (!socket.destroyed) {\n socket.end();\n }\n }\n } catch {\n socketReachable = false;\n }\n\n return {\n sessionId,\n hasLease: true,\n healthy: socketReachable,\n socketReachable,\n pidAlive,\n pid: owner.pid,\n socketPath: owner.socketPath,\n ownerGeneration: owner.ownerGeneration,\n queueDepth: owner.queueDepth,\n };\n}\n","import type { SetSessionConfigOptionResponse } from \"@agentclientprotocol/sdk\";\nimport { isAcpJsonRpcMessage } from \"../../acp/jsonrpc.js\";\nimport { isPromptInput, textPrompt } from \"../../prompt-content.js\";\nimport {\n OUTPUT_ERROR_CODES,\n OUTPUT_ERROR_ORIGINS,\n type AcpClientOptions,\n type OutputErrorAcpPayload,\n type OutputErrorCode,\n type OutputErrorOrigin,\n} from \"../../types.js\";\nimport type {\n AcpJsonRpcMessage,\n NonInteractivePermissionPolicy,\n PermissionMode,\n PromptInput,\n SessionResumePolicy,\n SessionSendResult,\n} from \"../../types.js\";\n\ntype QueueSessionOptions = NonNullable<AcpClientOptions[\"sessionOptions\"]>;\n\nexport type QueueSubmitRequest = {\n type: \"submit_prompt\";\n requestId: string;\n ownerGeneration?: number;\n message: string;\n prompt?: PromptInput;\n permissionMode: PermissionMode;\n resumePolicy?: SessionResumePolicy;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n timeoutMs?: number;\n suppressSdkConsoleErrors?: boolean;\n waitForCompletion: boolean;\n sessionOptions?: QueueSessionOptions;\n};\n\nexport type QueueCancelRequest = {\n type: \"cancel_prompt\";\n requestId: string;\n ownerGeneration?: number;\n};\n\nexport type QueueSetModeRequest = {\n type: \"set_mode\";\n requestId: string;\n ownerGeneration?: number;\n modeId: string;\n timeoutMs?: number;\n};\n\nexport type QueueSetModelRequest = {\n type: \"set_model\";\n requestId: string;\n ownerGeneration?: number;\n modelId: string;\n timeoutMs?: number;\n};\n\nexport type QueueSetConfigOptionRequest = {\n type: \"set_config_option\";\n requestId: string;\n ownerGeneration?: number;\n configId: string;\n value: string;\n timeoutMs?: number;\n};\n\nexport type QueueRequest =\n | QueueSubmitRequest\n | QueueCancelRequest\n | QueueSetModeRequest\n | QueueSetModelRequest\n | QueueSetConfigOptionRequest;\n\nexport type QueueOwnerAcceptedMessage = {\n type: \"accepted\";\n requestId: string;\n ownerGeneration?: number;\n};\n\nexport type QueueOwnerEventMessage = {\n type: \"event\";\n requestId: string;\n ownerGeneration?: number;\n message: AcpJsonRpcMessage;\n};\n\nexport type QueueOwnerResultMessage = {\n type: \"result\";\n requestId: string;\n ownerGeneration?: number;\n result: SessionSendResult;\n};\n\nexport type QueueOwnerCancelResultMessage = {\n type: \"cancel_result\";\n requestId: string;\n ownerGeneration?: number;\n cancelled: boolean;\n};\n\nexport type QueueOwnerSetModeResultMessage = {\n type: \"set_mode_result\";\n requestId: string;\n ownerGeneration?: number;\n modeId: string;\n};\n\nexport type QueueOwnerSetModelResultMessage = {\n type: \"set_model_result\";\n requestId: string;\n ownerGeneration?: number;\n modelId: string;\n};\n\nexport type QueueOwnerSetConfigOptionResultMessage = {\n type: \"set_config_option_result\";\n requestId: string;\n ownerGeneration?: number;\n response: SetSessionConfigOptionResponse;\n};\n\nexport type QueueOwnerErrorMessage = {\n type: \"error\";\n requestId: string;\n ownerGeneration?: number;\n code?: OutputErrorCode;\n detailCode?: string;\n origin?: OutputErrorOrigin;\n message: string;\n retryable?: boolean;\n acp?: OutputErrorAcpPayload;\n outputAlreadyEmitted?: boolean;\n};\n\nexport type QueueOwnerMessage =\n | QueueOwnerAcceptedMessage\n | QueueOwnerEventMessage\n | QueueOwnerResultMessage\n | QueueOwnerCancelResultMessage\n | QueueOwnerSetModeResultMessage\n | QueueOwnerSetModelResultMessage\n | QueueOwnerSetConfigOptionResultMessage\n | QueueOwnerErrorMessage;\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction isPermissionMode(value: unknown): value is PermissionMode {\n return value === \"approve-all\" || value === \"approve-reads\" || value === \"deny-all\";\n}\n\nfunction isSessionResumePolicy(value: unknown): value is SessionResumePolicy {\n return value === \"allow-new\" || value === \"same-session-only\";\n}\n\nfunction isNonInteractivePermissionPolicy(value: unknown): value is NonInteractivePermissionPolicy {\n return value === \"deny\" || value === \"fail\";\n}\n\nfunction isOutputErrorCode(value: unknown): value is OutputErrorCode {\n return typeof value === \"string\" && OUTPUT_ERROR_CODES.includes(value as OutputErrorCode);\n}\n\nfunction isOutputErrorOrigin(value: unknown): value is OutputErrorOrigin {\n return typeof value === \"string\" && OUTPUT_ERROR_ORIGINS.includes(value as OutputErrorOrigin);\n}\n\nfunction parseAcpError(value: unknown): OutputErrorAcpPayload | undefined {\n const record = asRecord(value);\n if (!record) {\n return undefined;\n }\n if (typeof record.code !== \"number\" || !Number.isFinite(record.code)) {\n return undefined;\n }\n if (typeof record.message !== \"string\" || record.message.length === 0) {\n return undefined;\n }\n\n return {\n code: record.code,\n message: record.message,\n data: record.data,\n };\n}\n\nfunction parseSessionOptions(value: unknown): QueueSessionOptions | null | undefined {\n if (value == null) {\n return undefined;\n }\n const record = asRecord(value);\n if (!record) {\n return null;\n }\n\n const sessionOptions: QueueSessionOptions = {};\n if (record.model != null) {\n if (typeof record.model !== \"string\" || record.model.trim().length === 0) {\n return null;\n }\n sessionOptions.model = record.model;\n }\n if (record.allowedTools != null) {\n if (!Array.isArray(record.allowedTools)) {\n return null;\n }\n const allowedTools = record.allowedTools.filter(\n (tool): tool is string => typeof tool === \"string\",\n );\n if (allowedTools.length !== record.allowedTools.length) {\n return null;\n }\n sessionOptions.allowedTools = allowedTools;\n }\n if (record.maxTurns != null) {\n if (typeof record.maxTurns !== \"number\" || !Number.isFinite(record.maxTurns)) {\n return null;\n }\n sessionOptions.maxTurns = Math.max(1, Math.round(record.maxTurns));\n }\n if (record.systemPrompt != null) {\n if (typeof record.systemPrompt === \"string\") {\n sessionOptions.systemPrompt = record.systemPrompt;\n } else {\n const systemPrompt = asRecord(record.systemPrompt);\n if (!systemPrompt || typeof systemPrompt.append !== \"string\") {\n return null;\n }\n sessionOptions.systemPrompt = { append: systemPrompt.append };\n }\n }\n\n return sessionOptions;\n}\n\nfunction parseOwnerGeneration(value: unknown): number | undefined | null {\n if (value == null) {\n return undefined;\n }\n if (typeof value !== \"number\" || !Number.isInteger(value) || value <= 0) {\n return null;\n }\n return value;\n}\n\nexport function parseQueueRequest(raw: unknown): QueueRequest | null {\n const request = asRecord(raw);\n if (!request) {\n return null;\n }\n\n if (typeof request.type !== \"string\" || typeof request.requestId !== \"string\") {\n return null;\n }\n const ownerGeneration = parseOwnerGeneration(request.ownerGeneration);\n if (ownerGeneration === null) {\n return null;\n }\n\n const timeoutRaw = request.timeoutMs;\n const timeoutMs =\n typeof timeoutRaw === \"number\" && Number.isFinite(timeoutRaw) && timeoutRaw > 0\n ? Math.round(timeoutRaw)\n : undefined;\n\n if (request.type === \"submit_prompt\") {\n const resumePolicy =\n request.resumePolicy == null\n ? undefined\n : isSessionResumePolicy(request.resumePolicy)\n ? request.resumePolicy\n : null;\n const nonInteractivePermissions =\n request.nonInteractivePermissions == null\n ? undefined\n : isNonInteractivePermissionPolicy(request.nonInteractivePermissions)\n ? request.nonInteractivePermissions\n : null;\n const suppressSdkConsoleErrors =\n request.suppressSdkConsoleErrors == null\n ? undefined\n : typeof request.suppressSdkConsoleErrors === \"boolean\"\n ? request.suppressSdkConsoleErrors\n : null;\n const sessionOptions = parseSessionOptions(request.sessionOptions);\n\n const prompt =\n request.prompt == null ? undefined : isPromptInput(request.prompt) ? request.prompt : null;\n if (\n typeof request.message !== \"string\" ||\n !isPermissionMode(request.permissionMode) ||\n resumePolicy === null ||\n prompt === null ||\n nonInteractivePermissions === null ||\n suppressSdkConsoleErrors === null ||\n sessionOptions === null ||\n typeof request.waitForCompletion !== \"boolean\"\n ) {\n return null;\n }\n\n return {\n type: \"submit_prompt\",\n requestId: request.requestId,\n ownerGeneration,\n message: request.message,\n prompt: prompt ?? textPrompt(request.message),\n permissionMode: request.permissionMode,\n ...(resumePolicy !== undefined ? { resumePolicy } : {}),\n nonInteractivePermissions,\n timeoutMs,\n ...(suppressSdkConsoleErrors !== undefined ? { suppressSdkConsoleErrors } : {}),\n waitForCompletion: request.waitForCompletion,\n ...(sessionOptions !== undefined ? { sessionOptions } : {}),\n };\n }\n\n if (request.type === \"cancel_prompt\") {\n return {\n type: \"cancel_prompt\",\n requestId: request.requestId,\n ownerGeneration,\n };\n }\n\n if (request.type === \"set_mode\") {\n if (typeof request.modeId !== \"string\" || request.modeId.trim().length === 0) {\n return null;\n }\n return {\n type: \"set_mode\",\n requestId: request.requestId,\n ownerGeneration,\n modeId: request.modeId,\n timeoutMs,\n };\n }\n\n if (request.type === \"set_model\") {\n if (typeof request.modelId !== \"string\" || request.modelId.trim().length === 0) {\n return null;\n }\n return {\n type: \"set_model\",\n requestId: request.requestId,\n ownerGeneration,\n modelId: request.modelId,\n timeoutMs,\n };\n }\n\n if (request.type === \"set_config_option\") {\n if (\n typeof request.configId !== \"string\" ||\n request.configId.trim().length === 0 ||\n typeof request.value !== \"string\" ||\n request.value.trim().length === 0\n ) {\n return null;\n }\n return {\n type: \"set_config_option\",\n requestId: request.requestId,\n ownerGeneration,\n configId: request.configId,\n value: request.value,\n timeoutMs,\n };\n }\n\n return null;\n}\n\nfunction parseSessionSendResult(raw: unknown): SessionSendResult | null {\n const result = asRecord(raw);\n if (!result) {\n return null;\n }\n\n if (\n typeof result.stopReason !== \"string\" ||\n typeof result.sessionId !== \"string\" ||\n typeof result.resumed !== \"boolean\"\n ) {\n return null;\n }\n\n const permissionStats = asRecord(result.permissionStats);\n const record = asRecord(result.record);\n if (!permissionStats || !record) {\n return null;\n }\n\n const statsValid =\n typeof permissionStats.requested === \"number\" &&\n typeof permissionStats.approved === \"number\" &&\n typeof permissionStats.denied === \"number\" &&\n typeof permissionStats.cancelled === \"number\";\n if (!statsValid) {\n return null;\n }\n\n const recordValid =\n typeof record.acpxRecordId === \"string\" &&\n typeof record.acpSessionId === \"string\" &&\n typeof record.agentCommand === \"string\" &&\n typeof record.cwd === \"string\" &&\n typeof record.createdAt === \"string\" &&\n typeof record.lastUsedAt === \"string\" &&\n Array.isArray(record.messages) &&\n typeof record.updated_at === \"string\" &&\n typeof record.lastSeq === \"number\" &&\n Number.isInteger(record.lastSeq) &&\n !!record.eventLog &&\n typeof record.eventLog === \"object\";\n if (!recordValid) {\n return null;\n }\n\n return result as SessionSendResult;\n}\n\nexport function parseQueueOwnerMessage(raw: unknown): QueueOwnerMessage | null {\n const message = asRecord(raw);\n if (!message || typeof message.type !== \"string\") {\n return null;\n }\n\n if (typeof message.requestId !== \"string\") {\n return null;\n }\n const ownerGeneration = parseOwnerGeneration(message.ownerGeneration);\n if (ownerGeneration === null) {\n return null;\n }\n\n if (message.type === \"accepted\") {\n return {\n type: \"accepted\",\n requestId: message.requestId,\n ownerGeneration,\n };\n }\n\n if (message.type === \"event\") {\n if (!isAcpJsonRpcMessage(message.message)) {\n return null;\n }\n\n return {\n type: \"event\",\n requestId: message.requestId,\n ownerGeneration,\n message: message.message,\n };\n }\n\n if (message.type === \"result\") {\n const parsedResult = parseSessionSendResult(message.result);\n if (!parsedResult) {\n return null;\n }\n return {\n type: \"result\",\n requestId: message.requestId,\n ownerGeneration,\n result: parsedResult,\n };\n }\n\n if (message.type === \"cancel_result\") {\n if (typeof message.cancelled !== \"boolean\") {\n return null;\n }\n return {\n type: \"cancel_result\",\n requestId: message.requestId,\n ownerGeneration,\n cancelled: message.cancelled,\n };\n }\n\n if (message.type === \"set_mode_result\") {\n if (typeof message.modeId !== \"string\") {\n return null;\n }\n return {\n type: \"set_mode_result\",\n requestId: message.requestId,\n ownerGeneration,\n modeId: message.modeId,\n };\n }\n\n if (message.type === \"set_model_result\") {\n if (typeof message.modelId !== \"string\") {\n return null;\n }\n return {\n type: \"set_model_result\",\n requestId: message.requestId,\n ownerGeneration,\n modelId: message.modelId,\n };\n }\n\n if (message.type === \"set_config_option_result\") {\n const response = asRecord(message.response);\n if (!response || !Array.isArray(response.configOptions)) {\n return null;\n }\n return {\n type: \"set_config_option_result\",\n requestId: message.requestId,\n ownerGeneration,\n response: response as SetSessionConfigOptionResponse,\n };\n }\n\n if (message.type === \"error\") {\n if (\n typeof message.message !== \"string\" ||\n !isOutputErrorCode(message.code) ||\n !isOutputErrorOrigin(message.origin)\n ) {\n return null;\n }\n\n const detailCode =\n typeof message.detailCode === \"string\" && message.detailCode.trim().length > 0\n ? message.detailCode\n : undefined;\n const retryable = typeof message.retryable === \"boolean\" ? message.retryable : undefined;\n const acp = parseAcpError(message.acp);\n const outputAlreadyEmitted =\n typeof message.outputAlreadyEmitted === \"boolean\" ? message.outputAlreadyEmitted : undefined;\n\n return {\n type: \"error\",\n requestId: message.requestId,\n ownerGeneration,\n code: message.code,\n detailCode,\n origin: message.origin,\n message: message.message,\n retryable,\n acp,\n ...(outputAlreadyEmitted === undefined ? {} : { outputAlreadyEmitted }),\n };\n }\n\n return null;\n}\n","import net from \"node:net\";\nimport type { SetSessionConfigOptionResponse } from \"@agentclientprotocol/sdk\";\nimport { normalizeOutputError } from \"../../acp/error-normalization.js\";\nimport { recordPerfDuration } from \"../../perf-metrics.js\";\nimport { textPrompt } from \"../../prompt-content.js\";\nimport type {\n AcpClientOptions,\n NonInteractivePermissionPolicy,\n PermissionMode,\n PromptInput,\n SessionResumePolicy,\n} from \"../../types.js\";\nimport {\n parseQueueRequest,\n type QueueOwnerErrorMessage,\n type QueueOwnerMessage,\n} from \"./messages.js\";\n\ntype QueueOwnerSocketLease = {\n socketPath: string;\n ownerGeneration?: number;\n};\n\nfunction makeQueueOwnerError(\n requestId: string,\n message: string,\n detailCode: string,\n options: {\n retryable?: boolean;\n } = {},\n): QueueOwnerErrorMessage {\n return {\n type: \"error\",\n requestId,\n ownerGeneration: undefined,\n code: \"RUNTIME\",\n detailCode,\n origin: \"queue\",\n retryable: options.retryable,\n message,\n };\n}\n\nfunction makeQueueOwnerErrorFromUnknown(\n requestId: string,\n error: unknown,\n detailCode: string,\n options: {\n retryable?: boolean;\n } = {},\n): QueueOwnerErrorMessage {\n const normalized = normalizeOutputError(error, {\n defaultCode: \"RUNTIME\",\n origin: \"queue\",\n detailCode,\n retryable: options.retryable,\n });\n\n return {\n type: \"error\",\n requestId,\n code: normalized.code,\n detailCode: normalized.detailCode,\n origin: normalized.origin,\n message: normalized.message,\n retryable: normalized.retryable,\n acp: normalized.acp,\n };\n}\n\nfunction writeQueueMessage(socket: net.Socket, message: QueueOwnerMessage): void {\n if (socket.destroyed || !socket.writable) {\n return;\n }\n socket.write(`${JSON.stringify(message)}\\n`);\n}\n\nexport type QueueTask = {\n requestId: string;\n message: string;\n prompt: PromptInput;\n permissionMode: PermissionMode;\n resumePolicy?: SessionResumePolicy;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n timeoutMs?: number;\n suppressSdkConsoleErrors?: boolean;\n sessionOptions?: NonNullable<AcpClientOptions[\"sessionOptions\"]>;\n waitForCompletion: boolean;\n enqueuedAt: number;\n send: (message: QueueOwnerMessage) => void;\n close: () => void;\n};\n\nexport type QueueOwnerControlHandlers = {\n cancelPrompt: () => Promise<boolean>;\n setSessionMode: (modeId: string, timeoutMs?: number) => Promise<void>;\n setSessionModel: (modelId: string, timeoutMs?: number) => Promise<void>;\n setSessionConfigOption: (\n configId: string,\n value: string,\n timeoutMs?: number,\n ) => Promise<SetSessionConfigOptionResponse>;\n};\n\ntype SessionQueueOwnerOptions = {\n maxQueueDepth: number;\n onQueueDepthChanged?: (queueDepth: number) => void;\n};\n\nexport class SessionQueueOwner {\n private readonly server: net.Server;\n private readonly controlHandlers: QueueOwnerControlHandlers;\n private readonly ownerGeneration?: number;\n private readonly maxQueueDepth: number;\n private readonly onQueueDepthChanged?: (queueDepth: number) => void;\n private readonly pending: QueueTask[] = [];\n private readonly waiters: Array<(task: QueueTask | undefined) => void> = [];\n private closed = false;\n\n private constructor(\n server: net.Server,\n controlHandlers: QueueOwnerControlHandlers,\n lease: QueueOwnerSocketLease,\n options: SessionQueueOwnerOptions,\n ) {\n this.server = server;\n this.controlHandlers = controlHandlers;\n this.ownerGeneration = lease.ownerGeneration;\n this.maxQueueDepth = Math.max(1, Math.round(options.maxQueueDepth));\n this.onQueueDepthChanged = options.onQueueDepthChanged;\n }\n\n static async start(\n lease: QueueOwnerSocketLease,\n controlHandlers: QueueOwnerControlHandlers,\n options: SessionQueueOwnerOptions = {\n maxQueueDepth: 16,\n },\n ): Promise<SessionQueueOwner> {\n const ownerRef: { current: SessionQueueOwner | undefined } = { current: undefined };\n const server = net.createServer((socket) => {\n ownerRef.current?.handleConnection(socket);\n });\n ownerRef.current = new SessionQueueOwner(server, controlHandlers, lease, options);\n\n await new Promise<void>((resolve, reject) => {\n const onListening = () => {\n server.off(\"error\", onError);\n resolve();\n };\n const onError = (error: Error) => {\n server.off(\"listening\", onListening);\n reject(error);\n };\n\n server.once(\"listening\", onListening);\n server.once(\"error\", onError);\n server.listen(lease.socketPath);\n });\n\n return ownerRef.current;\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n\n this.closed = true;\n for (const waiter of this.waiters.splice(0)) {\n waiter(undefined);\n }\n\n for (const task of this.pending.splice(0)) {\n if (task.waitForCompletion) {\n task.send(\n makeQueueOwnerError(\n task.requestId,\n \"Queue owner shutting down before prompt execution\",\n \"QUEUE_OWNER_SHUTTING_DOWN\",\n {\n retryable: true,\n },\n ),\n );\n }\n task.close();\n }\n this.emitQueueDepth();\n\n await new Promise<void>((resolve) => {\n this.server.close(() => resolve());\n });\n }\n\n async nextTask(timeoutMs?: number): Promise<QueueTask | undefined> {\n if (this.pending.length > 0) {\n const task = this.pending.shift();\n this.emitQueueDepth();\n if (task) {\n recordPerfDuration(\"queue.owner.wait_ms\", Date.now() - task.enqueuedAt);\n }\n return task;\n }\n if (this.closed) {\n return undefined;\n }\n\n return await new Promise<QueueTask | undefined>((resolve) => {\n const shouldTimeout = timeoutMs != null;\n const timer =\n shouldTimeout &&\n setTimeout(\n () => {\n const index = this.waiters.indexOf(waiter);\n if (index >= 0) {\n this.waiters.splice(index, 1);\n }\n resolve(undefined);\n },\n Math.max(0, timeoutMs),\n );\n\n const waiter = (task: QueueTask | undefined) => {\n if (timer) {\n clearTimeout(timer);\n }\n resolve(task);\n };\n\n this.waiters.push(waiter);\n });\n }\n\n queueDepth(): number {\n return this.pending.length;\n }\n\n private emitQueueDepth(): void {\n this.onQueueDepthChanged?.(this.pending.length);\n }\n\n private enqueue(task: QueueTask): void {\n if (this.closed) {\n if (task.waitForCompletion) {\n task.send(\n makeQueueOwnerError(\n task.requestId,\n \"Queue owner is shutting down\",\n \"QUEUE_OWNER_SHUTTING_DOWN\",\n {\n retryable: true,\n },\n ),\n );\n }\n task.close();\n return;\n }\n\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter(task);\n return;\n }\n\n if (this.pending.length >= this.maxQueueDepth) {\n if (task.waitForCompletion) {\n task.send({\n ...makeQueueOwnerError(\n task.requestId,\n `Queue owner is overloaded (${this.pending.length}/${this.maxQueueDepth} queued)`,\n \"QUEUE_OWNER_OVERLOADED\",\n {\n retryable: true,\n },\n ),\n ownerGeneration: this.ownerGeneration,\n });\n }\n task.close();\n return;\n }\n\n this.pending.push(task);\n this.emitQueueDepth();\n }\n\n private handleControlRequest<TMessage extends QueueOwnerMessage>(options: {\n socket: net.Socket;\n requestId: string;\n run: () => Promise<TMessage>;\n }): void {\n writeQueueMessage(options.socket, {\n type: \"accepted\",\n requestId: options.requestId,\n ownerGeneration: this.ownerGeneration,\n });\n\n void options\n .run()\n .then((message) => {\n writeQueueMessage(options.socket, {\n ...message,\n ownerGeneration: this.ownerGeneration,\n });\n })\n .catch((error) => {\n writeQueueMessage(options.socket, {\n ...makeQueueOwnerErrorFromUnknown(\n options.requestId,\n error,\n \"QUEUE_CONTROL_REQUEST_FAILED\",\n ),\n ownerGeneration: this.ownerGeneration,\n });\n })\n .finally(() => {\n if (!options.socket.destroyed) {\n options.socket.end();\n }\n });\n }\n\n private handleConnection(socket: net.Socket): void {\n socket.setEncoding(\"utf8\");\n\n if (this.closed) {\n writeQueueMessage(\n socket,\n makeQueueOwnerError(\"unknown\", \"Queue owner is closed\", \"QUEUE_OWNER_CLOSED\", {\n retryable: true,\n }),\n );\n socket.end();\n return;\n }\n\n let buffer = \"\";\n let handled = false;\n\n const fail = (requestId: string, message: string, detailCode: string): void => {\n writeQueueMessage(socket, {\n ...makeQueueOwnerError(requestId, message, detailCode, {\n retryable: false,\n }),\n ownerGeneration: this.ownerGeneration,\n });\n socket.end();\n };\n\n const processLine = (line: string): void => {\n if (handled) {\n return;\n }\n handled = true;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n fail(\"unknown\", \"Invalid queue request payload\", \"QUEUE_REQUEST_PAYLOAD_INVALID_JSON\");\n return;\n }\n\n const request = parseQueueRequest(parsed);\n if (!request) {\n fail(\"unknown\", \"Invalid queue request\", \"QUEUE_REQUEST_INVALID\");\n return;\n }\n\n if (\n request.ownerGeneration !== undefined &&\n this.ownerGeneration !== undefined &&\n request.ownerGeneration !== this.ownerGeneration\n ) {\n fail(\n request.requestId,\n \"Queue request targeted a stale queue owner generation\",\n \"QUEUE_OWNER_GENERATION_MISMATCH\",\n );\n return;\n }\n\n if (request.type === \"cancel_prompt\") {\n this.handleControlRequest({\n socket,\n requestId: request.requestId,\n run: async () => ({\n type: \"cancel_result\",\n requestId: request.requestId,\n cancelled: await this.controlHandlers.cancelPrompt(),\n }),\n });\n return;\n }\n\n if (request.type === \"set_mode\") {\n this.handleControlRequest({\n socket,\n requestId: request.requestId,\n run: async () => {\n await this.controlHandlers.setSessionMode(request.modeId, request.timeoutMs);\n return {\n type: \"set_mode_result\",\n requestId: request.requestId,\n modeId: request.modeId,\n };\n },\n });\n return;\n }\n\n if (request.type === \"set_model\") {\n this.handleControlRequest({\n socket,\n requestId: request.requestId,\n run: async () => {\n await this.controlHandlers.setSessionModel(request.modelId, request.timeoutMs);\n return {\n type: \"set_model_result\",\n requestId: request.requestId,\n modelId: request.modelId,\n };\n },\n });\n return;\n }\n\n if (request.type === \"set_config_option\") {\n this.handleControlRequest({\n socket,\n requestId: request.requestId,\n run: async () => ({\n type: \"set_config_option_result\",\n requestId: request.requestId,\n response: await this.controlHandlers.setSessionConfigOption(\n request.configId,\n request.value,\n request.timeoutMs,\n ),\n }),\n });\n return;\n }\n\n const task: QueueTask = {\n requestId: request.requestId,\n message: request.message,\n prompt: request.prompt ?? textPrompt(request.message),\n permissionMode: request.permissionMode,\n resumePolicy: request.resumePolicy,\n nonInteractivePermissions: request.nonInteractivePermissions,\n timeoutMs: request.timeoutMs,\n suppressSdkConsoleErrors: request.suppressSdkConsoleErrors,\n sessionOptions: request.sessionOptions,\n waitForCompletion: request.waitForCompletion,\n enqueuedAt: Date.now(),\n send: (message) => {\n writeQueueMessage(socket, {\n ...message,\n ownerGeneration: this.ownerGeneration,\n });\n },\n close: () => {\n if (!socket.destroyed) {\n socket.end();\n }\n },\n };\n\n writeQueueMessage(socket, {\n type: \"accepted\",\n requestId: request.requestId,\n ownerGeneration: this.ownerGeneration,\n });\n\n if (!request.waitForCompletion) {\n task.close();\n }\n\n this.enqueue(task);\n };\n\n socket.on(\"data\", (chunk: string) => {\n buffer += chunk;\n\n let index = buffer.indexOf(\"\\n\");\n while (index >= 0) {\n const line = buffer.slice(0, index).trim();\n buffer = buffer.slice(index + 1);\n\n if (line.length > 0) {\n processLine(line);\n }\n\n index = buffer.indexOf(\"\\n\");\n }\n });\n\n socket.on(\"error\", () => {\n // no-op: queue processing continues even if client disconnects\n });\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { SetSessionConfigOptionResponse } from \"@agentclientprotocol/sdk\";\nimport { QueueConnectionError, QueueProtocolError } from \"../../errors.js\";\nimport { incrementPerfCounter } from \"../../perf-metrics.js\";\nimport type {\n AcpClientOptions,\n NonInteractivePermissionPolicy,\n OutputErrorEmissionPolicy,\n OutputFormatter,\n PermissionMode,\n PromptInput,\n SessionResumePolicy,\n SessionEnqueueResult,\n SessionSendOutcome,\n} from \"../../types.js\";\nimport { probeQueueOwnerHealth, type QueueOwnerHealth } from \"./ipc-health.js\";\nimport { QUEUE_CONNECT_RETRY_MS, connectToQueueOwner } from \"./ipc-transport.js\";\nimport {\n type QueueOwnerRecord,\n readQueueOwnerRecord,\n terminateQueueOwnerForSession,\n} from \"./lease-store.js\";\nimport {\n parseQueueOwnerMessage,\n type QueueCancelRequest,\n type QueueOwnerCancelResultMessage,\n type QueueOwnerMessage,\n type QueueOwnerSetConfigOptionResultMessage,\n type QueueOwnerSetModelResultMessage,\n type QueueOwnerSetModeResultMessage,\n type QueueRequest,\n type QueueSetConfigOptionRequest,\n type QueueSetModelRequest,\n type QueueSetModeRequest,\n type QueueSubmitRequest,\n} from \"./messages.js\";\n\nexport { QUEUE_CONNECT_RETRY_MS } from \"./ipc-transport.js\";\nexport const MAX_MESSAGE_BUFFER_SIZE = 10 * 1024 * 1024;\nexport {\n isProcessAlive,\n releaseQueueOwnerLease,\n terminateProcess,\n terminateQueueOwnerForSession,\n tryAcquireQueueOwnerLease,\n waitMs,\n} from \"./lease-store.js\";\nexport type { QueueOwnerLease } from \"./lease-store.js\";\n\nconst STALE_OWNER_PROTOCOL_DETAIL_CODES = new Set([\n \"QUEUE_PROTOCOL_MALFORMED_MESSAGE\",\n \"QUEUE_PROTOCOL_UNEXPECTED_RESPONSE\",\n]);\n\nasync function maybeRecoverStaleOwnerAfterProtocolMismatch(params: {\n sessionId: string;\n owner: QueueOwnerRecord;\n error: unknown;\n verbose?: boolean;\n}): Promise<boolean> {\n if (!(params.error instanceof QueueProtocolError)) {\n return false;\n }\n\n const detailCode = params.error.detailCode;\n if (!detailCode || !STALE_OWNER_PROTOCOL_DETAIL_CODES.has(detailCode)) {\n return false;\n }\n\n await terminateQueueOwnerForSession(params.sessionId).catch(() => {\n // Preserve existing behavior if cleanup fails.\n });\n incrementPerfCounter(\"queue.owner.stale_recovered\");\n\n if (params.verbose) {\n process.stderr.write(\n `[acpx] dropped stale queue owner metadata after protocol mismatch for session ${params.sessionId} (${detailCode})\\n`,\n );\n }\n\n return true;\n}\nexport { probeQueueOwnerHealth };\nexport type { QueueOwnerHealth };\nexport type { QueueOwnerMessage, QueueSubmitRequest } from \"./messages.js\";\nexport type { QueueOwnerControlHandlers, QueueTask } from \"./ipc-server.js\";\nexport { SessionQueueOwner } from \"./ipc-server.js\";\n\nfunction assertOwnerGeneration(\n owner: QueueOwnerRecord,\n message: QueueOwnerMessage,\n): QueueOwnerMessage {\n if (\n owner.ownerGeneration !== undefined &&\n message.ownerGeneration !== undefined &&\n message.ownerGeneration !== owner.ownerGeneration\n ) {\n throw new QueueProtocolError(\"Queue owner returned mismatched generation\", {\n detailCode: \"QUEUE_OWNER_GENERATION_MISMATCH\",\n origin: \"queue\",\n retryable: true,\n });\n }\n return message;\n}\n\ntype QueueOwnerRequestState = {\n acknowledged: boolean;\n};\n\ntype QueueOwnerRequestControls<TResult> = {\n state: QueueOwnerRequestState;\n resolve: (result: TResult) => void;\n reject: (error: unknown) => void;\n};\n\nfunction makeMalformedQueueMessageError(): QueueProtocolError {\n return new QueueProtocolError(\"Queue owner sent malformed message\", {\n detailCode: \"QUEUE_PROTOCOL_MALFORMED_MESSAGE\",\n origin: \"queue\",\n retryable: true,\n });\n}\n\nfunction parseQueueOwnerResponseLine(\n owner: QueueOwnerRecord,\n requestId: string,\n line: string,\n): QueueOwnerMessage {\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n throw new QueueProtocolError(\"Queue owner sent invalid JSON payload\", {\n detailCode: \"QUEUE_PROTOCOL_INVALID_JSON\",\n origin: \"queue\",\n retryable: true,\n });\n }\n\n const parsedMessage = parseQueueOwnerMessage(parsed);\n if (!parsedMessage) {\n throw makeMalformedQueueMessageError();\n }\n\n const message = assertOwnerGeneration(owner, parsedMessage);\n if (message.requestId !== requestId) {\n throw makeMalformedQueueMessageError();\n }\n\n return message;\n}\n\nasync function runQueueOwnerRequest<TResult>(options: {\n owner: QueueOwnerRecord;\n request: QueueRequest;\n onAccepted?: (controls: QueueOwnerRequestControls<TResult>) => void;\n onMessage: (message: QueueOwnerMessage, controls: QueueOwnerRequestControls<TResult>) => void;\n onClose: (controls: QueueOwnerRequestControls<TResult>) => void;\n}): Promise<TResult | undefined> {\n const socket = await connectToQueueOwner(options.owner);\n if (!socket) {\n return undefined;\n }\n\n socket.setEncoding(\"utf8\");\n\n return await new Promise<TResult>((resolve, reject) => {\n let settled = false;\n let buffer = \"\";\n const state: QueueOwnerRequestState = {\n acknowledged: false,\n };\n\n const finishResolve = (result: TResult) => {\n if (settled) {\n return;\n }\n settled = true;\n socket.removeAllListeners();\n if (!socket.destroyed) {\n socket.end();\n }\n resolve(result);\n };\n\n const finishReject = (error: unknown) => {\n if (settled) {\n return;\n }\n settled = true;\n socket.removeAllListeners();\n if (!socket.destroyed) {\n socket.destroy();\n }\n reject(error);\n };\n\n const controls: QueueOwnerRequestControls<TResult> = {\n state,\n resolve: finishResolve,\n reject: finishReject,\n };\n\n const processLine = (line: string): void => {\n let message: QueueOwnerMessage;\n try {\n message = parseQueueOwnerResponseLine(options.owner, options.request.requestId, line);\n } catch (error) {\n finishReject(error);\n return;\n }\n\n if (message.type === \"accepted\") {\n state.acknowledged = true;\n options.onAccepted?.(controls);\n return;\n }\n\n options.onMessage(message, controls);\n };\n\n socket.on(\"data\", (chunk: string) => {\n buffer += chunk;\n\n if (buffer.length > MAX_MESSAGE_BUFFER_SIZE) {\n socket.destroy();\n finishReject(new Error(`Message buffer exceeded ${MAX_MESSAGE_BUFFER_SIZE} bytes`));\n return;\n }\n\n let index = buffer.indexOf(\"\\n\");\n while (index >= 0) {\n const line = buffer.slice(0, index).trim();\n buffer = buffer.slice(index + 1);\n\n if (line.length > 0) {\n processLine(line);\n }\n\n index = buffer.indexOf(\"\\n\");\n }\n });\n\n socket.once(\"error\", (error: Error) => {\n finishReject(error);\n });\n\n socket.once(\"close\", () => {\n if (settled) {\n return;\n }\n options.onClose(controls);\n });\n\n socket.write(`${JSON.stringify(options.request)}\\n`);\n });\n}\n\nexport type SubmitToQueueOwnerOptions = {\n sessionId: string;\n message: string;\n prompt?: PromptInput;\n permissionMode: PermissionMode;\n resumePolicy?: SessionResumePolicy;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n outputFormatter: OutputFormatter;\n errorEmissionPolicy?: OutputErrorEmissionPolicy;\n timeoutMs?: number;\n suppressSdkConsoleErrors?: boolean;\n waitForCompletion: boolean;\n verbose?: boolean;\n sessionOptions?: NonNullable<AcpClientOptions[\"sessionOptions\"]>;\n};\n\nasync function submitToQueueOwner(\n owner: QueueOwnerRecord,\n options: SubmitToQueueOwnerOptions,\n): Promise<SessionSendOutcome | undefined> {\n const requestId = randomUUID();\n const request: QueueSubmitRequest = {\n type: \"submit_prompt\",\n requestId,\n ownerGeneration: owner.ownerGeneration,\n message: options.message,\n prompt: options.prompt,\n permissionMode: options.permissionMode,\n resumePolicy: options.resumePolicy,\n nonInteractivePermissions: options.nonInteractivePermissions,\n timeoutMs: options.timeoutMs,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n waitForCompletion: options.waitForCompletion,\n sessionOptions: options.sessionOptions,\n };\n\n options.outputFormatter.setContext({\n sessionId: options.sessionId,\n });\n\n return await runQueueOwnerRequest<SessionSendOutcome>({\n owner,\n request,\n onAccepted: ({ resolve }) => {\n options.outputFormatter.setContext({\n sessionId: options.sessionId,\n });\n if (!options.waitForCompletion) {\n const queued: SessionEnqueueResult = {\n queued: true,\n sessionId: options.sessionId,\n requestId,\n };\n resolve(queued);\n }\n },\n onMessage: (message, { state, resolve, reject }) => {\n if (message.type === \"error\") {\n options.outputFormatter.setContext({\n sessionId: options.sessionId,\n });\n\n const queueErrorAlreadyEmitted =\n options.errorEmissionPolicy?.queueErrorAlreadyEmitted ?? true;\n const outputAlreadyEmitted = message.outputAlreadyEmitted === true;\n const shouldEmitInFormatter = !outputAlreadyEmitted || !queueErrorAlreadyEmitted;\n if (shouldEmitInFormatter) {\n options.outputFormatter.onError({\n code: message.code ?? \"RUNTIME\",\n detailCode: message.detailCode,\n origin: message.origin ?? \"queue\",\n message: message.message,\n retryable: message.retryable,\n acp: message.acp,\n });\n options.outputFormatter.flush();\n }\n reject(\n new QueueConnectionError(message.message, {\n outputCode: message.code,\n detailCode: message.detailCode,\n origin: message.origin ?? \"queue\",\n retryable: message.retryable,\n acp: message.acp,\n ...(queueErrorAlreadyEmitted ? { outputAlreadyEmitted: true } : {}),\n }),\n );\n return;\n }\n\n if (!state.acknowledged) {\n reject(\n new QueueConnectionError(\"Queue owner did not acknowledge request\", {\n detailCode: \"QUEUE_ACK_MISSING\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n return;\n }\n\n if (message.type === \"event\") {\n options.outputFormatter.onAcpMessage(message.message);\n return;\n }\n\n if (message.type === \"result\") {\n options.outputFormatter.flush();\n resolve(message.result);\n return;\n }\n\n reject(\n new QueueProtocolError(\"Queue owner returned unexpected response\", {\n detailCode: \"QUEUE_PROTOCOL_UNEXPECTED_RESPONSE\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n },\n onClose: ({ state, resolve, reject }) => {\n if (!state.acknowledged) {\n reject(\n new QueueConnectionError(\"Queue owner disconnected before acknowledging request\", {\n detailCode: \"QUEUE_DISCONNECTED_BEFORE_ACK\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n return;\n }\n\n if (!options.waitForCompletion) {\n const queued: SessionEnqueueResult = {\n queued: true,\n sessionId: options.sessionId,\n requestId,\n };\n resolve(queued);\n return;\n }\n\n reject(\n new QueueConnectionError(\"Queue owner disconnected before prompt completion\", {\n detailCode: \"QUEUE_DISCONNECTED_BEFORE_COMPLETION\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n },\n });\n}\n\nasync function submitControlToQueueOwner<TResponse extends QueueOwnerMessage>(\n owner: QueueOwnerRecord,\n request: QueueRequest,\n isExpectedResponse: (message: QueueOwnerMessage) => message is TResponse,\n): Promise<TResponse | undefined> {\n return await runQueueOwnerRequest<TResponse>({\n owner,\n request,\n onMessage: (message, { state, resolve, reject }) => {\n if (message.type === \"error\") {\n reject(\n new QueueConnectionError(message.message, {\n outputCode: message.code,\n detailCode: message.detailCode,\n origin: message.origin ?? \"queue\",\n retryable: message.retryable,\n acp: message.acp,\n }),\n );\n return;\n }\n\n if (!state.acknowledged) {\n reject(\n new QueueConnectionError(\"Queue owner did not acknowledge request\", {\n detailCode: \"QUEUE_ACK_MISSING\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n return;\n }\n\n if (!isExpectedResponse(message)) {\n reject(\n new QueueProtocolError(\"Queue owner returned unexpected response\", {\n detailCode: \"QUEUE_PROTOCOL_UNEXPECTED_RESPONSE\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n return;\n }\n\n resolve(message);\n },\n onClose: ({ state, reject }) => {\n if (!state.acknowledged) {\n reject(\n new QueueConnectionError(\"Queue owner disconnected before acknowledging request\", {\n detailCode: \"QUEUE_DISCONNECTED_BEFORE_ACK\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n return;\n }\n\n reject(\n new QueueConnectionError(\"Queue owner disconnected before responding\", {\n detailCode: \"QUEUE_DISCONNECTED_BEFORE_COMPLETION\",\n origin: \"queue\",\n retryable: true,\n }),\n );\n },\n });\n}\n\nasync function submitCancelToQueueOwner(owner: QueueOwnerRecord): Promise<boolean | undefined> {\n const request: QueueCancelRequest = {\n type: \"cancel_prompt\",\n requestId: randomUUID(),\n ownerGeneration: owner.ownerGeneration,\n };\n const response = await submitControlToQueueOwner(\n owner,\n request,\n (message): message is QueueOwnerCancelResultMessage => message.type === \"cancel_result\",\n );\n if (!response) {\n return undefined;\n }\n if (response.requestId !== request.requestId) {\n throw new QueueProtocolError(\"Queue owner returned mismatched cancel response\", {\n detailCode: \"QUEUE_PROTOCOL_MALFORMED_MESSAGE\",\n origin: \"queue\",\n retryable: true,\n });\n }\n return response.cancelled;\n}\n\nasync function submitSetModeToQueueOwner(\n owner: QueueOwnerRecord,\n modeId: string,\n timeoutMs?: number,\n): Promise<boolean | undefined> {\n const request: QueueSetModeRequest = {\n type: \"set_mode\",\n requestId: randomUUID(),\n ownerGeneration: owner.ownerGeneration,\n modeId,\n timeoutMs,\n };\n const response = await submitControlToQueueOwner(\n owner,\n request,\n (message): message is QueueOwnerSetModeResultMessage => message.type === \"set_mode_result\",\n );\n if (!response) {\n return undefined;\n }\n if (response.requestId !== request.requestId) {\n throw new QueueProtocolError(\"Queue owner returned mismatched set_mode response\", {\n detailCode: \"QUEUE_PROTOCOL_MALFORMED_MESSAGE\",\n origin: \"queue\",\n retryable: true,\n });\n }\n return true;\n}\n\nasync function submitSetModelToQueueOwner(\n owner: QueueOwnerRecord,\n modelId: string,\n timeoutMs?: number,\n): Promise<boolean | undefined> {\n const request: QueueSetModelRequest = {\n type: \"set_model\",\n requestId: randomUUID(),\n ownerGeneration: owner.ownerGeneration,\n modelId,\n timeoutMs,\n };\n const response = await submitControlToQueueOwner(\n owner,\n request,\n (message): message is QueueOwnerSetModelResultMessage => message.type === \"set_model_result\",\n );\n if (!response) {\n return undefined;\n }\n if (response.requestId !== request.requestId) {\n throw new QueueProtocolError(\"Queue owner returned mismatched set_model response\", {\n detailCode: \"QUEUE_PROTOCOL_MALFORMED_MESSAGE\",\n origin: \"queue\",\n retryable: true,\n });\n }\n return true;\n}\n\nasync function submitSetConfigOptionToQueueOwner(\n owner: QueueOwnerRecord,\n configId: string,\n value: string,\n timeoutMs?: number,\n): Promise<SetSessionConfigOptionResponse | undefined> {\n const request: QueueSetConfigOptionRequest = {\n type: \"set_config_option\",\n requestId: randomUUID(),\n ownerGeneration: owner.ownerGeneration,\n configId,\n value,\n timeoutMs,\n };\n const response = await submitControlToQueueOwner(\n owner,\n request,\n (message): message is QueueOwnerSetConfigOptionResultMessage =>\n message.type === \"set_config_option_result\",\n );\n if (!response) {\n return undefined;\n }\n if (response.requestId !== request.requestId) {\n throw new QueueProtocolError(\"Queue owner returned mismatched set_config_option response\", {\n detailCode: \"QUEUE_PROTOCOL_MALFORMED_MESSAGE\",\n origin: \"queue\",\n retryable: true,\n });\n }\n return response.response;\n}\n\nexport async function trySubmitToRunningOwner(\n options: SubmitToQueueOwnerOptions,\n): Promise<SessionSendOutcome | undefined> {\n const owner = await readQueueOwnerRecord(options.sessionId);\n if (!owner) {\n return undefined;\n }\n\n let submitted: SessionSendOutcome | undefined;\n try {\n submitted = await submitToQueueOwner(owner, options);\n } catch (error) {\n const recovered = await maybeRecoverStaleOwnerAfterProtocolMismatch({\n sessionId: options.sessionId,\n owner,\n error,\n verbose: options.verbose,\n });\n if (recovered) {\n return undefined;\n }\n throw error;\n }\n if (submitted) {\n if (options.verbose) {\n process.stderr.write(\n `[acpx] queued prompt on active owner pid ${owner.pid} for session ${options.sessionId}\\n`,\n );\n }\n return submitted;\n }\n\n const health = await probeQueueOwnerHealth(options.sessionId);\n if (!health.hasLease) {\n return undefined;\n }\n\n throw new QueueConnectionError(\n \"Session queue owner is running but not accepting queue requests\",\n {\n detailCode: \"QUEUE_NOT_ACCEPTING_REQUESTS\",\n origin: \"queue\",\n retryable: true,\n },\n );\n}\n\nexport async function tryCancelOnRunningOwner(options: {\n sessionId: string;\n verbose?: boolean;\n}): Promise<boolean | undefined> {\n const owner = await readQueueOwnerRecord(options.sessionId);\n if (!owner) {\n return undefined;\n }\n\n const cancelled = await submitCancelToQueueOwner(owner);\n if (cancelled !== undefined) {\n if (options.verbose) {\n process.stderr.write(\n `[acpx] requested cancel on active owner pid ${owner.pid} for session ${options.sessionId}\\n`,\n );\n }\n return cancelled;\n }\n\n const health = await probeQueueOwnerHealth(options.sessionId);\n if (!health.hasLease) {\n return undefined;\n }\n\n throw new QueueConnectionError(\n \"Session queue owner is running but not accepting cancel requests\",\n {\n detailCode: \"QUEUE_NOT_ACCEPTING_REQUESTS\",\n origin: \"queue\",\n retryable: true,\n },\n );\n}\n\nexport async function trySetModeOnRunningOwner(\n sessionId: string,\n modeId: string,\n timeoutMs: number | undefined,\n verbose: boolean | undefined,\n): Promise<boolean | undefined> {\n const owner = await readQueueOwnerRecord(sessionId);\n if (!owner) {\n return undefined;\n }\n\n const submitted = await submitSetModeToQueueOwner(owner, modeId, timeoutMs);\n if (submitted) {\n if (verbose) {\n process.stderr.write(\n `[acpx] requested session/set_mode on owner pid ${owner.pid} for session ${sessionId}\\n`,\n );\n }\n return true;\n }\n\n const health = await probeQueueOwnerHealth(sessionId);\n if (!health.hasLease) {\n return undefined;\n }\n\n throw new QueueConnectionError(\n \"Session queue owner is running but not accepting set_mode requests\",\n {\n detailCode: \"QUEUE_NOT_ACCEPTING_REQUESTS\",\n origin: \"queue\",\n retryable: true,\n },\n );\n}\n\nexport async function trySetModelOnRunningOwner(\n sessionId: string,\n modelId: string,\n timeoutMs: number | undefined,\n verbose: boolean | undefined,\n): Promise<boolean | undefined> {\n const owner = await readQueueOwnerRecord(sessionId);\n if (!owner) {\n return undefined;\n }\n\n const submitted = await submitSetModelToQueueOwner(owner, modelId, timeoutMs);\n if (submitted) {\n if (verbose) {\n process.stderr.write(\n `[acpx] requested session/set_model on owner pid ${owner.pid} for session ${sessionId}\\n`,\n );\n }\n return true;\n }\n\n const health = await probeQueueOwnerHealth(sessionId);\n if (!health.hasLease) {\n return undefined;\n }\n\n throw new QueueConnectionError(\n \"Session queue owner is running but not accepting set_model requests\",\n {\n detailCode: \"QUEUE_NOT_ACCEPTING_REQUESTS\",\n origin: \"queue\",\n retryable: true,\n },\n );\n}\n\nexport async function trySetConfigOptionOnRunningOwner(\n sessionId: string,\n configId: string,\n value: string,\n timeoutMs: number | undefined,\n verbose: boolean | undefined,\n): Promise<SetSessionConfigOptionResponse | undefined> {\n const owner = await readQueueOwnerRecord(sessionId);\n if (!owner) {\n return undefined;\n }\n\n const response = await submitSetConfigOptionToQueueOwner(owner, configId, value, timeoutMs);\n if (response) {\n if (verbose) {\n process.stderr.write(\n `[acpx] requested session/set_config_option on owner pid ${owner.pid} for session ${sessionId}\\n`,\n );\n }\n return response;\n }\n\n const health = await probeQueueOwnerHealth(sessionId);\n if (!health.hasLease) {\n return undefined;\n }\n\n throw new QueueConnectionError(\n \"Session queue owner is running but not accepting set_config_option requests\",\n {\n detailCode: \"QUEUE_NOT_ACCEPTING_REQUESTS\",\n origin: \"queue\",\n retryable: true,\n },\n );\n}\n"],"mappings":"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"}
|
|
@@ -24,13 +24,26 @@ function buildFallbackData(params) {
|
|
|
24
24
|
for (const [key, value] of Object.entries(data)) if (value === void 0) delete data[key];
|
|
25
25
|
return data;
|
|
26
26
|
}
|
|
27
|
-
function
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
...
|
|
27
|
+
function mergeAcpErrorData(acpData, fallbackData) {
|
|
28
|
+
if (Object.keys(fallbackData).length === 0) return acpData;
|
|
29
|
+
if (acpData === void 0) return fallbackData;
|
|
30
|
+
if (acpData && typeof acpData === "object" && !Array.isArray(acpData)) return {
|
|
31
|
+
...fallbackData,
|
|
32
|
+
...acpData
|
|
32
33
|
};
|
|
33
|
-
|
|
34
|
+
return acpData;
|
|
35
|
+
}
|
|
36
|
+
function buildErrorObject(params) {
|
|
37
|
+
const fallbackData = buildFallbackData(params);
|
|
38
|
+
if (hasValidAcpError(params.acp)) {
|
|
39
|
+
const data = mergeAcpErrorData(params.acp.data, fallbackData);
|
|
40
|
+
return {
|
|
41
|
+
code: params.acp.code,
|
|
42
|
+
message: params.acp.message,
|
|
43
|
+
...data !== void 0 ? { data } : {}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const data = fallbackData;
|
|
34
47
|
return {
|
|
35
48
|
code: OUTPUT_ERROR_JSONRPC_CODES[params.outputCode] ?? -32603,
|
|
36
49
|
message: params.message,
|
|
@@ -188,7 +201,10 @@ function createJsonOutputFormatter(stdout, suppressReads = false, context) {
|
|
|
188
201
|
}
|
|
189
202
|
//#endregion
|
|
190
203
|
//#region src/cli/output/output.ts
|
|
191
|
-
var output_exports = /* @__PURE__ */ __exportAll({
|
|
204
|
+
var output_exports = /* @__PURE__ */ __exportAll({
|
|
205
|
+
createOutputFormatter: () => createOutputFormatter,
|
|
206
|
+
getTextErrorRemediationHints: () => getTextErrorRemediationHints
|
|
207
|
+
});
|
|
192
208
|
const MAX_THOUGHT_CHARS = 900;
|
|
193
209
|
const MAX_INLINE_CHARS = 220;
|
|
194
210
|
const MAX_OUTPUT_CHARS = 2e3;
|
|
@@ -277,6 +293,15 @@ function readFirstString(source, keys) {
|
|
|
277
293
|
if (typeof value === "string" && value.trim()) return value.trim();
|
|
278
294
|
}
|
|
279
295
|
}
|
|
296
|
+
function readFirstFiniteNumber(source, keys) {
|
|
297
|
+
for (const key of keys) {
|
|
298
|
+
const value = source[key];
|
|
299
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
function formatMetadataNumber(value) {
|
|
303
|
+
return Number.isInteger(value) ? String(value) : String(Number(value.toFixed(8)));
|
|
304
|
+
}
|
|
280
305
|
function readFirstStringArray(source, keys) {
|
|
281
306
|
for (const key of keys) {
|
|
282
307
|
const value = source[key];
|
|
@@ -285,6 +310,55 @@ function readFirstStringArray(source, keys) {
|
|
|
285
310
|
if (entries.length > 0) return entries;
|
|
286
311
|
}
|
|
287
312
|
}
|
|
313
|
+
function formatDisjunction(values) {
|
|
314
|
+
if (values.length <= 1) return values[0] ?? "";
|
|
315
|
+
if (values.length === 2) return `${values[0]} or ${values[1]}`;
|
|
316
|
+
return `${values.slice(0, -1).join(", ")}, or ${values.at(-1)}`;
|
|
317
|
+
}
|
|
318
|
+
function parseAuthMethodIdsFromMessage(message) {
|
|
319
|
+
const methods = [];
|
|
320
|
+
const methodListMatch = message.match(/auth methods \[([^\]]+)\]/iu);
|
|
321
|
+
if (methodListMatch) methods.push(...methodListMatch[1].split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0));
|
|
322
|
+
const singleMethodMatch = message.match(/auth method ([\w.-]+)/iu);
|
|
323
|
+
if (singleMethodMatch) methods.push(singleMethodMatch[1]);
|
|
324
|
+
return dedupeStrings(methods);
|
|
325
|
+
}
|
|
326
|
+
function parseAuthMethodIdsFromAcpData(data) {
|
|
327
|
+
const record = asRecord(data);
|
|
328
|
+
if (!record) return [];
|
|
329
|
+
const methodIds = [];
|
|
330
|
+
if (typeof record.methodId === "string" && record.methodId.trim().length > 0) methodIds.push(record.methodId.trim());
|
|
331
|
+
if (Array.isArray(record.methods)) for (const entry of record.methods) {
|
|
332
|
+
if (typeof entry === "string" && entry.trim().length > 0) {
|
|
333
|
+
methodIds.push(entry.trim());
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const id = asRecord(entry)?.id;
|
|
337
|
+
if (typeof id === "string" && id.trim().length > 0) methodIds.push(id.trim());
|
|
338
|
+
}
|
|
339
|
+
return dedupeStrings(methodIds);
|
|
340
|
+
}
|
|
341
|
+
function renderAuthRequiredHint(params) {
|
|
342
|
+
const methodIds = dedupeStrings([...parseAuthMethodIdsFromAcpData(params.acp?.data), ...parseAuthMethodIdsFromMessage(params.message)]);
|
|
343
|
+
if (methodIds.length === 0) return "hint: run `acpx config show` to locate the active config, then add the required credential under `auth` and retry.";
|
|
344
|
+
return `hint: run \`acpx config show\` to locate the active config, then add ${formatDisjunction(methodIds.map((methodId) => `\`auth.${methodId}\``))} and retry.`;
|
|
345
|
+
}
|
|
346
|
+
function getTextErrorRemediationHints(params) {
|
|
347
|
+
const lowerMessage = params.message.toLowerCase();
|
|
348
|
+
if (params.detailCode === "AUTH_REQUIRED") return [renderAuthRequiredHint(params)];
|
|
349
|
+
if (params.code === "TIMEOUT") return ["hint: increase `--timeout <seconds>` for long-running prompts, or check whether the agent/provider is stalled."];
|
|
350
|
+
if (params.code === "NO_SESSION") {
|
|
351
|
+
if (lowerMessage.includes("create one:")) return [];
|
|
352
|
+
return ["hint: the saved ACP session is missing or stale; start a fresh session with `acpx <agent> sessions new`, then retry."];
|
|
353
|
+
}
|
|
354
|
+
if (lowerMessage.includes("does not support session/load")) return ["hint: this adapter cannot resume saved ACP sessions; create a fresh one with `acpx <agent> sessions new` instead of reusing `--resume-session`."];
|
|
355
|
+
if (lowerMessage.includes("failed to resume acp session") || lowerMessage.includes("session/load")) return ["hint: rerun with `--verbose` to capture the ACP load failure details.", "hint: if you do not need the old backend session, start a fresh one with `acpx <agent> sessions new` and retry."];
|
|
356
|
+
if (/\b429\b/u.test(params.message) || lowerMessage.includes("rate limit") || lowerMessage.includes("quota exceeded")) return ["hint: the provider appears rate-limited; retry later, switch model, or check provider quota/billing."];
|
|
357
|
+
if (lowerMessage.includes("model not found") || lowerMessage.includes("unknown model") || lowerMessage.includes("invalid model")) return ["hint: check the configured model name for this agent, then retry with `--model <model>` or `sessions set-model <model>`."];
|
|
358
|
+
if (lowerMessage.includes("session/set_mode") || lowerMessage.includes("session/set_model") || lowerMessage.includes("session/set_config_option")) return ["hint: rerun with `--verbose` to capture the ACP method/error details before retrying."];
|
|
359
|
+
if (params.origin === "acp" && params.code === "RUNTIME" && (params.acp?.code === -32602 || params.acp?.code === -32603 || lowerMessage.includes("internal error"))) return ["hint: rerun with `--verbose` to capture the underlying ACP error details."];
|
|
360
|
+
return [];
|
|
361
|
+
}
|
|
288
362
|
function summarizeToolInput(rawInput) {
|
|
289
363
|
if (rawInput == null) return;
|
|
290
364
|
if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") return toInline(String(rawInput));
|
|
@@ -501,6 +575,7 @@ var TextOutputFormatter = class {
|
|
|
501
575
|
this.flushThoughtBuffer();
|
|
502
576
|
this.beginSection("done");
|
|
503
577
|
this.writeLine(this.formatAnsi(`[error] ${params.code}: ${params.message}`, "31"));
|
|
578
|
+
for (const hint of getTextErrorRemediationHints(params)) this.writeLine(this.dim(hint));
|
|
504
579
|
}
|
|
505
580
|
onClientOperation(operation) {
|
|
506
581
|
this.flushThoughtBuffer();
|
|
@@ -639,10 +714,13 @@ var TextOutputFormatter = class {
|
|
|
639
714
|
};
|
|
640
715
|
var QuietOutputFormatter = class {
|
|
641
716
|
stdout;
|
|
717
|
+
stderr;
|
|
642
718
|
chunks = [];
|
|
643
719
|
flushed = false;
|
|
644
|
-
|
|
720
|
+
metadataFlushed = false;
|
|
721
|
+
constructor(stdout, stderr) {
|
|
645
722
|
this.stdout = stdout;
|
|
723
|
+
this.stderr = stderr;
|
|
646
724
|
}
|
|
647
725
|
setContext(_context) {}
|
|
648
726
|
onAcpMessage(message) {
|
|
@@ -651,7 +729,10 @@ var QuietOutputFormatter = class {
|
|
|
651
729
|
this.chunks.push(update.update.content.text);
|
|
652
730
|
return;
|
|
653
731
|
}
|
|
654
|
-
if (parsePromptStopReason(message))
|
|
732
|
+
if (parsePromptStopReason(message)) {
|
|
733
|
+
this.flushBufferedOutput();
|
|
734
|
+
this.flushMetadata(message);
|
|
735
|
+
}
|
|
655
736
|
}
|
|
656
737
|
onError(_params) {}
|
|
657
738
|
flush() {}
|
|
@@ -661,18 +742,66 @@ var QuietOutputFormatter = class {
|
|
|
661
742
|
const text = this.chunks.join("");
|
|
662
743
|
this.stdout.write(text.endsWith("\n") ? text : `${text}\n`);
|
|
663
744
|
}
|
|
745
|
+
flushMetadata(message) {
|
|
746
|
+
if (this.metadataFlushed) return;
|
|
747
|
+
this.metadataFlushed = true;
|
|
748
|
+
const result = asRecord(message.result);
|
|
749
|
+
if (!result) return;
|
|
750
|
+
const usageLine = this.formatUsageLine(asRecord(result.usage));
|
|
751
|
+
if (usageLine) this.stderr.write(`${usageLine}\n`);
|
|
752
|
+
const costLine = this.formatCostLine(result.cost);
|
|
753
|
+
if (costLine) this.stderr.write(`${costLine}\n`);
|
|
754
|
+
}
|
|
755
|
+
formatUsageLine(usage) {
|
|
756
|
+
if (!usage) return;
|
|
757
|
+
const parts = [];
|
|
758
|
+
for (const [label, keys] of [
|
|
759
|
+
["input", ["inputTokens", "input_tokens"]],
|
|
760
|
+
["output", ["outputTokens", "output_tokens"]],
|
|
761
|
+
["cache_read", [
|
|
762
|
+
"cachedReadTokens",
|
|
763
|
+
"cacheReadInputTokens",
|
|
764
|
+
"cache_read_input_tokens"
|
|
765
|
+
]],
|
|
766
|
+
["cache_write", [
|
|
767
|
+
"cachedWriteTokens",
|
|
768
|
+
"cacheCreationInputTokens",
|
|
769
|
+
"cache_creation_input_tokens"
|
|
770
|
+
]],
|
|
771
|
+
["total", ["totalTokens", "total_tokens"]]
|
|
772
|
+
]) {
|
|
773
|
+
const value = readFirstFiniteNumber(usage, keys);
|
|
774
|
+
if (value !== void 0) parts.push(`${label}=${formatMetadataNumber(value)}`);
|
|
775
|
+
}
|
|
776
|
+
return parts.length > 0 ? `[acpx] tokens: ${parts.join(" ")}` : void 0;
|
|
777
|
+
}
|
|
778
|
+
formatCostLine(cost) {
|
|
779
|
+
if (typeof cost === "number" && Number.isFinite(cost)) return `[acpx] cost: ${formatMetadataNumber(cost)}`;
|
|
780
|
+
if (typeof cost === "string" && cost.trim()) return `[acpx] cost: ${cost.trim()}`;
|
|
781
|
+
const record = asRecord(cost);
|
|
782
|
+
if (!record) return;
|
|
783
|
+
const amount = readFirstFiniteNumber(record, [
|
|
784
|
+
"amount",
|
|
785
|
+
"value",
|
|
786
|
+
"total"
|
|
787
|
+
]);
|
|
788
|
+
if (amount === void 0) return;
|
|
789
|
+
const currency = typeof record.currency === "string" && record.currency.trim() ? ` ${record.currency.trim()}` : "";
|
|
790
|
+
return `[acpx] cost: ${formatMetadataNumber(amount)}${currency}`;
|
|
791
|
+
}
|
|
664
792
|
};
|
|
665
793
|
function createOutputFormatter(format, options = {}) {
|
|
666
794
|
const stdout = options.stdout ?? process.stdout;
|
|
795
|
+
const stderr = options.stderr ?? process.stderr;
|
|
667
796
|
const suppressReads = options.suppressReads === true;
|
|
668
797
|
switch (format) {
|
|
669
798
|
case "text": return new TextOutputFormatter(stdout, suppressReads);
|
|
670
799
|
case "json": return createJsonOutputFormatter(stdout, suppressReads, options.jsonContext);
|
|
671
|
-
case "quiet": return new QuietOutputFormatter(stdout);
|
|
800
|
+
case "quiet": return new QuietOutputFormatter(stdout, stderr);
|
|
672
801
|
default: throw new Error("Unsupported output format");
|
|
673
802
|
}
|
|
674
803
|
}
|
|
675
804
|
//#endregion
|
|
676
|
-
export {
|
|
805
|
+
export { getTextErrorRemediationHints as n, output_exports as r, createOutputFormatter as t };
|
|
677
806
|
|
|
678
|
-
//# sourceMappingURL=output-
|
|
807
|
+
//# sourceMappingURL=output-DmHvT8vm.js.map
|