acpx 0.8.0 → 0.9.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.
Files changed (34) hide show
  1. package/README.md +7 -4
  2. package/dist/{cli-BGYGVo3b.js → cli-Bf3yjqzE.js} +4 -4
  3. package/dist/{cli-BGYGVo3b.js.map → cli-Bf3yjqzE.js.map} +1 -1
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +545 -247
  7. package/dist/cli.js.map +1 -1
  8. package/dist/{client-FzXPdgP7.d.ts → client-BssohYqM.d.ts} +30 -3
  9. package/dist/client-BssohYqM.d.ts.map +1 -0
  10. package/dist/{flags-D706STfk.js → flags-C-rwARqg.js} +96 -39
  11. package/dist/flags-C-rwARqg.js.map +1 -0
  12. package/dist/{flows-hcjHmU7P.js → flows-WLs26_5Y.js} +400 -335
  13. package/dist/flows-WLs26_5Y.js.map +1 -0
  14. package/dist/flows.d.ts +21 -1
  15. package/dist/flows.d.ts.map +1 -1
  16. package/dist/flows.js +1 -1
  17. package/dist/{live-checkpoint-B9ctAuqV.js → live-checkpoint-D5d-K9s1.js} +1355 -700
  18. package/dist/live-checkpoint-D5d-K9s1.js.map +1 -0
  19. package/dist/{output-BL9XRWzS.js → output-DPg20dvn.js} +1151 -717
  20. package/dist/output-DPg20dvn.js.map +1 -0
  21. package/dist/runtime.d.ts +30 -2
  22. package/dist/runtime.d.ts.map +1 -1
  23. package/dist/runtime.js +579 -425
  24. package/dist/runtime.js.map +1 -1
  25. package/dist/{session-options-BJyG6zEH.d.ts → session-options-CFudjdkU.d.ts} +7 -1
  26. package/dist/session-options-CFudjdkU.d.ts.map +1 -0
  27. package/package.json +15 -12
  28. package/skills/acpx/SKILL.md +11 -3
  29. package/dist/client-FzXPdgP7.d.ts.map +0 -1
  30. package/dist/flags-D706STfk.js.map +0 -1
  31. package/dist/flows-hcjHmU7P.js.map +0 -1
  32. package/dist/live-checkpoint-B9ctAuqV.js.map +0 -1
  33. package/dist/output-BL9XRWzS.js.map +0 -1
  34. package/dist/session-options-BJyG6zEH.d.ts.map +0 -1
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { a as runSessionQueueOwner, c as buildQueueOwnerArgOverride, h as __exportAll, l as flushPerfMetricsCapture, n as getTextErrorRemediationHints, p as probeQueueOwnerHealth, t as createOutputFormatter, u as installPerfMetricsCapture } from "./output-BL9XRWzS.js";
3
- import { At as EXIT_CODES, F as findSession, I as findSessionByDirectoryWalk, P as findGitRepositoryRoot, Pt as OUTPUT_FORMATS, St as exitCodeForOutputErrorCode, Tt as normalizeOutputError, bt as normalizeAgentName, ct as PromptInputValidationError, dt as parsePromptSource, mt as InterruptedError, pt as textPrompt, st as normalizeRuntimeSessionId, ut as mergePromptSourceWithText, vt as DEFAULT_AGENT_NAME, yt as listBuiltInAgents } from "./live-checkpoint-B9ctAuqV.js";
4
- import { _ as resolveOutputPolicy, b as loadPermissionPolicySpec, c as parseHistoryLimit, d as parseOutputFormat$1, f as parsePruneBeforeDate, g as resolveGlobalFlags, h as resolveAgentInvocation, i as addSessionOption, l as parseMaxTurns, m as parseTtlSeconds, n as addPromptInputOption, o as parseAllowedTools, p as parseSessionName, r as addSessionNameOption, s as parseDaysOlderThan, t as addGlobalFlags, u as parseNonEmptyValue, v as resolvePermissionMode, y as resolveSessionNameFromFlags } from "./flags-D706STfk.js";
2
+ import { a as runSessionQueueOwner, c as buildQueueOwnerArgOverride, h as __exportAll, l as flushPerfMetricsCapture, n as getTextErrorRemediationHints, p as probeQueueOwnerHealth, t as createOutputFormatter, u as installPerfMetricsCapture } from "./output-DPg20dvn.js";
3
+ import { At as EXIT_CODES, F as findSession, I as findSessionByDirectoryWalk, P as findGitRepositoryRoot, Pt as OUTPUT_FORMATS, Rt as AgentSpawnError, St as exitCodeForOutputErrorCode, Tt as normalizeOutputError, bt as normalizeAgentName, ct as PromptInputValidationError, dt as parsePromptSource, mt as InterruptedError, pt as textPrompt, st as normalizeRuntimeSessionId, ut as mergePromptSourceWithText, vt as DEFAULT_AGENT_NAME, yt as listBuiltInAgents } from "./live-checkpoint-D5d-K9s1.js";
4
+ import { _ as resolveOutputPolicy, b as loadPermissionPolicySpec, c as parseHistoryLimit, d as parseOutputFormat$1, f as parsePruneBeforeDate, g as resolveGlobalFlags, h as resolveAgentInvocation, i as addSessionOption, l as parseMaxTurns, m as parseTtlSeconds, n as addPromptInputOption, o as parseAllowedTools, p as parseSessionName, r as addSessionNameOption, s as parseDaysOlderThan, t as addGlobalFlags, u as parseNonEmptyValue, v as resolvePermissionMode, y as resolveSessionNameFromFlags } from "./flags-C-rwARqg.js";
5
5
  import { readFileSync, realpathSync } from "node:fs";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import path from "node:path";
@@ -34,7 +34,7 @@ Examples:
34
34
  acpx codex exec "what does this repo do"
35
35
  acpx codex cancel
36
36
  acpx codex set-mode plan
37
- acpx codex set thought_level high
37
+ acpx codex set model 'gpt-5.2[high]'
38
38
  acpx codex -s backend "fix the API"
39
39
  acpx codex sessions
40
40
  acpx codex sessions new --name backend
@@ -49,9 +49,8 @@ Examples:
49
49
  }
50
50
  //#endregion
51
51
  //#region src/acp/codex-compat.ts
52
- function isCodexInvocation(agentName, agentCommand) {
53
- if (agentName === "codex") return true;
54
- return /\bcodex-acp\b/u.test(agentCommand);
52
+ function isLegacyZedCodexAcpInvocation(agentCommand) {
53
+ return /@zed-industries\/codex-acp\b/u.test(agentCommand);
55
54
  }
56
55
  //#endregion
57
56
  //#region src/cli/output/json-output.ts
@@ -72,11 +71,11 @@ let sessionModulePromise;
72
71
  let outputModulePromise;
73
72
  let outputRenderModulePromise;
74
73
  function loadSessionModule() {
75
- sessionModulePromise ??= import("./output-BL9XRWzS.js").then((n) => n.i);
74
+ sessionModulePromise ??= import("./output-DPg20dvn.js").then((n) => n.i);
76
75
  return sessionModulePromise;
77
76
  }
78
77
  function loadOutputModule() {
79
- outputModulePromise ??= import("./output-BL9XRWzS.js").then((n) => n.r);
78
+ outputModulePromise ??= import("./output-DPg20dvn.js").then((n) => n.r);
80
79
  return outputModulePromise;
81
80
  }
82
81
  function loadOutputRenderModule() {
@@ -90,11 +89,7 @@ async function readPromptInputFromStdin() {
90
89
  }
91
90
  async function readPrompt(promptParts, filePath, cwd) {
92
91
  try {
93
- if (filePath) {
94
- const prompt = mergePromptSourceWithText(filePath === "-" ? await readPromptInputFromStdin() : await fs$1.readFile(path.resolve(cwd, filePath), "utf8"), promptParts.join(" "));
95
- if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
96
- return prompt;
97
- }
92
+ if (filePath) return await readPromptFromFile(filePath, cwd, promptParts);
98
93
  const joined = promptParts.join(" ").trim();
99
94
  if (joined.length > 0) return textPrompt(joined);
100
95
  if (process.stdin.isTTY) throw new InvalidArgumentError("Prompt is required (pass as argument, --file, or pipe via stdin)");
@@ -106,13 +101,18 @@ async function readPrompt(promptParts, filePath, cwd) {
106
101
  throw error;
107
102
  }
108
103
  }
104
+ async function readPromptFromFile(filePath, cwd, promptParts) {
105
+ const prompt = mergePromptSourceWithText(filePath === "-" ? await readPromptInputFromStdin() : await fs$1.readFile(path.resolve(cwd, filePath), "utf8"), promptParts.join(" "));
106
+ if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
107
+ return prompt;
108
+ }
109
109
  function applyPermissionExitCode(result) {
110
110
  const stats = result.permissionStats;
111
111
  const deniedOrCancelled = stats.denied + stats.cancelled;
112
112
  if (stats.requested > 0 && stats.approved === 0 && deniedOrCancelled > 0) process.exitCode = EXIT_CODES.PERMISSION_DENIED;
113
113
  }
114
114
  function resolveCompatibleConfigId(agent, configId) {
115
- if (isCodexInvocation(agent.agentName, agent.agentCommand) && configId === "thought_level") return "reasoning_effort";
115
+ if (isLegacyZedCodexAcpInvocation(agent.agentCommand) && configId === "thought_level") return "reasoning_effort";
116
116
  return configId;
117
117
  }
118
118
  function resolveRequestedOutputPolicy(globalFlags) {
@@ -154,6 +154,14 @@ function buildSessionStartOptions(params) {
154
154
  sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags)
155
155
  };
156
156
  }
157
+ function resolveSessionListFilterCwd(flags, agentCwd) {
158
+ return flags.filterCwd ? path.resolve(agentCwd, flags.filterCwd) : void 0;
159
+ }
160
+ async function printLocalSessionsList(agentCommand, filterCwd, format) {
161
+ const [{ listSessionsForAgent }, { printSessionsByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
162
+ const sessions = await listSessionsForAgent(agentCommand);
163
+ printSessionsByFormat(filterCwd ? sessions.filter((session) => session.cwd === filterCwd) : sessions, format);
164
+ }
157
165
  function missingScopedSessionMessage(agent, sessionName) {
158
166
  return sessionName ? `No named session "${sessionName}" for cwd ${agent.cwd} and agent ${agent.agentName}` : `No cwd session for ${agent.cwd} and agent ${agent.agentName}`;
159
167
  }
@@ -227,7 +235,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
227
235
  return;
228
236
  }
229
237
  applyPermissionExitCode(result);
230
- if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] loadSession failed, started fresh session: ${result.loadError}\n`);
238
+ if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] session reconnect failed, started fresh session: ${result.loadError}\n`);
231
239
  }
232
240
  async function handleExec(explicitAgentName, promptParts, flags, command, config) {
233
241
  if (config.disableExec) {
@@ -356,7 +364,7 @@ async function handleSetMode(explicitAgentName, modeId, flags, command, config)
356
364
  timeoutMs: globalFlags.timeout,
357
365
  verbose: globalFlags.verbose
358
366
  });
359
- if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] loadSession failed, started fresh session: ${result.loadError}\n`);
367
+ if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] session reconnect failed, started fresh session: ${result.loadError}\n`);
360
368
  printSetModeResultByFormat(modeId, result, globalFlags.format);
361
369
  }
362
370
  async function handleSetModel(explicitAgentName, modelId, flags, command, config) {
@@ -374,7 +382,7 @@ async function handleSetModel(explicitAgentName, modelId, flags, command, config
374
382
  timeoutMs: globalFlags.timeout,
375
383
  verbose: globalFlags.verbose
376
384
  });
377
- if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] loadSession failed, started fresh session: ${result.loadError}\n`);
385
+ if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] session reconnect failed, started fresh session: ${result.loadError}\n`);
378
386
  printSetModelResultByFormat(modelId, result, globalFlags.format);
379
387
  }
380
388
  async function handleSetConfigOption(explicitAgentName, configId, value, flags, command, config) {
@@ -398,14 +406,50 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
398
406
  timeoutMs: globalFlags.timeout,
399
407
  verbose: globalFlags.verbose
400
408
  });
401
- if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] loadSession failed, started fresh session: ${result.loadError}\n`);
409
+ if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] session reconnect failed, started fresh session: ${result.loadError}\n`);
402
410
  printSetConfigOptionResultByFormat(configId, value, result, globalFlags.format);
403
411
  }
404
- async function handleSessionsList(explicitAgentName, command, config) {
412
+ async function tryListAgentSessions(agent, flags, globalFlags, config) {
413
+ const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
414
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
415
+ const { listAgentSessions } = await loadSessionModule();
416
+ try {
417
+ return await listAgentSessions({
418
+ agentCommand: agent.agentCommand,
419
+ cwd: agent.cwd,
420
+ cursor: flags.cursor,
421
+ filterCwd: resolveSessionListFilterCwd(flags, agent.cwd),
422
+ mcpServers: config.mcpServers,
423
+ permissionMode,
424
+ nonInteractivePermissions: globalFlags.nonInteractivePermissions,
425
+ permissionPolicy,
426
+ authCredentials: config.auth,
427
+ authPolicy: globalFlags.authPolicy,
428
+ terminal: globalFlags.terminal,
429
+ timeoutMs: globalFlags.timeout,
430
+ verbose: globalFlags.verbose
431
+ });
432
+ } catch (error) {
433
+ if (error instanceof AgentSpawnError) return "spawn-failed";
434
+ throw error;
435
+ }
436
+ }
437
+ async function handleSessionsList(explicitAgentName, flags, command, config) {
405
438
  const globalFlags = resolveGlobalFlags(command, config);
406
439
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
407
- const [{ listSessionsForAgent }, { printSessionsByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
408
- printSessionsByFormat(await listSessionsForAgent(agent.agentCommand), globalFlags.format);
440
+ const filterCwd = resolveSessionListFilterCwd(flags, agent.cwd);
441
+ if (flags.local) {
442
+ if (flags.cursor) throw new InvalidArgumentError("--cursor cannot be combined with --local");
443
+ await printLocalSessionsList(agent.agentCommand, filterCwd, globalFlags.format);
444
+ return;
445
+ }
446
+ const [result, { printAgentSessionsByFormat }] = await Promise.all([tryListAgentSessions(agent, flags, globalFlags, config), loadOutputRenderModule()]);
447
+ if (!result || result === "spawn-failed") {
448
+ if (result !== "spawn-failed" && (flags.cursor || flags.filterCwd)) throw new Error(`Agent command "${agent.agentCommand}" does not advertise sessionCapabilities.list; cannot use agent-side session/list filters`);
449
+ await printLocalSessionsList(agent.agentCommand, void 0, globalFlags.format);
450
+ return;
451
+ }
452
+ printAgentSessionsByFormat(result, globalFlags.format);
409
453
  }
410
454
  async function handleSessionsClose(explicitAgentName, sessionName, command, config) {
411
455
  const globalFlags = resolveGlobalFlags(command, config);
@@ -470,6 +514,7 @@ function userContentToText(content) {
470
514
  if ("Text" in content) return content.Text;
471
515
  if ("Mention" in content) return content.Mention.content;
472
516
  if ("Image" in content) return content.Image.source || "[image]";
517
+ if ("Audio" in content) return `[audio] ${content.Audio.mime_type || "audio"}`;
473
518
  return "";
474
519
  }
475
520
  function agentContentToText(content) {
@@ -514,24 +559,32 @@ function printSessionDetailsByFormat(record, format) {
514
559
  process.stdout.write(`${record.acpxRecordId}\n`);
515
560
  return;
516
561
  }
517
- process.stdout.write(`id: ${record.acpxRecordId}\n`);
518
- process.stdout.write(`sessionId: ${record.acpSessionId}\n`);
519
- process.stdout.write(`agentSessionId: ${record.agentSessionId ?? "-"}\n`);
520
- process.stdout.write(`agent: ${record.agentCommand}\n`);
521
- process.stdout.write(`cwd: ${record.cwd}\n`);
522
- process.stdout.write(`name: ${record.name ?? "-"}\n`);
523
- process.stdout.write(`created: ${record.createdAt}\n`);
524
- process.stdout.write(`lastActivity: ${record.lastUsedAt}\n`);
525
- process.stdout.write(`lastPrompt: ${record.lastPromptAt ?? "-"}\n`);
526
- process.stdout.write(`closed: ${record.closed ? "yes" : "no"}\n`);
527
- process.stdout.write(`closedAt: ${record.closedAt ?? "-"}\n`);
528
- process.stdout.write(`pid: ${record.pid ?? "-"}\n`);
529
- process.stdout.write(`agentStartedAt: ${record.agentStartedAt ?? "-"}\n`);
530
- process.stdout.write(`lastExitCode: ${record.lastAgentExitCode ?? "-"}\n`);
531
- process.stdout.write(`lastExitSignal: ${record.lastAgentExitSignal ?? "-"}\n`);
532
- process.stdout.write(`lastExitAt: ${record.lastAgentExitAt ?? "-"}\n`);
533
- process.stdout.write(`disconnectReason: ${record.lastAgentDisconnectReason ?? "-"}\n`);
534
- process.stdout.write(`historyEntries: ${conversationHistoryEntries(record).length}\n`);
562
+ for (const line of sessionDetailsLines(record)) process.stdout.write(`${line}\n`);
563
+ }
564
+ function sessionDetailsLines(record) {
565
+ return [
566
+ `id: ${record.acpxRecordId}`,
567
+ `sessionId: ${record.acpSessionId}`,
568
+ `agentSessionId: ${displayValue(record.agentSessionId)}`,
569
+ `agent: ${record.agentCommand}`,
570
+ `cwd: ${record.cwd}`,
571
+ `name: ${displayValue(record.name)}`,
572
+ `created: ${record.createdAt}`,
573
+ `lastActivity: ${record.lastUsedAt}`,
574
+ `lastPrompt: ${displayValue(record.lastPromptAt)}`,
575
+ `closed: ${record.closed ? "yes" : "no"}`,
576
+ `closedAt: ${displayValue(record.closedAt)}`,
577
+ `pid: ${displayValue(record.pid)}`,
578
+ `agentStartedAt: ${displayValue(record.agentStartedAt)}`,
579
+ `lastExitCode: ${displayValue(record.lastAgentExitCode)}`,
580
+ `lastExitSignal: ${displayValue(record.lastAgentExitSignal)}`,
581
+ `lastExitAt: ${displayValue(record.lastAgentExitAt)}`,
582
+ `disconnectReason: ${displayValue(record.lastAgentDisconnectReason)}`,
583
+ `historyEntries: ${conversationHistoryEntries(record).length}`
584
+ ];
585
+ }
586
+ function displayValue(value) {
587
+ return value == null ? "-" : String(value);
535
588
  }
536
589
  function printSessionHistoryByFormat(record, limit, format) {
537
590
  const history = conversationHistoryEntries(record);
@@ -636,38 +689,38 @@ function parseMeta(value, path) {
636
689
  if (!asRecord$1(value)) throw new Error(`Invalid ${path}: expected object or null`);
637
690
  return value;
638
691
  }
639
- function parseServer(rawServer, path) {
640
- const serverRecord = asRecord$1(rawServer);
641
- if (!serverRecord) throw new Error(`Invalid ${path}: expected object`);
642
- const name = parseNonEmptyString(serverRecord.name, `${path}.name`);
643
- const _meta = parseMeta(serverRecord._meta, `${path}._meta`);
644
- const rawType = serverRecord.type;
645
- let typeValue;
646
- if (rawType === void 0) typeValue = "stdio";
647
- else {
648
- const parsedType = parseNonEmptyString(rawType, `${path}.type`);
649
- if (parsedType !== "http" && parsedType !== "sse" && parsedType !== "stdio") throw new Error(`Invalid ${path}.type: expected http, sse, or stdio`);
650
- typeValue = parsedType;
651
- }
652
- if (typeValue === "http" || typeValue === "sse") {
653
- const url = parseNonEmptyString(serverRecord.url, `${path}.url`);
654
- const headers = parseHeaders(serverRecord.headers, `${path}.headers`);
655
- return {
656
- type: typeValue,
657
- name,
658
- url,
659
- headers,
660
- _meta
661
- };
662
- }
663
- if (typeValue === "stdio") return {
692
+ function parseServerType(rawType, path) {
693
+ if (rawType === void 0) return "stdio";
694
+ const parsedType = parseNonEmptyString(rawType, `${path}.type`);
695
+ if (parsedType !== "http" && parsedType !== "sse" && parsedType !== "stdio") throw new Error(`Invalid ${path}.type: expected http, sse, or stdio`);
696
+ return parsedType;
697
+ }
698
+ function parseHttpServer(serverRecord, path, type, name, _meta) {
699
+ return {
700
+ type,
701
+ name,
702
+ url: parseNonEmptyString(serverRecord.url, `${path}.url`),
703
+ headers: parseHeaders(serverRecord.headers, `${path}.headers`),
704
+ _meta
705
+ };
706
+ }
707
+ function parseStdioServer(serverRecord, path, name, _meta) {
708
+ return {
664
709
  name,
665
710
  command: parseNonEmptyString(serverRecord.command, `${path}.command`),
666
711
  args: parseArgs(serverRecord.args, `${path}.args`),
667
712
  env: parseEnv(serverRecord.env, `${path}.env`),
668
713
  _meta
669
714
  };
670
- throw new Error(`Invalid ${path}.type: expected http, sse, or stdio`);
715
+ }
716
+ function parseServer(rawServer, path) {
717
+ const serverRecord = asRecord$1(rawServer);
718
+ if (!serverRecord) throw new Error(`Invalid ${path}: expected object`);
719
+ const name = parseNonEmptyString(serverRecord.name, `${path}.name`);
720
+ const _meta = parseMeta(serverRecord._meta, `${path}._meta`);
721
+ const typeValue = parseServerType(serverRecord.type, path);
722
+ if (typeValue === "http" || typeValue === "sse") return parseHttpServer(serverRecord, path, typeValue, name, _meta);
723
+ return parseStdioServer(serverRecord, path, name, _meta);
671
724
  }
672
725
  function parseMcpServers(value, sourcePath, fieldName = "mcpServers") {
673
726
  const fieldPath = `${fieldName} in ${sourcePath}`;
@@ -828,35 +881,13 @@ async function loadResolvedConfig(cwd) {
828
881
  const [globalResult, projectResult] = await Promise.all([readConfigFile(globalPath), readConfigFile(projectPath)]);
829
882
  const globalConfig = globalResult.config;
830
883
  const projectConfig = projectResult.config;
831
- const defaultAgent = parseDefaultAgent(projectConfig?.defaultAgent, projectPath) ?? parseDefaultAgent(globalConfig?.defaultAgent, globalPath) ?? "codex";
832
- const defaultPermissions = parsePermissionMode(projectConfig?.defaultPermissions, projectPath) ?? parsePermissionMode(globalConfig?.defaultPermissions, globalPath) ?? DEFAULT_PERMISSION_MODE;
833
- const nonInteractivePermissions = parseNonInteractivePermissionPolicy(projectConfig?.nonInteractivePermissions, projectPath) ?? parseNonInteractivePermissionPolicy(globalConfig?.nonInteractivePermissions, globalPath) ?? DEFAULT_NON_INTERACTIVE_PERMISSION_POLICY;
834
- const authPolicy = parseAuthPolicy(projectConfig?.authPolicy, projectPath) ?? parseAuthPolicy(globalConfig?.authPolicy, globalPath) ?? DEFAULT_AUTH_POLICY;
835
- const ttlMs = parseTtlMs(projectConfig?.ttl, projectPath) ?? parseTtlMs(globalConfig?.ttl, globalPath) ?? DEFAULT_TTL_MS;
836
- const timeoutConfiguredInProject = projectConfig != null && Object.prototype.hasOwnProperty.call(projectConfig, "timeout");
837
- const timeoutConfiguredInGlobal = globalConfig != null && Object.prototype.hasOwnProperty.call(globalConfig, "timeout");
838
- let timeoutMs = DEFAULT_TIMEOUT_MS;
839
- if (timeoutConfiguredInProject) timeoutMs = parseTimeoutMs(projectConfig?.timeout, projectPath);
840
- else if (timeoutConfiguredInGlobal) timeoutMs = parseTimeoutMs(globalConfig?.timeout, globalPath);
841
- const format = parseOutputFormat(projectConfig?.format, projectPath) ?? parseOutputFormat(globalConfig?.format, globalPath) ?? DEFAULT_OUTPUT_FORMAT;
842
- const queueMaxDepth = parseQueueMaxDepth(projectConfig?.queueMaxDepth, projectPath) ?? parseQueueMaxDepth(globalConfig?.queueMaxDepth, globalPath) ?? DEFAULT_QUEUE_MAX_DEPTH;
884
+ const scalar = resolveScalarConfigValues(projectConfig, projectPath, globalConfig, globalPath);
843
885
  const agents = mergeAgents(parseAgents(globalConfig?.agents, globalPath), parseAgents(projectConfig?.agents, projectPath));
844
886
  const auth = mergeAuth(parseAuth(globalConfig?.auth, globalPath), parseAuth(projectConfig?.auth, projectPath));
845
- const mcpServersConfiguredInProject = projectConfig != null && Object.prototype.hasOwnProperty.call(projectConfig, "mcpServers");
846
- const mcpServersConfiguredInGlobal = globalConfig != null && Object.prototype.hasOwnProperty.call(globalConfig, "mcpServers");
847
- let mcpServers = [];
848
- if (mcpServersConfiguredInProject) mcpServers = parseMcpServers(projectConfig?.mcpServers, projectPath);
849
- else if (mcpServersConfiguredInGlobal) mcpServers = parseMcpServers(globalConfig?.mcpServers, globalPath);
850
- const disableExec = parseDisableExec(projectConfig?.disableExec, projectPath) ?? parseDisableExec(globalConfig?.disableExec, globalPath) ?? DEFAULT_DISABLE_EXEC;
887
+ const mcpServers = resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath);
888
+ const disableExec = resolveDisableExec(projectConfig, projectPath, globalConfig, globalPath);
851
889
  return {
852
- defaultAgent,
853
- defaultPermissions,
854
- nonInteractivePermissions,
855
- authPolicy,
856
- ttlMs,
857
- timeoutMs,
858
- queueMaxDepth,
859
- format,
890
+ ...scalar,
860
891
  agents,
861
892
  auth,
862
893
  disableExec,
@@ -867,6 +898,55 @@ async function loadResolvedConfig(cwd) {
867
898
  hasProjectConfig: projectResult.exists
868
899
  };
869
900
  }
901
+ function resolveScalarConfigValues(projectConfig, projectPath, globalConfig, globalPath) {
902
+ return {
903
+ defaultAgent: resolveDefaultAgent(projectConfig, projectPath, globalConfig, globalPath),
904
+ defaultPermissions: resolveDefaultPermissions(projectConfig, projectPath, globalConfig, globalPath),
905
+ nonInteractivePermissions: resolveNonInteractivePermissions(projectConfig, projectPath, globalConfig, globalPath),
906
+ authPolicy: resolveAuthPolicy(projectConfig, projectPath, globalConfig, globalPath),
907
+ ttlMs: resolveTtlMs(projectConfig, projectPath, globalConfig, globalPath),
908
+ timeoutMs: resolveTimeoutMs(projectConfig, projectPath, globalConfig, globalPath),
909
+ queueMaxDepth: resolveQueueMaxDepth(projectConfig, projectPath, globalConfig, globalPath),
910
+ format: resolveFormat(projectConfig, projectPath, globalConfig, globalPath)
911
+ };
912
+ }
913
+ function resolveDefaultAgent(projectConfig, projectPath, globalConfig, globalPath) {
914
+ return parseDefaultAgent(projectConfig?.defaultAgent, projectPath) ?? parseDefaultAgent(globalConfig?.defaultAgent, globalPath) ?? "codex";
915
+ }
916
+ function resolveDefaultPermissions(projectConfig, projectPath, globalConfig, globalPath) {
917
+ return parsePermissionMode(projectConfig?.defaultPermissions, projectPath) ?? parsePermissionMode(globalConfig?.defaultPermissions, globalPath) ?? DEFAULT_PERMISSION_MODE;
918
+ }
919
+ function resolveNonInteractivePermissions(projectConfig, projectPath, globalConfig, globalPath) {
920
+ return parseNonInteractivePermissionPolicy(projectConfig?.nonInteractivePermissions, projectPath) ?? parseNonInteractivePermissionPolicy(globalConfig?.nonInteractivePermissions, globalPath) ?? DEFAULT_NON_INTERACTIVE_PERMISSION_POLICY;
921
+ }
922
+ function resolveAuthPolicy(projectConfig, projectPath, globalConfig, globalPath) {
923
+ return parseAuthPolicy(projectConfig?.authPolicy, projectPath) ?? parseAuthPolicy(globalConfig?.authPolicy, globalPath) ?? DEFAULT_AUTH_POLICY;
924
+ }
925
+ function resolveTtlMs(projectConfig, projectPath, globalConfig, globalPath) {
926
+ return parseTtlMs(projectConfig?.ttl, projectPath) ?? parseTtlMs(globalConfig?.ttl, globalPath) ?? DEFAULT_TTL_MS;
927
+ }
928
+ function resolveQueueMaxDepth(projectConfig, projectPath, globalConfig, globalPath) {
929
+ return parseQueueMaxDepth(projectConfig?.queueMaxDepth, projectPath) ?? parseQueueMaxDepth(globalConfig?.queueMaxDepth, globalPath) ?? DEFAULT_QUEUE_MAX_DEPTH;
930
+ }
931
+ function resolveFormat(projectConfig, projectPath, globalConfig, globalPath) {
932
+ return parseOutputFormat(projectConfig?.format, projectPath) ?? parseOutputFormat(globalConfig?.format, globalPath) ?? DEFAULT_OUTPUT_FORMAT;
933
+ }
934
+ function hasConfigKey(config, key) {
935
+ return config != null && Object.prototype.hasOwnProperty.call(config, key);
936
+ }
937
+ function resolveTimeoutMs(projectConfig, projectPath, globalConfig, globalPath) {
938
+ if (hasConfigKey(projectConfig, "timeout")) return parseTimeoutMs(projectConfig?.timeout, projectPath);
939
+ if (hasConfigKey(globalConfig, "timeout")) return parseTimeoutMs(globalConfig?.timeout, globalPath);
940
+ return DEFAULT_TIMEOUT_MS;
941
+ }
942
+ function resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath) {
943
+ if (hasConfigKey(projectConfig, "mcpServers")) return parseMcpServers(projectConfig?.mcpServers, projectPath);
944
+ if (hasConfigKey(globalConfig, "mcpServers")) return parseMcpServers(globalConfig?.mcpServers, globalPath);
945
+ return [];
946
+ }
947
+ function resolveDisableExec(projectConfig, projectPath, globalConfig, globalPath) {
948
+ return parseDisableExec(projectConfig?.disableExec, projectPath) ?? parseDisableExec(globalConfig?.disableExec, globalPath) ?? DEFAULT_DISABLE_EXEC;
949
+ }
870
950
  function toConfigDisplay(config) {
871
951
  const agents = {};
872
952
  for (const [name, command] of Object.entries(config.agents)) agents[name] = { command };
@@ -970,6 +1050,7 @@ function registerConfigCommand(program, config) {
970
1050
  var render_exports = /* @__PURE__ */ __exportAll({
971
1051
  agentSessionIdPayload: () => agentSessionIdPayload,
972
1052
  formatPromptSessionBannerLine: () => formatPromptSessionBannerLine,
1053
+ printAgentSessionsByFormat: () => printAgentSessionsByFormat,
973
1054
  printClosedSessionByFormat: () => printClosedSessionByFormat,
974
1055
  printCreatedSessionBanner: () => printCreatedSessionBanner,
975
1056
  printEnsuredSessionByFormat: () => printEnsuredSessionByFormat,
@@ -996,10 +1077,7 @@ function printSessionsByFormat(sessions, format) {
996
1077
  return;
997
1078
  }
998
1079
  if (format === "quiet") {
999
- for (const session of sessions) {
1000
- const closedMarker = session.closed ? " [closed]" : "";
1001
- process.stdout.write(`${session.acpxRecordId}${closedMarker}\n`);
1002
- }
1080
+ printQuietSessions(sessions);
1003
1081
  return;
1004
1082
  }
1005
1083
  if (sessions.length === 0) {
@@ -1011,6 +1089,36 @@ function printSessionsByFormat(sessions, format) {
1011
1089
  process.stdout.write(`${session.acpxRecordId}${closedMarker}\t${session.name ?? "-"}\t${session.cwd}\t${session.lastUsedAt}\n`);
1012
1090
  }
1013
1091
  }
1092
+ function printQuietSessions(sessions) {
1093
+ for (const session of sessions) {
1094
+ const closedMarker = session.closed ? " [closed]" : "";
1095
+ process.stdout.write(`${session.acpxRecordId}${closedMarker}\n`);
1096
+ }
1097
+ }
1098
+ function printAgentSessionsByFormat(result, format) {
1099
+ if (format === "json") {
1100
+ process.stdout.write(`${JSON.stringify(result)}\n`);
1101
+ return;
1102
+ }
1103
+ if (format === "quiet") {
1104
+ printQuietAgentSessions(result);
1105
+ return;
1106
+ }
1107
+ printTextAgentSessions(result);
1108
+ }
1109
+ function printQuietAgentSessions(result) {
1110
+ for (const session of result.sessions) process.stdout.write(`${session.sessionId}\n`);
1111
+ }
1112
+ function printTextAgentSessions(result) {
1113
+ if (result.sessions.length === 0) process.stdout.write("No sessions\n");
1114
+ else for (const session of result.sessions) {
1115
+ const title = session.title ?? "-";
1116
+ const updatedAt = session.updatedAt ?? "-";
1117
+ const meta = session._meta ? JSON.stringify(session._meta) : "-";
1118
+ process.stdout.write(`${session.sessionId}\t${title}\t${session.cwd}\t${updatedAt}\t${meta}\n`);
1119
+ }
1120
+ if (result.nextCursor) process.stdout.write(`Next cursor: ${result.nextCursor}\n`);
1121
+ }
1014
1122
  function printClosedSessionByFormat(record, format) {
1015
1123
  if (emitJsonResult(format, {
1016
1124
  action: "session_closed",
@@ -1095,29 +1203,38 @@ function formatBytes(bytes) {
1095
1203
  }
1096
1204
  function printPruneResultByFormat(result, format) {
1097
1205
  const count = result.pruned.length;
1098
- if (emitJsonResult(format, {
1099
- action: result.dryRun ? "sessions_prune_dry_run" : "sessions_pruned",
1100
- dryRun: result.dryRun,
1101
- count,
1102
- bytesFreed: result.bytesFreed,
1103
- pruned: result.pruned.map((r) => r.acpxRecordId)
1104
- })) return;
1206
+ if (emitPruneJsonResult(result, format, count)) return;
1105
1207
  if (format === "quiet") {
1106
- for (const record of result.pruned) process.stdout.write(`${record.acpxRecordId}\n`);
1208
+ printQuietPruneResult(result.pruned);
1107
1209
  return;
1108
1210
  }
1109
1211
  if (count === 0) {
1110
1212
  process.stdout.write(result.dryRun ? "[DRY RUN] No sessions to prune\n" : "No sessions pruned\n");
1111
1213
  return;
1112
1214
  }
1113
- const prefix = result.dryRun ? "[DRY RUN] Would prune" : "Pruned";
1114
- const bytesSuffix = !result.dryRun && result.bytesFreed > 0 ? `, freed ${formatBytes(result.bytesFreed)}` : "";
1115
- process.stdout.write(`${prefix} ${count} session${count === 1 ? "" : "s"}${bytesSuffix}\n`);
1215
+ process.stdout.write(`${formatPruneSummaryLine(result, count)}\n`);
1116
1216
  for (const record of result.pruned) {
1117
1217
  const label = record.name ? ` (${record.name})` : "";
1118
1218
  process.stdout.write(` ${record.acpxRecordId}${label}\t${record.closedAt ?? record.lastUsedAt}\n`);
1119
1219
  }
1120
1220
  }
1221
+ function emitPruneJsonResult(result, format, count) {
1222
+ return emitJsonResult(format, {
1223
+ action: result.dryRun ? "sessions_prune_dry_run" : "sessions_pruned",
1224
+ dryRun: result.dryRun,
1225
+ count,
1226
+ bytesFreed: result.bytesFreed,
1227
+ pruned: result.pruned.map((r) => r.acpxRecordId)
1228
+ });
1229
+ }
1230
+ function printQuietPruneResult(pruned) {
1231
+ for (const record of pruned) process.stdout.write(`${record.acpxRecordId}\n`);
1232
+ }
1233
+ function formatPruneSummaryLine(result, count) {
1234
+ const prefix = result.dryRun ? "[DRY RUN] Would prune" : "Pruned";
1235
+ const bytesSuffix = !result.dryRun && result.bytesFreed > 0 ? `, freed ${formatBytes(result.bytesFreed)}` : "";
1236
+ return `${prefix} ${count} session${count === 1 ? "" : "s"}${bytesSuffix}`;
1237
+ }
1121
1238
  function agentSessionIdPayload(agentSessionId) {
1122
1239
  const normalized = normalizeRuntimeSessionId(agentSessionId);
1123
1240
  if (!normalized) return {};
@@ -1159,63 +1276,115 @@ async function handleStatus(explicitAgentName, flags, command, config) {
1159
1276
  name: resolveSessionNameFromFlags(flags, command)
1160
1277
  });
1161
1278
  if (!record) {
1162
- if (emitJsonResult(globalFlags.format, {
1163
- action: "status_snapshot",
1164
- status: "no-session",
1165
- summary: "no active session"
1166
- })) return;
1167
- if (globalFlags.format === "quiet") {
1168
- process.stdout.write("no-session\n");
1169
- return;
1170
- }
1171
- process.stdout.write("session: -\n");
1172
- process.stdout.write(`agent: ${agent.agentCommand}\n`);
1173
- process.stdout.write("pid: -\n");
1174
- process.stdout.write("status: no-session\n");
1175
- process.stdout.write("model: -\n");
1176
- process.stdout.write("mode: -\n");
1177
- process.stdout.write("uptime: -\n");
1178
- process.stdout.write("lastPromptTime: -\n");
1279
+ printMissingStatus(globalFlags.format, agent.agentCommand);
1179
1280
  return;
1180
1281
  }
1282
+ await printSessionStatus(record, globalFlags.format);
1283
+ }
1284
+ function printMissingStatus(format, agentCommand) {
1285
+ if (emitJsonResult(format, {
1286
+ action: "status_snapshot",
1287
+ status: "no-session",
1288
+ summary: "no active session"
1289
+ })) return;
1290
+ if (format === "quiet") {
1291
+ process.stdout.write("no-session\n");
1292
+ return;
1293
+ }
1294
+ process.stdout.write("session: -\n");
1295
+ process.stdout.write(`agent: ${agentCommand}\n`);
1296
+ process.stdout.write("pid: -\n");
1297
+ process.stdout.write("status: no-session\n");
1298
+ process.stdout.write("model: -\n");
1299
+ process.stdout.write("mode: -\n");
1300
+ process.stdout.write("uptime: -\n");
1301
+ process.stdout.write("lastPromptTime: -\n");
1302
+ }
1303
+ async function printSessionStatus(record, format) {
1181
1304
  const health = await probeQueueOwnerHealth(record.acpxRecordId);
1182
1305
  const statusState = resolveStatusState(record, health);
1183
- const running = statusState === "running";
1184
- const dead = statusState === "dead";
1185
- const payload = {
1306
+ const payload = createStatusPayload(record, health, statusState);
1307
+ const running = isRunningStatus(statusState);
1308
+ const dead = isDeadStatus(statusState);
1309
+ if (emitStatusJson(format, record, payload, statusState, running, dead)) return;
1310
+ if (format === "quiet") {
1311
+ process.stdout.write(`${payload.status}\n`);
1312
+ return;
1313
+ }
1314
+ printTextStatus(payload, dead);
1315
+ }
1316
+ function createStatusPayload(record, health, statusState) {
1317
+ const running = isRunningStatus(statusState);
1318
+ const acpx = statusAcpxFields(record);
1319
+ return {
1186
1320
  sessionId: record.acpxRecordId,
1187
1321
  agentCommand: record.agentCommand,
1188
- pid: health.pid ?? record.pid ?? null,
1322
+ pid: statusPid(health),
1189
1323
  status: statusState,
1324
+ model: acpx.model,
1325
+ mode: acpx.mode,
1326
+ availableModels: acpx.availableModels,
1327
+ uptime: running ? optionalStatusString(formatUptime(record.agentStartedAt)) : null,
1328
+ lastPromptTime: optionalStatusString(record.lastPromptAt),
1329
+ exitCode: running ? null : optionalStatusNumber(record.lastAgentExitCode),
1330
+ signal: running ? null : optionalStatusSignal(record.lastAgentExitSignal),
1331
+ ...agentSessionIdPayload(record.agentSessionId)
1332
+ };
1333
+ }
1334
+ function statusAcpxFields(record) {
1335
+ return {
1190
1336
  model: record.acpx?.current_model_id ?? null,
1191
1337
  mode: record.acpx?.current_mode_id ?? null,
1192
- availableModels: record.acpx?.available_models ?? null,
1193
- uptime: running ? formatUptime(record.agentStartedAt) ?? null : null,
1194
- lastPromptTime: record.lastPromptAt ?? null,
1195
- exitCode: running ? null : record.lastAgentExitCode ?? null,
1196
- signal: running ? null : record.lastAgentExitSignal ?? null,
1197
- ...agentSessionIdPayload(record.agentSessionId)
1338
+ availableModels: record.acpx?.available_models ?? null
1198
1339
  };
1199
- if (emitJsonResult(globalFlags.format, {
1340
+ }
1341
+ function statusPid(health) {
1342
+ if (health.pidAlive) return health.pid ?? null;
1343
+ return null;
1344
+ }
1345
+ function optionalStatusString(value) {
1346
+ return value ?? null;
1347
+ }
1348
+ function optionalStatusNumber(value) {
1349
+ return value ?? null;
1350
+ }
1351
+ function optionalStatusSignal(value) {
1352
+ return value ?? null;
1353
+ }
1354
+ function isRunningStatus(status) {
1355
+ return status === "running";
1356
+ }
1357
+ function isDeadStatus(status) {
1358
+ return status === "dead";
1359
+ }
1360
+ function emitStatusJson(format, record, payload, statusState, running, dead) {
1361
+ return emitJsonResult(format, statusJsonPayload(record, payload, statusState, running, dead));
1362
+ }
1363
+ function statusJsonPayload(record, payload, statusState, running, dead) {
1364
+ const result = {
1200
1365
  action: "status_snapshot",
1201
1366
  status: running ? "alive" : statusState,
1202
- pid: payload.pid ?? void 0,
1203
1367
  summary: statusSummary(statusState),
1204
- model: payload.model ?? void 0,
1205
- mode: payload.mode ?? void 0,
1206
- availableModels: payload.availableModels ?? void 0,
1207
- uptime: payload.uptime ?? void 0,
1208
- lastPromptTime: payload.lastPromptTime ?? void 0,
1209
- exitCode: dead ? payload.exitCode ?? void 0 : void 0,
1210
- signal: dead ? payload.signal ?? void 0 : void 0,
1211
1368
  acpxRecordId: record.acpxRecordId,
1212
1369
  acpxSessionId: record.acpSessionId,
1213
1370
  agentSessionId: record.agentSessionId
1214
- })) return;
1215
- if (globalFlags.format === "quiet") {
1216
- process.stdout.write(`${payload.status}\n`);
1217
- return;
1371
+ };
1372
+ assignDefinedJsonField(result, "pid", payload.pid);
1373
+ assignDefinedJsonField(result, "model", payload.model);
1374
+ assignDefinedJsonField(result, "mode", payload.mode);
1375
+ assignDefinedJsonField(result, "availableModels", payload.availableModels);
1376
+ assignDefinedJsonField(result, "uptime", payload.uptime);
1377
+ assignDefinedJsonField(result, "lastPromptTime", payload.lastPromptTime);
1378
+ if (dead) {
1379
+ assignDefinedJsonField(result, "exitCode", payload.exitCode);
1380
+ assignDefinedJsonField(result, "signal", payload.signal);
1218
1381
  }
1382
+ return result;
1383
+ }
1384
+ function assignDefinedJsonField(target, key, value) {
1385
+ if (value !== null && value !== void 0) target[key] = value;
1386
+ }
1387
+ function printTextStatus(payload, dead) {
1219
1388
  process.stdout.write(`session: ${payload.sessionId}\n`);
1220
1389
  if ("agentSessionId" in payload) process.stdout.write(`agentSessionId: ${payload.agentSessionId}\n`);
1221
1390
  process.stdout.write(`agent: ${payload.agentCommand}\n`);
@@ -1225,10 +1394,11 @@ async function handleStatus(explicitAgentName, flags, command, config) {
1225
1394
  process.stdout.write(`mode: ${payload.mode ?? "-"}\n`);
1226
1395
  process.stdout.write(`uptime: ${payload.uptime ?? "-"}\n`);
1227
1396
  process.stdout.write(`lastPromptTime: ${payload.lastPromptTime ?? "-"}\n`);
1228
- if (dead) {
1229
- process.stdout.write(`exitCode: ${payload.exitCode ?? "-"}\n`);
1230
- process.stdout.write(`signal: ${payload.signal ?? "-"}\n`);
1231
- }
1397
+ if (dead) printDeadStatusDetails(payload);
1398
+ }
1399
+ function printDeadStatusDetails(payload) {
1400
+ process.stdout.write(`exitCode: ${payload.exitCode ?? "-"}\n`);
1401
+ process.stdout.write(`signal: ${payload.signal ?? "-"}\n`);
1232
1402
  }
1233
1403
  function registerStatusCommand(parent, explicitAgentName, config, description) {
1234
1404
  const statusCommand = parent.command("status").description(description);
@@ -1239,13 +1409,17 @@ function registerStatusCommand(parent, explicitAgentName, config, description) {
1239
1409
  }
1240
1410
  //#endregion
1241
1411
  //#region src/cli/command-registration.ts
1412
+ function addSessionsListOptions(command) {
1413
+ return command.option("--local", "List local acpx session records instead of agent protocol sessions").option("--cursor <cursor>", "Opaque ACP session/list cursor", (value) => parseNonEmptyValue("Cursor", value)).option("--filter-cwd <dir>", "Filter agent sessions by working directory", (value) => parseNonEmptyValue("Filter cwd", value));
1414
+ }
1242
1415
  function registerSessionsCommand(parent, explicitAgentName, config) {
1243
1416
  const sessionsCommand = parent.command("sessions").description("List, ensure, create, or close sessions for this agent");
1244
- sessionsCommand.action(async function() {
1245
- await handleSessionsList(explicitAgentName, this, config);
1417
+ addSessionsListOptions(sessionsCommand);
1418
+ sessionsCommand.action(async function(flags) {
1419
+ await handleSessionsList(explicitAgentName, flags, this, config);
1246
1420
  });
1247
- sessionsCommand.command("list").description("List sessions").action(async function() {
1248
- await handleSessionsList(explicitAgentName, this, config);
1421
+ addSessionsListOptions(sessionsCommand.command("list")).description("List sessions").action(async function(flags) {
1422
+ await handleSessionsList(explicitAgentName, flags, this, config);
1249
1423
  });
1250
1424
  sessionsCommand.command("new").description("Create a fresh session for current cwd").option("-s, --name <name>", "Session name", parseSessionName).option("--resume-session <id>", "Resume existing ACP session id", (value) => parseNonEmptyValue("Resume session id", value)).action(async function(flags) {
1251
1425
  await handleSessionsNew(explicitAgentName, flags, this, config);
@@ -1317,7 +1491,7 @@ function registerAgentCommand(program, agentName, config) {
1317
1491
  }
1318
1492
  function registerFlowCommand(program, config) {
1319
1493
  program.command("flow").description("Run multi-step ACP workflows from flow files").command("run").description("Run a flow file").argument("<file>", "Flow module path").option("--input-json <json>", "Flow input as JSON").option("--input-file <path>", "Read flow input JSON from file").option("--default-agent <name>", "Default agent profile for ACP nodes without profile", (value) => parseNonEmptyValue("Default agent", value)).action(async function(file, flags) {
1320
- const { handleFlowRun } = await import("./cli-BGYGVo3b.js");
1494
+ const { handleFlowRun } = await import("./cli-Bf3yjqzE.js");
1321
1495
  await handleFlowRun(file, flags, this, config);
1322
1496
  });
1323
1497
  }
@@ -1349,33 +1523,63 @@ function parseQueueOwnerPayload(raw) {
1349
1523
  sessionId: record.sessionId,
1350
1524
  permissionMode: record.permissionMode
1351
1525
  };
1526
+ assignQueueOwnerTransportOptions(options, record);
1527
+ assignQueueOwnerScalarOptions(options, record);
1528
+ assignQueueOwnerSessionOptions(options, record.sessionOptions);
1529
+ return options;
1530
+ }
1531
+ function assignQueueOwnerTransportOptions(options, record) {
1352
1532
  const parsedMcpServers = parseOptionalMcpServers(record.mcpServers, "queue owner payload");
1353
1533
  if (parsedMcpServers) options.mcpServers = parsedMcpServers;
1354
- if (typeof record.nonInteractivePermissions === "string") options.nonInteractivePermissions = record.nonInteractivePermissions === "deny" || record.nonInteractivePermissions === "fail" ? record.nonInteractivePermissions : void 0;
1355
1534
  if (record.authCredentials && typeof record.authCredentials === "object") {
1356
1535
  const entries = Object.entries(record.authCredentials).filter(([, value]) => typeof value === "string");
1357
1536
  options.authCredentials = Object.fromEntries(entries);
1358
1537
  }
1538
+ }
1539
+ function assignQueueOwnerScalarOptions(options, record) {
1540
+ if (record.nonInteractivePermissions === "deny" || record.nonInteractivePermissions === "fail") options.nonInteractivePermissions = record.nonInteractivePermissions;
1359
1541
  if (record.authPolicy === "skip" || record.authPolicy === "fail") options.authPolicy = record.authPolicy;
1360
- if (typeof record.terminal === "boolean") options.terminal = record.terminal;
1361
- if (typeof record.suppressSdkConsoleErrors === "boolean") options.suppressSdkConsoleErrors = record.suppressSdkConsoleErrors;
1362
- if (typeof record.verbose === "boolean") options.verbose = record.verbose;
1363
- if (typeof record.ttlMs === "number" && Number.isFinite(record.ttlMs)) options.ttlMs = record.ttlMs;
1364
- if (typeof record.maxQueueDepth === "number" && Number.isFinite(record.maxQueueDepth)) options.maxQueueDepth = Math.max(1, Math.round(record.maxQueueDepth));
1365
- if (typeof record.promptRetries === "number" && Number.isFinite(record.promptRetries)) options.promptRetries = Math.max(0, Math.round(record.promptRetries));
1366
- const sessionOpts = asRecord(record.sessionOptions);
1367
- if (sessionOpts) {
1368
- options.sessionOptions = {};
1369
- if (typeof sessionOpts.model === "string" && sessionOpts.model.trim().length > 0) options.sessionOptions.model = sessionOpts.model;
1370
- if (Array.isArray(sessionOpts.allowedTools)) options.sessionOptions.allowedTools = sessionOpts.allowedTools.filter((tool) => typeof tool === "string");
1371
- if (typeof sessionOpts.maxTurns === "number" && Number.isFinite(sessionOpts.maxTurns)) options.sessionOptions.maxTurns = Math.max(1, Math.round(sessionOpts.maxTurns));
1372
- if (typeof sessionOpts.systemPrompt === "string") options.sessionOptions.systemPrompt = sessionOpts.systemPrompt;
1373
- else {
1374
- const systemPrompt = asRecord(sessionOpts.systemPrompt);
1375
- if (typeof systemPrompt?.append === "string") options.sessionOptions.systemPrompt = { append: systemPrompt.append };
1376
- }
1542
+ assignBooleanOption(options, "terminal", record.terminal);
1543
+ assignBooleanOption(options, "suppressSdkConsoleErrors", record.suppressSdkConsoleErrors);
1544
+ assignBooleanOption(options, "verbose", record.verbose);
1545
+ assignFiniteNumberOption(options, "ttlMs", record.ttlMs);
1546
+ assignRoundedNumberOption(options, "maxQueueDepth", record.maxQueueDepth, 1);
1547
+ assignRoundedNumberOption(options, "promptRetries", record.promptRetries, 0);
1548
+ }
1549
+ function assignBooleanOption(options, key, value) {
1550
+ if (typeof value === "boolean") options[key] = value;
1551
+ }
1552
+ function assignFiniteNumberOption(options, key, value) {
1553
+ if (typeof value === "number" && Number.isFinite(value)) options[key] = value;
1554
+ }
1555
+ function assignRoundedNumberOption(options, key, value, min) {
1556
+ if (typeof value === "number" && Number.isFinite(value)) options[key] = Math.max(min, Math.round(value));
1557
+ }
1558
+ function assignQueueOwnerSessionOptions(options, rawSessionOptions) {
1559
+ const sessionOpts = asRecord(rawSessionOptions);
1560
+ if (!sessionOpts) return;
1561
+ options.sessionOptions = {};
1562
+ assignSessionModel(options.sessionOptions, sessionOpts.model);
1563
+ assignSessionAllowedTools(options.sessionOptions, sessionOpts.allowedTools);
1564
+ assignSessionMaxTurns(options.sessionOptions, sessionOpts.maxTurns);
1565
+ assignSessionSystemPrompt(options.sessionOptions, sessionOpts.systemPrompt);
1566
+ }
1567
+ function assignSessionModel(options, value) {
1568
+ if (typeof value === "string" && value.trim().length > 0) options.model = value;
1569
+ }
1570
+ function assignSessionAllowedTools(options, value) {
1571
+ if (Array.isArray(value)) options.allowedTools = value.filter((tool) => typeof tool === "string");
1572
+ }
1573
+ function assignSessionMaxTurns(options, value) {
1574
+ if (typeof value === "number" && Number.isFinite(value)) options.maxTurns = Math.max(1, Math.round(value));
1575
+ }
1576
+ function assignSessionSystemPrompt(options, value) {
1577
+ if (typeof value === "string") {
1578
+ options.systemPrompt = value;
1579
+ return;
1377
1580
  }
1378
- return options;
1581
+ const systemPrompt = asRecord(value);
1582
+ if (typeof systemPrompt?.append === "string") options.systemPrompt = { append: systemPrompt.append };
1379
1583
  }
1380
1584
  async function runQueueOwnerFromEnv(env) {
1381
1585
  const payload = env.ACPX_QUEUE_OWNER_PAYLOAD;
@@ -1410,13 +1614,16 @@ function resolveVersionFromAncestors(startDir) {
1410
1614
  }
1411
1615
  }
1412
1616
  function resolveAcpxVersion(params) {
1413
- const env = params?.env ?? process.env;
1414
- const envPackageName = parseVersion(env.npm_package_name);
1415
- const envVersion = parseVersion(env.npm_package_version);
1416
- if (envPackageName === "acpx" && envVersion) return envVersion;
1617
+ const envVersion = resolvePackageEnvVersion(params?.env ?? process.env);
1618
+ if (envVersion) return envVersion;
1417
1619
  if (params?.packageJsonPath) return readPackageVersion(params.packageJsonPath) ?? UNKNOWN_VERSION;
1418
1620
  return resolveVersionFromAncestors(MODULE_DIR) ?? UNKNOWN_VERSION;
1419
1621
  }
1622
+ function resolvePackageEnvVersion(env) {
1623
+ const envPackageName = parseVersion(env.npm_package_name);
1624
+ const envVersion = parseVersion(env.npm_package_version);
1625
+ return envPackageName === "acpx" ? envVersion : null;
1626
+ }
1420
1627
  function getAcpxVersion() {
1421
1628
  if (cachedVersion) return cachedVersion;
1422
1629
  cachedVersion = resolveAcpxVersion();
@@ -1436,6 +1643,36 @@ const TOP_LEVEL_VERBS = new Set([
1436
1643
  "config",
1437
1644
  "help"
1438
1645
  ]);
1646
+ const TOP_LEVEL_VERSION_VALUE_FLAG_VALUES = [
1647
+ "--agent",
1648
+ "--cwd",
1649
+ "--auth-policy",
1650
+ "--non-interactive-permissions",
1651
+ "--permission-policy",
1652
+ "--policy",
1653
+ "--format",
1654
+ "--model",
1655
+ "--allowed-tools",
1656
+ "--max-turns",
1657
+ "--system-prompt",
1658
+ "--append-system-prompt",
1659
+ "--prompt-retries",
1660
+ "--timeout",
1661
+ "--ttl"
1662
+ ];
1663
+ const TOP_LEVEL_VERSION_VALUE_FLAGS = new Set(TOP_LEVEL_VERSION_VALUE_FLAG_VALUES);
1664
+ const TOP_LEVEL_VERSION_BOOLEAN_FLAGS = new Set([
1665
+ "--approve-all",
1666
+ "--approve-reads",
1667
+ "--deny-all",
1668
+ "--suppress-reads",
1669
+ "--json-strict",
1670
+ "--no-terminal",
1671
+ "--verbose"
1672
+ ]);
1673
+ const AGENT_SCAN_VALUE_FLAG_VALUES = [...TOP_LEVEL_VERSION_VALUE_FLAG_VALUES, "--file"];
1674
+ const AGENT_SCAN_VALUE_FLAGS = new Set(AGENT_SCAN_VALUE_FLAG_VALUES);
1675
+ const AGENT_SCAN_BOOLEAN_FLAGS = new Set(TOP_LEVEL_VERSION_BOOLEAN_FLAGS);
1439
1676
  let skillflagModulePromise;
1440
1677
  function loadSkillflagModule() {
1441
1678
  skillflagModulePromise ??= import("skillflag");
@@ -1444,31 +1681,48 @@ function loadSkillflagModule() {
1444
1681
  function shouldMaybeHandleSkillflag(argv) {
1445
1682
  return argv.some((token) => token === "--skill" || token.startsWith("--skill="));
1446
1683
  }
1684
+ function matchesLongFlagValue(token, flags) {
1685
+ for (const flag of flags) if (token.startsWith(`${flag}=`)) return true;
1686
+ return false;
1687
+ }
1688
+ function classifyAgentTokenFlag(token) {
1689
+ if (token === "--agent" || token.startsWith("--agent=")) return "agent-value";
1690
+ if (AGENT_SCAN_VALUE_FLAGS.has(token)) return "skip-next";
1691
+ if (AGENT_SCAN_BOOLEAN_FLAGS.has(token) || matchesLongFlagValue(token, AGENT_SCAN_VALUE_FLAGS) || token.startsWith("--json-strict=")) return "skip";
1692
+ return "unknown";
1693
+ }
1694
+ function scanAgentTokenStep(token, hasAgentOverride) {
1695
+ if (token === "--") return {
1696
+ result: { hasAgentOverride },
1697
+ indexDelta: 0
1698
+ };
1699
+ if (!token.startsWith("-") || token === "-") return {
1700
+ result: {
1701
+ token,
1702
+ hasAgentOverride
1703
+ },
1704
+ indexDelta: 0
1705
+ };
1706
+ const flagScan = classifyAgentTokenFlag(token);
1707
+ if (flagScan === "agent-value") return {
1708
+ indexDelta: token === "--agent" ? 1 : 0,
1709
+ hasAgentOverride: true
1710
+ };
1711
+ if (flagScan === "skip-next") return { indexDelta: 1 };
1712
+ if (flagScan === "skip") return { indexDelta: 0 };
1713
+ return {
1714
+ result: { hasAgentOverride },
1715
+ indexDelta: 0
1716
+ };
1717
+ }
1447
1718
  function detectAgentToken(argv) {
1448
1719
  let hasAgentOverride = false;
1449
1720
  for (let index = 0; index < argv.length; index += 1) {
1450
1721
  const token = argv[index];
1451
- if (token === "--") break;
1452
- if (!token.startsWith("-") || token === "-") return {
1453
- token,
1454
- hasAgentOverride
1455
- };
1456
- if (token === "--agent") {
1457
- hasAgentOverride = true;
1458
- index += 1;
1459
- continue;
1460
- }
1461
- if (token.startsWith("--agent=")) {
1462
- hasAgentOverride = true;
1463
- continue;
1464
- }
1465
- if (token === "--cwd" || token === "--auth-policy" || token === "--non-interactive-permissions" || token === "--permission-policy" || token === "--policy" || token === "--format" || token === "--model" || token === "--allowed-tools" || token === "--max-turns" || token === "--timeout" || token === "--ttl" || token === "--file") {
1466
- index += 1;
1467
- continue;
1468
- }
1469
- if (token.startsWith("--cwd=") || token.startsWith("--auth-policy=") || token.startsWith("--non-interactive-permissions=") || token.startsWith("--permission-policy=") || token.startsWith("--policy=") || token.startsWith("--format=") || token.startsWith("--model=") || token.startsWith("--allowed-tools=") || token.startsWith("--max-turns=") || token.startsWith("--json-strict=") || token.startsWith("--timeout=") || token.startsWith("--ttl=") || token.startsWith("--file=")) continue;
1470
- if (token === "--approve-all" || token === "--approve-reads" || token === "--deny-all" || token === "--json-strict" || token === "--verbose" || token === "--suppress-reads") continue;
1471
- return { hasAgentOverride };
1722
+ const step = scanAgentTokenStep(token, hasAgentOverride);
1723
+ if (step.result) return step.result;
1724
+ if (step.hasAgentOverride) hasAgentOverride = true;
1725
+ index += step.indexDelta;
1472
1726
  }
1473
1727
  return { hasAgentOverride };
1474
1728
  }
@@ -1494,24 +1748,52 @@ function detectRequestedOutputFormat(argv, fallback) {
1494
1748
  for (let index = 0; index < argv.length; index += 1) {
1495
1749
  const token = argv[index];
1496
1750
  if (token === "--") break;
1497
- if (token === "--json-strict" || token.startsWith("--json-strict=")) return "json";
1498
- if (token === "--format") {
1499
- const raw = argv[index + 1];
1500
- if (raw && OUTPUT_FORMATS.includes(raw)) detectedFormat = raw;
1501
- continue;
1502
- }
1503
- if (token.startsWith("--format=")) {
1504
- const raw = token.slice(9).trim();
1505
- if (OUTPUT_FORMATS.includes(raw)) detectedFormat = raw;
1506
- }
1751
+ if (isJsonStrictToken(token)) return "json";
1752
+ const format = readFormatFlagValue(token, argv[index + 1]);
1753
+ if (format) detectedFormat = format;
1507
1754
  }
1508
1755
  return detectedFormat;
1509
1756
  }
1757
+ function readFormatFlagValue(token, nextToken) {
1758
+ const raw = token === "--format" ? nextToken : readInlineFlagValue(token, "--format");
1759
+ return isOutputFormat(raw) ? raw : void 0;
1760
+ }
1761
+ function readInlineFlagValue(token, flag) {
1762
+ if (!token.startsWith(`${flag}=`)) return;
1763
+ return token.slice(flag.length + 1).trim();
1764
+ }
1765
+ function isOutputFormat(value) {
1766
+ return typeof value === "string" && OUTPUT_FORMATS.includes(value);
1767
+ }
1768
+ function isJsonStrictToken(token) {
1769
+ return token === "--json-strict" || token.startsWith("--json-strict=");
1770
+ }
1510
1771
  function detectJsonStrict(argv) {
1511
1772
  for (let index = 0; index < argv.length; index += 1) {
1512
1773
  const token = argv[index];
1513
1774
  if (token === "--") break;
1514
- if (token === "--json-strict" || token.startsWith("--json-strict=")) return true;
1775
+ if (isJsonStrictToken(token)) return true;
1776
+ }
1777
+ return false;
1778
+ }
1779
+ function shouldSkipTopLevelVersionToken(token) {
1780
+ return matchesLongFlagValue(token, TOP_LEVEL_VERSION_VALUE_FLAG_VALUES) || TOP_LEVEL_VERSION_BOOLEAN_FLAGS.has(token);
1781
+ }
1782
+ function topLevelVersionTokenDecision(token) {
1783
+ if (token === "--version" || token === "-V") return "version";
1784
+ if (!token.startsWith("-") || token === "-") return "stop";
1785
+ if (TOP_LEVEL_VERSION_VALUE_FLAGS.has(token)) return "skip-next";
1786
+ if (shouldSkipTopLevelVersionToken(token)) return "skip";
1787
+ return "stop";
1788
+ }
1789
+ function isTopLevelVersionRequest(argv) {
1790
+ for (let index = 0; index < argv.length; index += 1) {
1791
+ const token = argv[index];
1792
+ if (token === "--") return false;
1793
+ const decision = topLevelVersionTokenDecision(token);
1794
+ if (decision === "version") return true;
1795
+ if (decision === "stop") return false;
1796
+ if (decision === "skip-next") index += 1;
1515
1797
  }
1516
1798
  return false;
1517
1799
  }
@@ -1541,43 +1823,69 @@ async function emitRequestedError(error, normalized, outputPolicy) {
1541
1823
  async function runWithOutputPolicy(_outputPolicy, run) {
1542
1824
  return await run();
1543
1825
  }
1544
- async function main(argv = process.argv) {
1826
+ async function handleQueueOwnerCommand(argv) {
1545
1827
  installPerfMetricsCapture({
1546
1828
  argv: argv.slice(2),
1547
1829
  role: argv[2] === "__queue-owner" ? "queue_owner" : "cli"
1548
1830
  });
1549
- if (argv.includes("--version") || argv.includes("-V")) {
1550
- process.stdout.write(`${getAcpxVersion()}\n`);
1551
- return;
1552
- }
1553
- if (argv[2] === "__queue-owner") try {
1831
+ if (argv[2] !== "__queue-owner") return false;
1832
+ try {
1554
1833
  await runQueueOwnerFromEnv(process.env);
1555
- return;
1834
+ return true;
1556
1835
  } catch (error) {
1557
1836
  const message = error instanceof Error ? error.message : String(error);
1558
1837
  process.stderr.write(`[acpx] queue owner failed: ${message}\n`);
1559
1838
  process.exit(EXIT_CODES.ERROR);
1839
+ return true;
1560
1840
  }
1561
- if (shouldMaybeHandleSkillflag(argv)) {
1562
- const { findSkillsRoot, maybeHandleSkillflag } = await loadSkillflagModule();
1563
- await maybeHandleSkillflag(argv, {
1564
- skillsRoot: findSkillsRoot(import.meta.url),
1565
- includeBundledSkill: false
1841
+ }
1842
+ async function maybeHandleSkillflag(argv) {
1843
+ if (!shouldMaybeHandleSkillflag(argv)) return;
1844
+ const { findSkillsRoot, maybeHandleSkillflag } = await loadSkillflagModule();
1845
+ await maybeHandleSkillflag(argv, {
1846
+ skillsRoot: findSkillsRoot(import.meta.url),
1847
+ includeBundledSkill: false
1848
+ });
1849
+ }
1850
+ function createProgram(requestedJsonStrict) {
1851
+ const program = new Command();
1852
+ program.name("acpx").description("Headless CLI client for the Agent Client Protocol").version(getAcpxVersion()).enablePositionalOptions().showHelpAfterError();
1853
+ if (requestedJsonStrict) program.configureOutput({
1854
+ writeOut: () => {},
1855
+ writeErr: () => {}
1856
+ });
1857
+ return program;
1858
+ }
1859
+ async function handleProgramParseError(error, requestedOutputPolicy) {
1860
+ if (error instanceof CommanderError) {
1861
+ if (error.code === "commander.helpDisplayed" || error.code === "commander.version") process.exit(EXIT_CODES.SUCCESS);
1862
+ const normalized = normalizeOutputError(error, {
1863
+ defaultCode: "USAGE",
1864
+ origin: "cli"
1566
1865
  });
1866
+ await emitRequestedError(error, normalized, requestedOutputPolicy);
1867
+ process.exit(exitCodeForOutputErrorCode(normalized.code));
1567
1868
  }
1869
+ if (error instanceof InterruptedError) process.exit(EXIT_CODES.INTERRUPTED);
1870
+ const normalized = normalizeOutputError(error, { origin: "cli" });
1871
+ await emitRequestedError(error, normalized, requestedOutputPolicy);
1872
+ process.exit(exitCodeForOutputErrorCode(normalized.code));
1873
+ }
1874
+ async function main(argv = process.argv) {
1568
1875
  const rawArgs = argv.slice(2);
1876
+ if (await handleQueueOwnerCommand(argv)) return;
1877
+ if (isTopLevelVersionRequest(rawArgs)) {
1878
+ process.stdout.write(`${getAcpxVersion()}\n`);
1879
+ return;
1880
+ }
1881
+ await maybeHandleSkillflag(argv);
1569
1882
  const config = await loadResolvedConfig(detectInitialCwd(rawArgs));
1570
1883
  const requestedJsonStrict = detectJsonStrict(rawArgs);
1571
1884
  const requestedOutputPolicy = {
1572
1885
  ...resolveOutputPolicy(detectRequestedOutputFormat(rawArgs, config.format), requestedJsonStrict),
1573
1886
  suppressReads: rawArgs.some((token) => token === "--suppress-reads")
1574
1887
  };
1575
- const program = new Command();
1576
- program.name("acpx").description("Headless CLI client for the Agent Client Protocol").version(getAcpxVersion()).enablePositionalOptions().showHelpAfterError();
1577
- if (requestedJsonStrict) program.configureOutput({
1578
- writeOut: () => {},
1579
- writeErr: () => {}
1580
- });
1888
+ const program = createProgram(requestedJsonStrict);
1581
1889
  addGlobalFlags(program);
1582
1890
  configurePublicCli({
1583
1891
  program,
@@ -1601,19 +1909,7 @@ async function main(argv = process.argv) {
1601
1909
  try {
1602
1910
  await program.parseAsync(argv);
1603
1911
  } catch (error) {
1604
- if (error instanceof CommanderError) {
1605
- if (error.code === "commander.helpDisplayed" || error.code === "commander.version") process.exit(EXIT_CODES.SUCCESS);
1606
- const normalized = normalizeOutputError(error, {
1607
- defaultCode: "USAGE",
1608
- origin: "cli"
1609
- });
1610
- await emitRequestedError(error, normalized, requestedOutputPolicy);
1611
- process.exit(exitCodeForOutputErrorCode(normalized.code));
1612
- }
1613
- if (error instanceof InterruptedError) process.exit(EXIT_CODES.INTERRUPTED);
1614
- const normalized = normalizeOutputError(error, { origin: "cli" });
1615
- await emitRequestedError(error, normalized, requestedOutputPolicy);
1616
- process.exit(exitCodeForOutputErrorCode(normalized.code));
1912
+ await handleProgramParseError(error, requestedOutputPolicy);
1617
1913
  }
1618
1914
  });
1619
1915
  } finally {
@@ -1628,10 +1924,6 @@ function installBrokenPipeHandler(stream) {
1628
1924
  throw error;
1629
1925
  });
1630
1926
  }
1631
- installBrokenPipeHandler(process.stdout);
1632
- installBrokenPipeHandler(process.stderr);
1633
- const queueOwnerArgOverride = buildQueueOwnerArgOverride(fileURLToPath(import.meta.url));
1634
- if (queueOwnerArgOverride) process.env.ACPX_QUEUE_OWNER_ARGS ??= queueOwnerArgOverride;
1635
1927
  function isCliEntrypoint(argv) {
1636
1928
  const entry = argv[1];
1637
1929
  if (!entry) return false;
@@ -1642,7 +1934,13 @@ function isCliEntrypoint(argv) {
1642
1934
  return false;
1643
1935
  }
1644
1936
  }
1645
- if (isCliEntrypoint(process.argv)) main(process.argv);
1937
+ if (isCliEntrypoint(process.argv)) {
1938
+ installBrokenPipeHandler(process.stdout);
1939
+ installBrokenPipeHandler(process.stderr);
1940
+ const queueOwnerArgOverride = buildQueueOwnerArgOverride(fileURLToPath(import.meta.url));
1941
+ if (queueOwnerArgOverride) process.env.ACPX_QUEUE_OWNER_ARGS ??= queueOwnerArgOverride;
1942
+ main(process.argv);
1943
+ }
1646
1944
  //#endregion
1647
1945
  export { formatPromptSessionBannerLine, parseAllowedTools, parseMaxTurns, parseTtlSeconds };
1648
1946