acpx 0.5.2 → 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,20 +1,21 @@
|
|
|
1
|
-
import { B as PermissionPromptUnavailableError, C as isAcpResourceNotFoundError, F as AuthPolicyError, G as
|
|
1
|
+
import { B as PermissionPromptUnavailableError, C as isAcpResourceNotFoundError, F as AuthPolicyError, G as SessionModelReplayError, I as ClaudeAcpSessionCreateTimeoutError, J as SessionResumeRequiredError, K as SessionNotFoundError, L as CopilotAcpUnsupportedError, M as AgentDisconnectedError, N as AgentSpawnError, P as AgentStartupError, R as GeminiAcpStartupTimeoutError, S as extractAcpError, U as SessionConfigOptionReplayError, W as SessionModeReplayError, g as textPrompt, i as measurePerf, j as SESSION_RECORD_SCHEMA, l as extractRuntimeSessionId, q as SessionResolutionError, r as incrementPerfCounter, u as normalizeRuntimeSessionId, v as formatErrorMessage, y as isAcpQueryClosedBeforeResponseError, z as PermissionDeniedError } from "./perf-metrics-DvT_gvUh.js";
|
|
2
2
|
import { r as isSessionUpdateNotification } from "./jsonrpc-DSxh2w5R.js";
|
|
3
3
|
import fs, { statSync } from "node:fs";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import fs$1 from "node:fs/promises";
|
|
7
7
|
import os from "node:os";
|
|
8
|
-
import { spawn } from "node:child_process";
|
|
8
|
+
import { execFile, spawn } from "node:child_process";
|
|
9
9
|
import { Readable, Writable } from "node:stream";
|
|
10
10
|
import { ClientSideConnection, PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
|
|
11
11
|
import readline from "node:readline/promises";
|
|
12
|
+
import { promisify } from "node:util";
|
|
12
13
|
import { randomUUID } from "node:crypto";
|
|
13
14
|
//#region src/agent-registry.ts
|
|
14
15
|
const ACP_ADAPTER_PACKAGE_RANGES = {
|
|
15
|
-
pi: "^0.0.
|
|
16
|
-
codex: "^0.
|
|
17
|
-
claude: "^0.
|
|
16
|
+
pi: "^0.0.26",
|
|
17
|
+
codex: "^0.12.0",
|
|
18
|
+
claude: "^0.31.0"
|
|
18
19
|
};
|
|
19
20
|
const AGENT_REGISTRY = {
|
|
20
21
|
pi: `npx pi-acp@${ACP_ADAPTER_PACKAGE_RANGES.pi}`,
|
|
@@ -278,6 +279,7 @@ const MAP_OBJECT_PATHS = new Set(["request_token_usage", "messages.Agent.tool_re
|
|
|
278
279
|
const OPAQUE_VALUE_PATHS = new Set([
|
|
279
280
|
"agent_capabilities",
|
|
280
281
|
"messages.Agent.content.ToolUse.input",
|
|
282
|
+
"acpx.desired_config_options",
|
|
281
283
|
"acpx.config_options"
|
|
282
284
|
]);
|
|
283
285
|
function isRecord(value) {
|
|
@@ -480,6 +482,12 @@ function parseAcpxState(raw) {
|
|
|
480
482
|
if (record.reset_on_next_ensure === true) state.reset_on_next_ensure = true;
|
|
481
483
|
if (typeof record.current_mode_id === "string") state.current_mode_id = record.current_mode_id;
|
|
482
484
|
if (typeof record.desired_mode_id === "string") state.desired_mode_id = record.desired_mode_id;
|
|
485
|
+
const desiredConfigOptions = asRecord$3(record.desired_config_options);
|
|
486
|
+
if (desiredConfigOptions) {
|
|
487
|
+
const parsed = {};
|
|
488
|
+
for (const [key, value] of Object.entries(desiredConfigOptions)) if (typeof key === "string" && typeof value === "string") parsed[key] = value;
|
|
489
|
+
if (Object.keys(parsed).length > 0) state.desired_config_options = parsed;
|
|
490
|
+
}
|
|
483
491
|
if (typeof record.current_model_id === "string") state.current_model_id = record.current_model_id;
|
|
484
492
|
if (isStringArray(record.available_models)) state.available_models = [...record.available_models];
|
|
485
493
|
if (isStringArray(record.available_commands)) state.available_commands = [...record.available_commands];
|
|
@@ -490,6 +498,12 @@ function parseAcpxState(raw) {
|
|
|
490
498
|
if (typeof sessionOptions.model === "string") parsedSessionOptions.model = sessionOptions.model;
|
|
491
499
|
if (isStringArray(sessionOptions.allowed_tools)) parsedSessionOptions.allowed_tools = [...sessionOptions.allowed_tools];
|
|
492
500
|
if (typeof sessionOptions.max_turns === "number" && Number.isInteger(sessionOptions.max_turns) && sessionOptions.max_turns > 0) parsedSessionOptions.max_turns = sessionOptions.max_turns;
|
|
501
|
+
const rawSystemPrompt = sessionOptions.system_prompt;
|
|
502
|
+
if (typeof rawSystemPrompt === "string" && rawSystemPrompt.length > 0) parsedSessionOptions.system_prompt = rawSystemPrompt;
|
|
503
|
+
else {
|
|
504
|
+
const appendRecord = asRecord$3(rawSystemPrompt);
|
|
505
|
+
if (appendRecord && typeof appendRecord.append === "string" && appendRecord.append.length > 0) parsedSessionOptions.system_prompt = { append: appendRecord.append };
|
|
506
|
+
}
|
|
493
507
|
if (Object.keys(parsedSessionOptions).length > 0) state.session_options = parsedSessionOptions;
|
|
494
508
|
}
|
|
495
509
|
return state;
|
|
@@ -831,6 +845,58 @@ async function findSessionByDirectoryWalk(options) {
|
|
|
831
845
|
if (!isWithinBoundary(walkBoundary, current)) return;
|
|
832
846
|
}
|
|
833
847
|
}
|
|
848
|
+
function closedAtOrLastUsedAt(record) {
|
|
849
|
+
return record.closedAt ?? record.lastUsedAt;
|
|
850
|
+
}
|
|
851
|
+
function isSessionStreamFile(fileName, safeId) {
|
|
852
|
+
return fileName === `${safeId}.stream.ndjson` || fileName === `${safeId}.stream.lock` || fileName.startsWith(`${safeId}.stream.`);
|
|
853
|
+
}
|
|
854
|
+
async function pruneSessions(options = {}) {
|
|
855
|
+
await ensureSessionDir();
|
|
856
|
+
let eligible = (await loadSessionIndexEntries()).filter((entry) => entry.closed);
|
|
857
|
+
if (options.agentCommand) eligible = eligible.filter((entry) => entry.agentCommand === options.agentCommand);
|
|
858
|
+
const cutoff = options.before ?? (options.olderThanMs != null ? new Date(Date.now() - options.olderThanMs) : void 0);
|
|
859
|
+
const records = [];
|
|
860
|
+
for (const entry of eligible) {
|
|
861
|
+
const record = await loadRecordFromIndexEntry(entry);
|
|
862
|
+
if (record && (!cutoff || closedAtOrLastUsedAt(record) < cutoff.toISOString())) records.push(record);
|
|
863
|
+
}
|
|
864
|
+
if (options.dryRun) return {
|
|
865
|
+
pruned: records,
|
|
866
|
+
bytesFreed: 0,
|
|
867
|
+
dryRun: true
|
|
868
|
+
};
|
|
869
|
+
const sessionDir = sessionBaseDir();
|
|
870
|
+
let bytesFreed = 0;
|
|
871
|
+
let dirEntries = [];
|
|
872
|
+
if (options.includeHistory) try {
|
|
873
|
+
dirEntries = await fs$1.readdir(sessionDir);
|
|
874
|
+
} catch {}
|
|
875
|
+
for (const record of records) {
|
|
876
|
+
const safeId = encodeURIComponent(record.acpxRecordId);
|
|
877
|
+
const jsonFile = path.join(sessionDir, `${safeId}.json`);
|
|
878
|
+
try {
|
|
879
|
+
const stat = await fs$1.stat(jsonFile);
|
|
880
|
+
bytesFreed += stat.size;
|
|
881
|
+
} catch {}
|
|
882
|
+
await fs$1.unlink(jsonFile).catch(() => void 0);
|
|
883
|
+
if (options.includeHistory) for (const name of dirEntries) {
|
|
884
|
+
if (!isSessionStreamFile(name, safeId)) continue;
|
|
885
|
+
const filePath = path.join(sessionDir, name);
|
|
886
|
+
try {
|
|
887
|
+
const stat = await fs$1.stat(filePath);
|
|
888
|
+
bytesFreed += stat.size;
|
|
889
|
+
} catch {}
|
|
890
|
+
await fs$1.unlink(filePath).catch(() => void 0);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
await rebuildSessionIndex(sessionDir).catch(() => {});
|
|
894
|
+
return {
|
|
895
|
+
pruned: records,
|
|
896
|
+
bytesFreed,
|
|
897
|
+
dryRun: false
|
|
898
|
+
};
|
|
899
|
+
}
|
|
834
900
|
//#endregion
|
|
835
901
|
//#region src/permission-prompt.ts
|
|
836
902
|
async function promptForPermission(options) {
|
|
@@ -875,7 +941,7 @@ async function defaultConfirmWrite(filePath, preview) {
|
|
|
875
941
|
});
|
|
876
942
|
}
|
|
877
943
|
function canPromptForPermission$2() {
|
|
878
|
-
return
|
|
944
|
+
return process.stdin.isTTY && process.stderr.isTTY;
|
|
879
945
|
}
|
|
880
946
|
var FileSystemHandlers = class {
|
|
881
947
|
rootDir;
|
|
@@ -1039,7 +1105,7 @@ async function promptForToolPermission(params) {
|
|
|
1039
1105
|
return await promptForPermission({ prompt: `\n[permission] Allow ${params.toolCall.title ?? "tool"} [${inferToolKind(params) ?? "other"}]? (y/N) ` });
|
|
1040
1106
|
}
|
|
1041
1107
|
function canPromptForPermission$1() {
|
|
1042
|
-
return
|
|
1108
|
+
return process.stdin.isTTY && process.stderr.isTTY;
|
|
1043
1109
|
}
|
|
1044
1110
|
function permissionModeSatisfies(actual, required) {
|
|
1045
1111
|
return PERMISSION_MODE_RANK[actual] >= PERMISSION_MODE_RANK[required];
|
|
@@ -1112,6 +1178,7 @@ function buildSpawnCommandOptions(command, options, platform = process.platform,
|
|
|
1112
1178
|
}
|
|
1113
1179
|
//#endregion
|
|
1114
1180
|
//#region src/acp/client-process.ts
|
|
1181
|
+
const execFileAsync = promisify(execFile);
|
|
1115
1182
|
function isoNow$1() {
|
|
1116
1183
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
1117
1184
|
}
|
|
@@ -1203,6 +1270,34 @@ function splitCommandLine(value) {
|
|
|
1203
1270
|
function asAbsoluteCwd(cwd) {
|
|
1204
1271
|
return path.resolve(cwd);
|
|
1205
1272
|
}
|
|
1273
|
+
async function resolveAgentSessionCwd(cwd, agentCommand, options = {}) {
|
|
1274
|
+
const resolved = asAbsoluteCwd(cwd);
|
|
1275
|
+
if (!shouldTranslateWslWindowsCwd(agentCommand, options)) return resolved;
|
|
1276
|
+
const translated = (await (options.runWslpath ?? runWslpath)(resolved)).trim();
|
|
1277
|
+
if (!translated) throw new Error(`wslpath returned an empty Windows path for cwd: ${resolved}`);
|
|
1278
|
+
return translated;
|
|
1279
|
+
}
|
|
1280
|
+
function shouldTranslateWslWindowsCwd(agentCommand, options) {
|
|
1281
|
+
if (!isWsl(options)) return false;
|
|
1282
|
+
try {
|
|
1283
|
+
const { command } = splitCommandLine(agentCommand);
|
|
1284
|
+
return isWindowsExecutableCommand(command);
|
|
1285
|
+
} catch {
|
|
1286
|
+
return false;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
function isWsl(options) {
|
|
1290
|
+
if ((options.platform ?? process.platform) !== "linux") return false;
|
|
1291
|
+
return (options.existsSync ?? fs.existsSync)("/proc/sys/fs/binfmt_misc/WSLInterop");
|
|
1292
|
+
}
|
|
1293
|
+
function isWindowsExecutableCommand(command) {
|
|
1294
|
+
const normalized = command.replace(/\\/g, "/").toLowerCase();
|
|
1295
|
+
return normalized.endsWith(".exe") || normalized.startsWith("/mnt/c/");
|
|
1296
|
+
}
|
|
1297
|
+
async function runWslpath(cwd) {
|
|
1298
|
+
const { stdout } = await execFileAsync("wslpath", ["-w", cwd], { encoding: "utf8" });
|
|
1299
|
+
return stdout;
|
|
1300
|
+
}
|
|
1206
1301
|
function basenameToken(value) {
|
|
1207
1302
|
return path.basename(value).toLowerCase().replace(/\.(cmd|exe|bat)$/u, "");
|
|
1208
1303
|
}
|
|
@@ -1425,46 +1520,57 @@ function buildClaudeCodeOptionsMeta(options) {
|
|
|
1425
1520
|
if (typeof options.model === "string" && options.model.trim().length > 0) claudeCodeOptions.model = options.model;
|
|
1426
1521
|
if (Array.isArray(options.allowedTools)) claudeCodeOptions.allowedTools = [...options.allowedTools];
|
|
1427
1522
|
if (typeof options.maxTurns === "number") claudeCodeOptions.maxTurns = options.maxTurns;
|
|
1428
|
-
|
|
1429
|
-
|
|
1523
|
+
const meta = {};
|
|
1524
|
+
if (Object.keys(claudeCodeOptions).length > 0) meta.claudeCode = { options: claudeCodeOptions };
|
|
1525
|
+
const systemPrompt = options.systemPrompt;
|
|
1526
|
+
if (typeof systemPrompt === "string" && systemPrompt.length > 0) meta.systemPrompt = systemPrompt;
|
|
1527
|
+
else if (systemPrompt && typeof systemPrompt === "object" && typeof systemPrompt.append === "string" && systemPrompt.append.length > 0) meta.systemPrompt = { append: systemPrompt.append };
|
|
1528
|
+
if (Object.keys(meta).length === 0) return;
|
|
1529
|
+
return meta;
|
|
1430
1530
|
}
|
|
1431
1531
|
//#endregion
|
|
1432
1532
|
//#region src/acp/auth-env.ts
|
|
1533
|
+
const AUTH_ENV_PREFIX = "ACPX_AUTH_";
|
|
1433
1534
|
function toEnvToken(value) {
|
|
1434
1535
|
return value.trim().replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
|
|
1435
1536
|
}
|
|
1436
|
-
function
|
|
1537
|
+
function buildAuthEnvKey(methodId) {
|
|
1437
1538
|
const token = toEnvToken(methodId);
|
|
1438
|
-
|
|
1439
|
-
if (token) {
|
|
1440
|
-
keys.add(token);
|
|
1441
|
-
keys.add(`ACPX_AUTH_${token}`);
|
|
1442
|
-
}
|
|
1443
|
-
return [...keys];
|
|
1539
|
+
return token.length > 0 ? `${AUTH_ENV_PREFIX}${token}` : void 0;
|
|
1444
1540
|
}
|
|
1445
|
-
const
|
|
1446
|
-
function
|
|
1447
|
-
const cached =
|
|
1448
|
-
if (cached) return cached;
|
|
1449
|
-
const
|
|
1450
|
-
|
|
1451
|
-
return
|
|
1541
|
+
const authEnvKeyCache = /* @__PURE__ */ new Map();
|
|
1542
|
+
function authEnvKey(methodId) {
|
|
1543
|
+
const cached = authEnvKeyCache.get(methodId);
|
|
1544
|
+
if (cached !== void 0) return cached;
|
|
1545
|
+
const key = buildAuthEnvKey(methodId);
|
|
1546
|
+
authEnvKeyCache.set(methodId, key);
|
|
1547
|
+
return key;
|
|
1452
1548
|
}
|
|
1453
1549
|
function readEnvCredential(methodId) {
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1550
|
+
const key = authEnvKey(methodId);
|
|
1551
|
+
if (!key) return;
|
|
1552
|
+
const value = process.env[key];
|
|
1553
|
+
if (typeof value === "string" && value.trim().length > 0) return value;
|
|
1554
|
+
}
|
|
1555
|
+
function promotePrefixedAuthEnvironment(env) {
|
|
1556
|
+
for (const [key, value] of Object.entries(env)) {
|
|
1557
|
+
if (!key.startsWith(AUTH_ENV_PREFIX)) continue;
|
|
1558
|
+
if (typeof value !== "string" || value.trim().length === 0) continue;
|
|
1559
|
+
const normalized = key.slice(10);
|
|
1560
|
+
if (!normalized || env[normalized] != null) continue;
|
|
1561
|
+
env[normalized] = value;
|
|
1457
1562
|
}
|
|
1458
1563
|
}
|
|
1459
1564
|
function buildAgentEnvironment(authCredentials) {
|
|
1460
1565
|
const env = { ...process.env };
|
|
1566
|
+
promotePrefixedAuthEnvironment(env);
|
|
1461
1567
|
if (!authCredentials) return env;
|
|
1462
1568
|
for (const [methodId, credential] of Object.entries(authCredentials)) {
|
|
1463
1569
|
if (typeof credential !== "string" || credential.trim().length === 0) continue;
|
|
1464
1570
|
if (!methodId.includes("=") && !methodId.includes("\0") && env[methodId] == null) env[methodId] = credential;
|
|
1465
1571
|
const normalized = toEnvToken(methodId);
|
|
1466
1572
|
if (normalized) {
|
|
1467
|
-
const prefixed =
|
|
1573
|
+
const prefixed = `${AUTH_ENV_PREFIX}${normalized}`;
|
|
1468
1574
|
if (env[prefixed] == null) env[prefixed] = credential;
|
|
1469
1575
|
if (env[normalized] == null) env[normalized] = credential;
|
|
1470
1576
|
}
|
|
@@ -1570,7 +1676,7 @@ async function defaultConfirmExecute(commandLine) {
|
|
|
1570
1676
|
return await promptForPermission({ prompt: `\n[permission] Allow terminal command "${commandLine}"? (y/N) ` });
|
|
1571
1677
|
}
|
|
1572
1678
|
function canPromptForPermission() {
|
|
1573
|
-
return
|
|
1679
|
+
return process.stdin.isTTY && process.stderr.isTTY;
|
|
1574
1680
|
}
|
|
1575
1681
|
function waitMs(ms) {
|
|
1576
1682
|
return new Promise((resolve) => {
|
|
@@ -1966,6 +2072,7 @@ var AcpClient = class {
|
|
|
1966
2072
|
updateRuntimeOptions(options) {
|
|
1967
2073
|
if (options.permissionMode) this.options.permissionMode = options.permissionMode;
|
|
1968
2074
|
if (options.nonInteractivePermissions !== void 0) this.options.nonInteractivePermissions = options.nonInteractivePermissions;
|
|
2075
|
+
if (options.terminal !== void 0) this.options.terminal = options.terminal;
|
|
1969
2076
|
if (options.permissionMode || options.nonInteractivePermissions !== void 0) {
|
|
1970
2077
|
this.filesystem.updatePermissionPolicy(this.options.permissionMode, this.options.nonInteractivePermissions);
|
|
1971
2078
|
this.terminalManager.updatePermissionPolicy(this.options.permissionMode, this.options.nonInteractivePermissions);
|
|
@@ -2057,7 +2164,7 @@ var AcpClient = class {
|
|
|
2057
2164
|
readTextFile: true,
|
|
2058
2165
|
writeTextFile: true
|
|
2059
2166
|
},
|
|
2060
|
-
terminal:
|
|
2167
|
+
terminal: this.options.terminal !== false
|
|
2061
2168
|
},
|
|
2062
2169
|
clientInfo: {
|
|
2063
2170
|
name: "acpx",
|
|
@@ -2075,6 +2182,7 @@ var AcpClient = class {
|
|
|
2075
2182
|
this.log(`initialized protocol version ${initResult.protocolVersion}`);
|
|
2076
2183
|
} catch (error) {
|
|
2077
2184
|
startupFailure.dispose();
|
|
2185
|
+
const normalizedError = await this.normalizeInitializeError(error, child, startupStderr);
|
|
2078
2186
|
try {
|
|
2079
2187
|
child.kill();
|
|
2080
2188
|
} catch {}
|
|
@@ -2082,7 +2190,7 @@ var AcpClient = class {
|
|
|
2082
2190
|
cause: error,
|
|
2083
2191
|
retryable: true
|
|
2084
2192
|
});
|
|
2085
|
-
throw
|
|
2193
|
+
throw normalizedError;
|
|
2086
2194
|
}
|
|
2087
2195
|
}
|
|
2088
2196
|
createTappedStream(base) {
|
|
@@ -2126,10 +2234,11 @@ var AcpClient = class {
|
|
|
2126
2234
|
const connection = this.getConnection();
|
|
2127
2235
|
const { command, args } = splitCommandLine(this.options.agentCommand);
|
|
2128
2236
|
const claudeAcp = isClaudeAcpCommand(command, args);
|
|
2237
|
+
const sessionCwd = await resolveAgentSessionCwd(cwd, this.options.agentCommand);
|
|
2129
2238
|
let result;
|
|
2130
2239
|
try {
|
|
2131
2240
|
const createPromise = this.runConnectionRequest(() => connection.newSession({
|
|
2132
|
-
cwd:
|
|
2241
|
+
cwd: sessionCwd,
|
|
2133
2242
|
mcpServers: this.options.mcpServers ?? [],
|
|
2134
2243
|
_meta: buildClaudeCodeOptionsMeta(this.options.sessionOptions)
|
|
2135
2244
|
}));
|
|
@@ -2154,6 +2263,7 @@ var AcpClient = class {
|
|
|
2154
2263
|
}
|
|
2155
2264
|
async loadSessionWithOptions(sessionId, cwd = this.options.cwd, options = {}) {
|
|
2156
2265
|
const connection = this.getConnection();
|
|
2266
|
+
const sessionCwd = await resolveAgentSessionCwd(cwd, this.options.agentCommand);
|
|
2157
2267
|
const previousSuppression = this.suppressSessionUpdates;
|
|
2158
2268
|
const previousReplaySuppression = this.suppressReplaySessionUpdateMessages;
|
|
2159
2269
|
this.suppressSessionUpdates = previousSuppression || Boolean(options.suppressReplayUpdates);
|
|
@@ -2162,7 +2272,7 @@ var AcpClient = class {
|
|
|
2162
2272
|
try {
|
|
2163
2273
|
response = await this.runConnectionRequest(() => connection.loadSession({
|
|
2164
2274
|
sessionId,
|
|
2165
|
-
cwd:
|
|
2275
|
+
cwd: sessionCwd,
|
|
2166
2276
|
mcpServers: this.options.mcpServers ?? []
|
|
2167
2277
|
}));
|
|
2168
2278
|
await this.waitForSessionUpdateDrain(options.replayIdleMs ?? REPLAY_IDLE_MS, options.replayDrainTimeoutMs ?? REPLAY_DRAIN_TIMEOUT_MS);
|
|
@@ -2255,7 +2365,7 @@ var AcpClient = class {
|
|
|
2255
2365
|
}
|
|
2256
2366
|
async closeSession(sessionId) {
|
|
2257
2367
|
const connection = this.getConnection();
|
|
2258
|
-
await this.runConnectionRequest(() => connection.
|
|
2368
|
+
await this.runConnectionRequest(() => connection.unstable_closeNes({ sessionId }));
|
|
2259
2369
|
if (this.loadedSessionId === sessionId) this.loadedSessionId = void 0;
|
|
2260
2370
|
}
|
|
2261
2371
|
async requestCancelActivePrompt() {
|
|
@@ -2402,6 +2512,20 @@ var AcpClient = class {
|
|
|
2402
2512
|
dispose: () => finish()
|
|
2403
2513
|
};
|
|
2404
2514
|
}
|
|
2515
|
+
async normalizeInitializeError(error, child, startupStderr) {
|
|
2516
|
+
if (error instanceof AgentStartupError) return error;
|
|
2517
|
+
const connectionClosedDuringInitialize = error instanceof Error && /acp connection closed/i.test(error.message);
|
|
2518
|
+
await waitForChildExit(child, 100);
|
|
2519
|
+
const childExited = child.exitCode !== null || child.signalCode !== null;
|
|
2520
|
+
if (!connectionClosedDuringInitialize && !childExited) return error;
|
|
2521
|
+
return new AgentStartupError({
|
|
2522
|
+
agentCommand: this.options.agentCommand,
|
|
2523
|
+
exitCode: child.exitCode ?? null,
|
|
2524
|
+
signal: child.signalCode ?? null,
|
|
2525
|
+
stderrSummary: this.summarizeStartupStderr(startupStderr),
|
|
2526
|
+
cause: error
|
|
2527
|
+
});
|
|
2528
|
+
}
|
|
2405
2529
|
selectAuthMethod(methods) {
|
|
2406
2530
|
for (const method of methods) {
|
|
2407
2531
|
const envCredential = readEnvCredential(method.id);
|
|
@@ -2851,6 +2975,7 @@ function cloneSessionAcpxState(state) {
|
|
|
2851
2975
|
return {
|
|
2852
2976
|
current_mode_id: state.current_mode_id,
|
|
2853
2977
|
desired_mode_id: state.desired_mode_id,
|
|
2978
|
+
desired_config_options: state.desired_config_options ? { ...state.desired_config_options } : void 0,
|
|
2854
2979
|
current_model_id: state.current_model_id,
|
|
2855
2980
|
available_models: state.available_models ? [...state.available_models] : void 0,
|
|
2856
2981
|
available_commands: state.available_commands ? [...state.available_commands] : void 0,
|
|
@@ -2858,7 +2983,8 @@ function cloneSessionAcpxState(state) {
|
|
|
2858
2983
|
session_options: state.session_options ? {
|
|
2859
2984
|
model: state.session_options.model,
|
|
2860
2985
|
allowed_tools: state.session_options.allowed_tools ? [...state.session_options.allowed_tools] : void 0,
|
|
2861
|
-
max_turns: state.session_options.max_turns
|
|
2986
|
+
max_turns: state.session_options.max_turns,
|
|
2987
|
+
...state.session_options.system_prompt !== void 0 ? { system_prompt: typeof state.session_options.system_prompt === "string" ? state.session_options.system_prompt : { append: state.session_options.system_prompt.append } } : {}
|
|
2862
2988
|
} : void 0
|
|
2863
2989
|
};
|
|
2864
2990
|
}
|
|
@@ -2990,6 +3116,14 @@ function normalizeModelId(modelId) {
|
|
|
2990
3116
|
function getDesiredModeId(state) {
|
|
2991
3117
|
return normalizeModeId(state?.desired_mode_id);
|
|
2992
3118
|
}
|
|
3119
|
+
function getDesiredConfigOptions(state) {
|
|
3120
|
+
const desired = state?.desired_config_options;
|
|
3121
|
+
if (!desired) return {};
|
|
3122
|
+
return Object.fromEntries(Object.entries(desired).flatMap(([configId, value]) => {
|
|
3123
|
+
const normalizedConfigId = normalizeModeId(configId);
|
|
3124
|
+
return normalizedConfigId && typeof value === "string" ? [[normalizedConfigId, value]] : [];
|
|
3125
|
+
}));
|
|
3126
|
+
}
|
|
2993
3127
|
function setDesiredModeId(record, modeId) {
|
|
2994
3128
|
const acpx = ensureAcpxState(record.acpx);
|
|
2995
3129
|
const normalized = normalizeModeId(modeId);
|
|
@@ -2997,6 +3131,17 @@ function setDesiredModeId(record, modeId) {
|
|
|
2997
3131
|
else delete acpx.desired_mode_id;
|
|
2998
3132
|
record.acpx = acpx;
|
|
2999
3133
|
}
|
|
3134
|
+
function setDesiredConfigOption(record, configId, value) {
|
|
3135
|
+
const normalizedConfigId = normalizeModeId(configId);
|
|
3136
|
+
if (!normalizedConfigId || normalizedConfigId === "mode" || normalizedConfigId === "model") return;
|
|
3137
|
+
const acpx = ensureAcpxState(record.acpx);
|
|
3138
|
+
const desired = { ...acpx.desired_config_options };
|
|
3139
|
+
if (typeof value === "string") desired[normalizedConfigId] = value;
|
|
3140
|
+
else delete desired[normalizedConfigId];
|
|
3141
|
+
if (Object.keys(desired).length > 0) acpx.desired_config_options = desired;
|
|
3142
|
+
else delete acpx.desired_config_options;
|
|
3143
|
+
record.acpx = acpx;
|
|
3144
|
+
}
|
|
3000
3145
|
function getDesiredModelId(state) {
|
|
3001
3146
|
return normalizeModelId(state?.session_options?.model);
|
|
3002
3147
|
}
|
|
@@ -3006,7 +3151,7 @@ function setDesiredModelId(record, modelId) {
|
|
|
3006
3151
|
const sessionOptions = { ...acpx.session_options };
|
|
3007
3152
|
if (normalized) sessionOptions.model = normalized;
|
|
3008
3153
|
else delete sessionOptions.model;
|
|
3009
|
-
if (typeof sessionOptions.model === "string" || Array.isArray(sessionOptions.allowed_tools) || typeof sessionOptions.max_turns === "number") acpx.session_options = sessionOptions;
|
|
3154
|
+
if (typeof sessionOptions.model === "string" || Array.isArray(sessionOptions.allowed_tools) || typeof sessionOptions.max_turns === "number" || sessionOptions.system_prompt !== void 0) acpx.session_options = sessionOptions;
|
|
3010
3155
|
else delete acpx.session_options;
|
|
3011
3156
|
record.acpx = acpx;
|
|
3012
3157
|
}
|
|
@@ -3111,6 +3256,17 @@ async function replayDesiredModel(params) {
|
|
|
3111
3256
|
});
|
|
3112
3257
|
}
|
|
3113
3258
|
}
|
|
3259
|
+
async function replayDesiredConfigOptions(params) {
|
|
3260
|
+
for (const [configId, value] of Object.entries(params.desiredConfigOptions)) try {
|
|
3261
|
+
await withTimeout(params.client.setSessionConfigOption(params.sessionId, configId, value), params.timeoutMs);
|
|
3262
|
+
if (params.verbose) process.stderr.write(`[acpx] replayed desired config option ${configId} on fresh ACP session ${params.sessionId} (previous ${params.previousSessionId})\n`);
|
|
3263
|
+
} catch (error) {
|
|
3264
|
+
throw new SessionConfigOptionReplayError(`Failed to replay saved session config option ${configId} on fresh ACP session ${params.sessionId}: ${formatErrorMessage(error)}`, {
|
|
3265
|
+
cause: error instanceof Error ? error : void 0,
|
|
3266
|
+
retryable: true
|
|
3267
|
+
});
|
|
3268
|
+
}
|
|
3269
|
+
}
|
|
3114
3270
|
function restoreOriginalSessionState(params) {
|
|
3115
3271
|
params.record.acpSessionId = params.sessionId;
|
|
3116
3272
|
params.record.agentSessionId = params.agentSessionId;
|
|
@@ -3123,6 +3279,7 @@ async function connectAndLoadSession(options) {
|
|
|
3123
3279
|
const originalAgentSessionId = record.agentSessionId;
|
|
3124
3280
|
const desiredModeId = getDesiredModeId(record.acpx);
|
|
3125
3281
|
const desiredModelId = getDesiredModelId(record.acpx);
|
|
3282
|
+
const desiredConfigOptions = getDesiredConfigOptions(record.acpx);
|
|
3126
3283
|
const storedProcessAlive = isProcessAlive(record.pid);
|
|
3127
3284
|
const shouldReconnect = Boolean(record.pid) && !storedProcessAlive;
|
|
3128
3285
|
if (options.verbose) {
|
|
@@ -3193,6 +3350,14 @@ async function connectAndLoadSession(options) {
|
|
|
3193
3350
|
timeoutMs: options.timeoutMs,
|
|
3194
3351
|
verbose: options.verbose
|
|
3195
3352
|
});
|
|
3353
|
+
await replayDesiredConfigOptions({
|
|
3354
|
+
client,
|
|
3355
|
+
sessionId,
|
|
3356
|
+
desiredConfigOptions,
|
|
3357
|
+
previousSessionId: originalSessionId,
|
|
3358
|
+
timeoutMs: options.timeoutMs,
|
|
3359
|
+
verbose: options.verbose
|
|
3360
|
+
});
|
|
3196
3361
|
} catch (error) {
|
|
3197
3362
|
restoreOriginalSessionState({
|
|
3198
3363
|
record,
|
|
@@ -3217,6 +3382,14 @@ async function connectAndLoadSession(options) {
|
|
|
3217
3382
|
}
|
|
3218
3383
|
//#endregion
|
|
3219
3384
|
//#region src/runtime/engine/session-options.ts
|
|
3385
|
+
function mergeSessionOptions(preferred, fallback) {
|
|
3386
|
+
const merged = { ...fallback };
|
|
3387
|
+
if (preferred?.model !== void 0) merged.model = preferred.model;
|
|
3388
|
+
if (preferred?.allowedTools !== void 0) merged.allowedTools = preferred.allowedTools;
|
|
3389
|
+
if (preferred?.maxTurns !== void 0) merged.maxTurns = preferred.maxTurns;
|
|
3390
|
+
if (preferred?.systemPrompt !== void 0) merged.systemPrompt = preferred.systemPrompt;
|
|
3391
|
+
return Object.keys(merged).length > 0 ? merged : void 0;
|
|
3392
|
+
}
|
|
3220
3393
|
function sessionOptionsFromRecord(record) {
|
|
3221
3394
|
const stored = record.acpx?.session_options;
|
|
3222
3395
|
if (!stored) return;
|
|
@@ -3224,6 +3397,9 @@ function sessionOptionsFromRecord(record) {
|
|
|
3224
3397
|
if (typeof stored.model === "string" && stored.model.trim().length > 0) sessionOptions.model = stored.model;
|
|
3225
3398
|
if (Array.isArray(stored.allowed_tools)) sessionOptions.allowedTools = [...stored.allowed_tools];
|
|
3226
3399
|
if (typeof stored.max_turns === "number") sessionOptions.maxTurns = stored.max_turns;
|
|
3400
|
+
const storedSystemPrompt = stored.system_prompt;
|
|
3401
|
+
if (typeof storedSystemPrompt === "string" && storedSystemPrompt.length > 0) sessionOptions.systemPrompt = storedSystemPrompt;
|
|
3402
|
+
else if (storedSystemPrompt && typeof storedSystemPrompt === "object" && typeof storedSystemPrompt.append === "string" && storedSystemPrompt.append.length > 0) sessionOptions.systemPrompt = { append: storedSystemPrompt.append };
|
|
3227
3403
|
return Object.keys(sessionOptions).length > 0 ? sessionOptions : void 0;
|
|
3228
3404
|
}
|
|
3229
3405
|
//#endregion
|
|
@@ -3254,6 +3430,7 @@ async function withConnectedSession(options) {
|
|
|
3254
3430
|
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
3255
3431
|
authCredentials: options.authCredentials,
|
|
3256
3432
|
authPolicy: options.authPolicy,
|
|
3433
|
+
terminal: options.terminal,
|
|
3257
3434
|
verbose: options.verbose,
|
|
3258
3435
|
sessionOptions: sessionOptionsFromRecord(record)
|
|
3259
3436
|
}) ?? new AcpClient({
|
|
@@ -3264,6 +3441,7 @@ async function withConnectedSession(options) {
|
|
|
3264
3441
|
nonInteractivePermissions: options.nonInteractivePermissions,
|
|
3265
3442
|
authCredentials: options.authCredentials,
|
|
3266
3443
|
authPolicy: options.authPolicy,
|
|
3444
|
+
terminal: options.terminal,
|
|
3267
3445
|
verbose: options.verbose,
|
|
3268
3446
|
sessionOptions: sessionOptionsFromRecord(record)
|
|
3269
3447
|
});
|
|
@@ -3338,8 +3516,13 @@ async function runPromptTurn(params) {
|
|
|
3338
3516
|
try {
|
|
3339
3517
|
const promptPromise = params.client.prompt(params.sessionId, params.prompt);
|
|
3340
3518
|
await params.onPromptStarted?.();
|
|
3519
|
+
const response = await withTimeout(promptPromise, params.timeoutMs);
|
|
3520
|
+
await params.client.waitForSessionUpdatesIdle?.({
|
|
3521
|
+
idleMs: SESSION_REPLY_IDLE_MS,
|
|
3522
|
+
timeoutMs: SESSION_REPLY_DRAIN_TIMEOUT_MS
|
|
3523
|
+
}).catch(() => {});
|
|
3341
3524
|
return {
|
|
3342
|
-
stopReason:
|
|
3525
|
+
stopReason: response.stopReason,
|
|
3343
3526
|
source: "rpc"
|
|
3344
3527
|
};
|
|
3345
3528
|
} catch (error) {
|
|
@@ -3356,6 +3539,6 @@ async function runPromptTurn(params) {
|
|
|
3356
3539
|
}
|
|
3357
3540
|
}
|
|
3358
3541
|
//#endregion
|
|
3359
|
-
export {
|
|
3542
|
+
export { listSessionsForAgent as A, sessionEventLockPath as B, DEFAULT_HISTORY_LIMIT as C, findSessionByDirectoryWalk as D, findSession as E, parseSessionRecord as F, TimeoutError as G, assertPersistedKeyPolicy as H, DEFAULT_EVENT_SEGMENT_MAX_BYTES as I, DEFAULT_AGENT_NAME as J, withInterrupt as K, defaultSessionEventLog as L, pruneSessions as M, resolveSessionRecord as N, isoNow$2 as O, writeSessionRecord as P, sessionBaseDir$1 as R, permissionModeSatisfies as S, findGitRepositoryRoot as T, serializeSessionRecordForDisk as U, sessionEventSegmentPath as V, InterruptedError as W, normalizeAgentName$1 as X, listBuiltInAgents as Y, resolveAgentCommand as Z, recordClientOperation as _, connectAndLoadSession as a, trimConversationForRuntime as b, reconcileAgentSessionId as c, setDesiredModeId as d, setDesiredModelId as f, createSessionConversation as g, cloneSessionConversation as h, sessionOptionsFromRecord as i, normalizeName as j, listSessions as k, setCurrentModelId as l, cloneSessionAcpxState as m, withConnectedSession as n, applyConversation as o, syncAdvertisedModelState as p, withTimeout as q, mergeSessionOptions as r, applyLifecycleSnapshotToRecord as s, runPromptTurn as t, setDesiredConfigOption as u, recordPromptSubmission as v, absolutePath as w, AcpClient as x, recordSessionUpdate as y, sessionEventActivePath as z };
|
|
3360
3543
|
|
|
3361
|
-
//# sourceMappingURL=prompt-turn-
|
|
3544
|
+
//# sourceMappingURL=prompt-turn-BOoZaDEq.js.map
|