acpx 0.7.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 (50) hide show
  1. package/README.md +14 -6
  2. package/dist/{cli-T-Z-9x6a.js → cli-Bf3yjqzE.js} +35 -10
  3. package/dist/cli-Bf3yjqzE.js.map +1 -0
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +724 -241
  7. package/dist/cli.js.map +1 -1
  8. package/dist/{client-COPilhO_.d.ts → client-BssohYqM.d.ts} +35 -4
  9. package/dist/client-BssohYqM.d.ts.map +1 -0
  10. package/dist/flags-C-rwARqg.js +260 -0
  11. package/dist/flags-C-rwARqg.js.map +1 -0
  12. package/dist/{flows-CF8w1rPI.js → flows-WLs26_5Y.js} +405 -337
  13. package/dist/flows-WLs26_5Y.js.map +1 -0
  14. package/dist/flows.d.ts +23 -2
  15. package/dist/flows.d.ts.map +1 -1
  16. package/dist/flows.js +1 -1
  17. package/dist/{prompt-turn-CVPMWdj1.js → live-checkpoint-D5d-K9s1.js} +2487 -609
  18. package/dist/live-checkpoint-D5d-K9s1.js.map +1 -0
  19. package/dist/output-DPg20dvn.js +4146 -0
  20. package/dist/output-DPg20dvn.js.map +1 -0
  21. package/dist/runtime.d.ts +56 -4
  22. package/dist/runtime.d.ts.map +1 -1
  23. package/dist/runtime.js +676 -393
  24. package/dist/runtime.js.map +1 -1
  25. package/dist/{types-CVBeQyi3.d.ts → session-options-CFudjdkU.d.ts} +62 -3
  26. package/dist/session-options-CFudjdkU.d.ts.map +1 -0
  27. package/package.json +30 -25
  28. package/skills/acpx/SKILL.md +211 -13
  29. package/dist/cli-T-Z-9x6a.js.map +0 -1
  30. package/dist/client-COPilhO_.d.ts.map +0 -1
  31. package/dist/flags-Dj-IXgo9.js +0 -163
  32. package/dist/flags-Dj-IXgo9.js.map +0 -1
  33. package/dist/flows-CF8w1rPI.js.map +0 -1
  34. package/dist/ipc-ABXlXzGP.js +0 -1290
  35. package/dist/ipc-ABXlXzGP.js.map +0 -1
  36. package/dist/jsonrpc-DSxh2w5R.js +0 -68
  37. package/dist/jsonrpc-DSxh2w5R.js.map +0 -1
  38. package/dist/output-DmHvT8vm.js +0 -807
  39. package/dist/output-DmHvT8vm.js.map +0 -1
  40. package/dist/perf-metrics-C2pXfxvR.js +0 -598
  41. package/dist/perf-metrics-C2pXfxvR.js.map +0 -1
  42. package/dist/prompt-turn-CVPMWdj1.js.map +0 -1
  43. package/dist/render-N5YwotCy.js +0 -172
  44. package/dist/render-N5YwotCy.js.map +0 -1
  45. package/dist/rolldown-runtime-CiIaOW0V.js +0 -13
  46. package/dist/session-CDaQe6BH.js +0 -1538
  47. package/dist/session-CDaQe6BH.js.map +0 -1
  48. package/dist/session-options-pCbHn_n7.d.ts +0 -13
  49. package/dist/session-options-pCbHn_n7.d.ts.map +0 -1
  50. package/dist/types-CVBeQyi3.d.ts.map +0 -1
package/dist/cli.js CHANGED
@@ -1,11 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { A as OUTPUT_FORMATS, E as EXIT_CODES, _ as exitCodeForOutputErrorCode, d as PromptInputValidationError, g as textPrompt, m as parsePromptSource, p as mergePromptSourceWithText, x as normalizeOutputError } from "./perf-metrics-C2pXfxvR.js";
3
- import { D as findGitRepositoryRoot, K as InterruptedError, O as findSession, Q as normalizeAgentName, X as DEFAULT_AGENT_NAME, Z as listBuiltInAgents, k as findSessionByDirectoryWalk } from "./prompt-turn-CVPMWdj1.js";
4
- import { a as buildQueueOwnerArgOverride, n as runSessionQueueOwner, o as flushPerfMetricsCapture, s as installPerfMetricsCapture } from "./session-CDaQe6BH.js";
5
- import { c as probeQueueOwnerHealth } from "./ipc-ABXlXzGP.js";
6
- import { _ as resolvePermissionMode, c as parseHistoryLimit, d as parsePruneBeforeDate, f as parseSessionName, g as resolveOutputPolicy, h as resolveGlobalFlags, i as addSessionOption, l as parseMaxTurns, m as resolveAgentInvocation, n as addPromptInputOption, o as parseAllowedTools, p as parseTtlSeconds, r as addSessionNameOption, s as parseDaysOlderThan, t as addGlobalFlags, u as parseNonEmptyValue, v as resolveSessionNameFromFlags } from "./flags-Dj-IXgo9.js";
7
- import { i as emitJsonResult, n as formatPromptSessionBannerLine, t as agentSessionIdPayload } from "./render-N5YwotCy.js";
8
- import { n as getTextErrorRemediationHints, t as createOutputFormatter } from "./output-DmHvT8vm.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";
9
5
  import { readFileSync, realpathSync } from "node:fs";
10
6
  import { fileURLToPath, pathToFileURL } from "node:url";
11
7
  import path from "node:path";
@@ -38,7 +34,7 @@ Examples:
38
34
  acpx codex exec "what does this repo do"
39
35
  acpx codex cancel
40
36
  acpx codex set-mode plan
41
- acpx codex set thought_level high
37
+ acpx codex set model 'gpt-5.2[high]'
42
38
  acpx codex -s backend "fix the API"
43
39
  acpx codex sessions
44
40
  acpx codex sessions new --name backend
@@ -53,9 +49,15 @@ Examples:
53
49
  }
54
50
  //#endregion
55
51
  //#region src/acp/codex-compat.ts
56
- function isCodexInvocation(agentName, agentCommand) {
57
- if (agentName === "codex") return true;
58
- return /\bcodex-acp\b/u.test(agentCommand);
52
+ function isLegacyZedCodexAcpInvocation(agentCommand) {
53
+ return /@zed-industries\/codex-acp\b/u.test(agentCommand);
54
+ }
55
+ //#endregion
56
+ //#region src/cli/output/json-output.ts
57
+ function emitJsonResult(format, payload) {
58
+ if (format !== "json") return false;
59
+ process.stdout.write(`${JSON.stringify(payload)}\n`);
60
+ return true;
59
61
  }
60
62
  //#endregion
61
63
  //#region src/cli/command-handlers.ts
@@ -69,15 +71,15 @@ let sessionModulePromise;
69
71
  let outputModulePromise;
70
72
  let outputRenderModulePromise;
71
73
  function loadSessionModule() {
72
- sessionModulePromise ??= import("./session-CDaQe6BH.js").then((n) => n.t);
74
+ sessionModulePromise ??= import("./output-DPg20dvn.js").then((n) => n.i);
73
75
  return sessionModulePromise;
74
76
  }
75
77
  function loadOutputModule() {
76
- outputModulePromise ??= import("./output-DmHvT8vm.js").then((n) => n.r);
78
+ outputModulePromise ??= import("./output-DPg20dvn.js").then((n) => n.r);
77
79
  return outputModulePromise;
78
80
  }
79
81
  function loadOutputRenderModule() {
80
- outputRenderModulePromise ??= import("./render-N5YwotCy.js").then((n) => n.r);
82
+ outputRenderModulePromise ??= Promise.resolve().then(() => render_exports);
81
83
  return outputRenderModulePromise;
82
84
  }
83
85
  async function readPromptInputFromStdin() {
@@ -87,11 +89,7 @@ async function readPromptInputFromStdin() {
87
89
  }
88
90
  async function readPrompt(promptParts, filePath, cwd) {
89
91
  try {
90
- if (filePath) {
91
- const prompt = mergePromptSourceWithText(filePath === "-" ? await readPromptInputFromStdin() : await fs$1.readFile(path.resolve(cwd, filePath), "utf8"), promptParts.join(" "));
92
- if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
93
- return prompt;
94
- }
92
+ if (filePath) return await readPromptFromFile(filePath, cwd, promptParts);
95
93
  const joined = promptParts.join(" ").trim();
96
94
  if (joined.length > 0) return textPrompt(joined);
97
95
  if (process.stdin.isTTY) throw new InvalidArgumentError("Prompt is required (pass as argument, --file, or pipe via stdin)");
@@ -103,13 +101,18 @@ async function readPrompt(promptParts, filePath, cwd) {
103
101
  throw error;
104
102
  }
105
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
+ }
106
109
  function applyPermissionExitCode(result) {
107
110
  const stats = result.permissionStats;
108
111
  const deniedOrCancelled = stats.denied + stats.cancelled;
109
112
  if (stats.requested > 0 && stats.approved === 0 && deniedOrCancelled > 0) process.exitCode = EXIT_CODES.PERMISSION_DENIED;
110
113
  }
111
114
  function resolveCompatibleConfigId(agent, configId) {
112
- if (isCodexInvocation(agent.agentName, agent.agentCommand) && configId === "thought_level") return "reasoning_effort";
115
+ if (isLegacyZedCodexAcpInvocation(agent.agentCommand) && configId === "thought_level") return "reasoning_effort";
113
116
  return configId;
114
117
  }
115
118
  function resolveRequestedOutputPolicy(globalFlags) {
@@ -126,6 +129,13 @@ function sessionOptionsFromGlobalFlags(globalFlags) {
126
129
  systemPrompt: globalFlags.systemPrompt
127
130
  };
128
131
  }
132
+ async function resolvePermissionPolicyFromFlags(globalFlags) {
133
+ try {
134
+ return await loadPermissionPolicySpec(globalFlags.permissionPolicy, globalFlags.cwd);
135
+ } catch (error) {
136
+ throw new InvalidArgumentError(`Invalid permission policy: ${error instanceof Error ? error.message : String(error)}`);
137
+ }
138
+ }
129
139
  function buildSessionStartOptions(params) {
130
140
  return {
131
141
  agentCommand: params.agent.agentCommand,
@@ -135,6 +145,7 @@ function buildSessionStartOptions(params) {
135
145
  mcpServers: params.config.mcpServers,
136
146
  permissionMode: params.permissionMode,
137
147
  nonInteractivePermissions: params.globalFlags.nonInteractivePermissions,
148
+ permissionPolicy: params.permissionPolicy,
138
149
  authCredentials: params.config.auth,
139
150
  authPolicy: params.globalFlags.authPolicy,
140
151
  terminal: params.globalFlags.terminal,
@@ -143,6 +154,14 @@ function buildSessionStartOptions(params) {
143
154
  sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags)
144
155
  };
145
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
+ }
146
165
  function missingScopedSessionMessage(agent, sessionName) {
147
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}`;
148
167
  }
@@ -171,6 +190,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
171
190
  const globalFlags = resolveGlobalFlags(command, config);
172
191
  const outputPolicy = resolveRequestedOutputPolicy(globalFlags);
173
192
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
193
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
174
194
  const prompt = await readPrompt(promptParts, flags.file, globalFlags.cwd);
175
195
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
176
196
  const [{ createOutputFormatter }, { printPromptSessionBanner, printQueuedPromptByFormat }, { sendSession }] = await Promise.all([
@@ -190,6 +210,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
190
210
  mcpServers: config.mcpServers,
191
211
  permissionMode,
192
212
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
213
+ permissionPolicy,
193
214
  authCredentials: config.auth,
194
215
  authPolicy: globalFlags.authPolicy,
195
216
  terminal: globalFlags.terminal,
@@ -214,7 +235,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
214
235
  return;
215
236
  }
216
237
  applyPermissionExitCode(result);
217
- 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`);
218
239
  }
219
240
  async function handleExec(explicitAgentName, promptParts, flags, command, config) {
220
241
  if (config.disableExec) {
@@ -233,6 +254,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
233
254
  const globalFlags = resolveGlobalFlags(command, config);
234
255
  const outputPolicy = resolveRequestedOutputPolicy(globalFlags);
235
256
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
257
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
236
258
  const prompt = await readPrompt(promptParts, flags.file, globalFlags.cwd);
237
259
  const [{ createOutputFormatter }, { runOnce }] = await Promise.all([loadOutputModule(), loadSessionModule()]);
238
260
  const outputFormatter = createOutputFormatter(outputPolicy.format, { suppressReads: outputPolicy.suppressReads });
@@ -244,6 +266,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
244
266
  mcpServers: config.mcpServers,
245
267
  permissionMode,
246
268
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
269
+ permissionPolicy,
247
270
  authCredentials: config.auth,
248
271
  authPolicy: globalFlags.authPolicy,
249
272
  terminal: globalFlags.terminal,
@@ -341,7 +364,7 @@ async function handleSetMode(explicitAgentName, modeId, flags, command, config)
341
364
  timeoutMs: globalFlags.timeout,
342
365
  verbose: globalFlags.verbose
343
366
  });
344
- 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`);
345
368
  printSetModeResultByFormat(modeId, result, globalFlags.format);
346
369
  }
347
370
  async function handleSetModel(explicitAgentName, modelId, flags, command, config) {
@@ -359,7 +382,7 @@ async function handleSetModel(explicitAgentName, modelId, flags, command, config
359
382
  timeoutMs: globalFlags.timeout,
360
383
  verbose: globalFlags.verbose
361
384
  });
362
- 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`);
363
386
  printSetModelResultByFormat(modelId, result, globalFlags.format);
364
387
  }
365
388
  async function handleSetConfigOption(explicitAgentName, configId, value, flags, command, config) {
@@ -383,14 +406,50 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
383
406
  timeoutMs: globalFlags.timeout,
384
407
  verbose: globalFlags.verbose
385
408
  });
386
- 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`);
387
410
  printSetConfigOptionResultByFormat(configId, value, result, globalFlags.format);
388
411
  }
389
- 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) {
390
438
  const globalFlags = resolveGlobalFlags(command, config);
391
439
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
392
- const [{ listSessionsForAgent }, { printSessionsByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
393
- 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);
394
453
  }
395
454
  async function handleSessionsClose(explicitAgentName, sessionName, command, config) {
396
455
  const globalFlags = resolveGlobalFlags(command, config);
@@ -407,6 +466,7 @@ async function handleSessionsClose(explicitAgentName, sessionName, command, conf
407
466
  async function handleSessionsNew(explicitAgentName, flags, command, config) {
408
467
  const globalFlags = resolveGlobalFlags(command, config);
409
468
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
469
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
410
470
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
411
471
  const [{ createSession, closeSession }, { printCreatedSessionBanner, printNewSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
412
472
  const replaced = await findSession({
@@ -423,7 +483,8 @@ async function handleSessionsNew(explicitAgentName, flags, command, config) {
423
483
  flags,
424
484
  globalFlags,
425
485
  config,
426
- permissionMode
486
+ permissionMode,
487
+ permissionPolicy
427
488
  }));
428
489
  printCreatedSessionBanner(created, agent.agentName, globalFlags.format, globalFlags.jsonStrict);
429
490
  if (globalFlags.verbose) {
@@ -435,6 +496,7 @@ async function handleSessionsNew(explicitAgentName, flags, command, config) {
435
496
  async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
436
497
  const globalFlags = resolveGlobalFlags(command, config);
437
498
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
499
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
438
500
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
439
501
  const [{ ensureSession }, { printCreatedSessionBanner, printEnsuredSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
440
502
  const result = await ensureSession(buildSessionStartOptions({
@@ -442,7 +504,8 @@ async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
442
504
  flags,
443
505
  globalFlags,
444
506
  config,
445
- permissionMode
507
+ permissionMode,
508
+ permissionPolicy
446
509
  }));
447
510
  if (result.created) printCreatedSessionBanner(result.record, agent.agentName, globalFlags.format, globalFlags.jsonStrict);
448
511
  printEnsuredSessionByFormat(result.record, result.created, globalFlags.format);
@@ -451,6 +514,7 @@ function userContentToText(content) {
451
514
  if ("Text" in content) return content.Text;
452
515
  if ("Mention" in content) return content.Mention.content;
453
516
  if ("Image" in content) return content.Image.source || "[image]";
517
+ if ("Audio" in content) return `[audio] ${content.Audio.mime_type || "audio"}`;
454
518
  return "";
455
519
  }
456
520
  function agentContentToText(content) {
@@ -495,24 +559,32 @@ function printSessionDetailsByFormat(record, format) {
495
559
  process.stdout.write(`${record.acpxRecordId}\n`);
496
560
  return;
497
561
  }
498
- process.stdout.write(`id: ${record.acpxRecordId}\n`);
499
- process.stdout.write(`sessionId: ${record.acpSessionId}\n`);
500
- process.stdout.write(`agentSessionId: ${record.agentSessionId ?? "-"}\n`);
501
- process.stdout.write(`agent: ${record.agentCommand}\n`);
502
- process.stdout.write(`cwd: ${record.cwd}\n`);
503
- process.stdout.write(`name: ${record.name ?? "-"}\n`);
504
- process.stdout.write(`created: ${record.createdAt}\n`);
505
- process.stdout.write(`lastActivity: ${record.lastUsedAt}\n`);
506
- process.stdout.write(`lastPrompt: ${record.lastPromptAt ?? "-"}\n`);
507
- process.stdout.write(`closed: ${record.closed ? "yes" : "no"}\n`);
508
- process.stdout.write(`closedAt: ${record.closedAt ?? "-"}\n`);
509
- process.stdout.write(`pid: ${record.pid ?? "-"}\n`);
510
- process.stdout.write(`agentStartedAt: ${record.agentStartedAt ?? "-"}\n`);
511
- process.stdout.write(`lastExitCode: ${record.lastAgentExitCode ?? "-"}\n`);
512
- process.stdout.write(`lastExitSignal: ${record.lastAgentExitSignal ?? "-"}\n`);
513
- process.stdout.write(`lastExitAt: ${record.lastAgentExitAt ?? "-"}\n`);
514
- process.stdout.write(`disconnectReason: ${record.lastAgentDisconnectReason ?? "-"}\n`);
515
- 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);
516
588
  }
517
589
  function printSessionHistoryByFormat(record, limit, format) {
518
590
  const history = conversationHistoryEntries(record);
@@ -617,38 +689,38 @@ function parseMeta(value, path) {
617
689
  if (!asRecord$1(value)) throw new Error(`Invalid ${path}: expected object or null`);
618
690
  return value;
619
691
  }
620
- function parseServer(rawServer, path) {
621
- const serverRecord = asRecord$1(rawServer);
622
- if (!serverRecord) throw new Error(`Invalid ${path}: expected object`);
623
- const name = parseNonEmptyString(serverRecord.name, `${path}.name`);
624
- const _meta = parseMeta(serverRecord._meta, `${path}._meta`);
625
- const rawType = serverRecord.type;
626
- let typeValue;
627
- if (rawType === void 0) typeValue = "stdio";
628
- else {
629
- const parsedType = parseNonEmptyString(rawType, `${path}.type`);
630
- if (parsedType !== "http" && parsedType !== "sse" && parsedType !== "stdio") throw new Error(`Invalid ${path}.type: expected http, sse, or stdio`);
631
- typeValue = parsedType;
632
- }
633
- if (typeValue === "http" || typeValue === "sse") {
634
- const url = parseNonEmptyString(serverRecord.url, `${path}.url`);
635
- const headers = parseHeaders(serverRecord.headers, `${path}.headers`);
636
- return {
637
- type: typeValue,
638
- name,
639
- url,
640
- headers,
641
- _meta
642
- };
643
- }
644
- 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 {
645
709
  name,
646
710
  command: parseNonEmptyString(serverRecord.command, `${path}.command`),
647
711
  args: parseArgs(serverRecord.args, `${path}.args`),
648
712
  env: parseEnv(serverRecord.env, `${path}.env`),
649
713
  _meta
650
714
  };
651
- 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);
652
724
  }
653
725
  function parseMcpServers(value, sourcePath, fieldName = "mcpServers") {
654
726
  const fieldPath = `${fieldName} in ${sourcePath}`;
@@ -809,35 +881,13 @@ async function loadResolvedConfig(cwd) {
809
881
  const [globalResult, projectResult] = await Promise.all([readConfigFile(globalPath), readConfigFile(projectPath)]);
810
882
  const globalConfig = globalResult.config;
811
883
  const projectConfig = projectResult.config;
812
- const defaultAgent = parseDefaultAgent(projectConfig?.defaultAgent, projectPath) ?? parseDefaultAgent(globalConfig?.defaultAgent, globalPath) ?? "codex";
813
- const defaultPermissions = parsePermissionMode(projectConfig?.defaultPermissions, projectPath) ?? parsePermissionMode(globalConfig?.defaultPermissions, globalPath) ?? DEFAULT_PERMISSION_MODE;
814
- const nonInteractivePermissions = parseNonInteractivePermissionPolicy(projectConfig?.nonInteractivePermissions, projectPath) ?? parseNonInteractivePermissionPolicy(globalConfig?.nonInteractivePermissions, globalPath) ?? DEFAULT_NON_INTERACTIVE_PERMISSION_POLICY;
815
- const authPolicy = parseAuthPolicy(projectConfig?.authPolicy, projectPath) ?? parseAuthPolicy(globalConfig?.authPolicy, globalPath) ?? DEFAULT_AUTH_POLICY;
816
- const ttlMs = parseTtlMs(projectConfig?.ttl, projectPath) ?? parseTtlMs(globalConfig?.ttl, globalPath) ?? DEFAULT_TTL_MS;
817
- const timeoutConfiguredInProject = projectConfig != null && Object.prototype.hasOwnProperty.call(projectConfig, "timeout");
818
- const timeoutConfiguredInGlobal = globalConfig != null && Object.prototype.hasOwnProperty.call(globalConfig, "timeout");
819
- let timeoutMs = DEFAULT_TIMEOUT_MS;
820
- if (timeoutConfiguredInProject) timeoutMs = parseTimeoutMs(projectConfig?.timeout, projectPath);
821
- else if (timeoutConfiguredInGlobal) timeoutMs = parseTimeoutMs(globalConfig?.timeout, globalPath);
822
- const format = parseOutputFormat(projectConfig?.format, projectPath) ?? parseOutputFormat(globalConfig?.format, globalPath) ?? DEFAULT_OUTPUT_FORMAT;
823
- const queueMaxDepth = parseQueueMaxDepth(projectConfig?.queueMaxDepth, projectPath) ?? parseQueueMaxDepth(globalConfig?.queueMaxDepth, globalPath) ?? DEFAULT_QUEUE_MAX_DEPTH;
884
+ const scalar = resolveScalarConfigValues(projectConfig, projectPath, globalConfig, globalPath);
824
885
  const agents = mergeAgents(parseAgents(globalConfig?.agents, globalPath), parseAgents(projectConfig?.agents, projectPath));
825
886
  const auth = mergeAuth(parseAuth(globalConfig?.auth, globalPath), parseAuth(projectConfig?.auth, projectPath));
826
- const mcpServersConfiguredInProject = projectConfig != null && Object.prototype.hasOwnProperty.call(projectConfig, "mcpServers");
827
- const mcpServersConfiguredInGlobal = globalConfig != null && Object.prototype.hasOwnProperty.call(globalConfig, "mcpServers");
828
- let mcpServers = [];
829
- if (mcpServersConfiguredInProject) mcpServers = parseMcpServers(projectConfig?.mcpServers, projectPath);
830
- else if (mcpServersConfiguredInGlobal) mcpServers = parseMcpServers(globalConfig?.mcpServers, globalPath);
831
- 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);
832
889
  return {
833
- defaultAgent,
834
- defaultPermissions,
835
- nonInteractivePermissions,
836
- authPolicy,
837
- ttlMs,
838
- timeoutMs,
839
- queueMaxDepth,
840
- format,
890
+ ...scalar,
841
891
  agents,
842
892
  auth,
843
893
  disableExec,
@@ -848,6 +898,55 @@ async function loadResolvedConfig(cwd) {
848
898
  hasProjectConfig: projectResult.exists
849
899
  };
850
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
+ }
851
950
  function toConfigDisplay(config) {
852
951
  const agents = {};
853
952
  for (const [name, command] of Object.entries(config.agents)) agents[name] = { command };
@@ -936,10 +1035,10 @@ async function handleConfigInit(command, config) {
936
1035
  }
937
1036
  function registerConfigCommand(program, config) {
938
1037
  const configCommand = program.command("config").description("Inspect and initialize acpx configuration");
939
- configCommand.command("show").description("Show resolved config").action(async function() {
1038
+ configCommand.command("show").description("Show resolved config").option("--format <fmt>", "Output format: text, json, quiet", parseOutputFormat$1).action(async function() {
940
1039
  await handleConfigShow(this, config);
941
1040
  });
942
- configCommand.command("init").description("Create global config template").action(async function() {
1041
+ configCommand.command("init").description("Create global config template").option("--format <fmt>", "Output format: text, json, quiet", parseOutputFormat$1).action(async function() {
943
1042
  await handleConfigInit(this, config);
944
1043
  });
945
1044
  configCommand.action(async function() {
@@ -947,6 +1046,201 @@ function registerConfigCommand(program, config) {
947
1046
  });
948
1047
  }
949
1048
  //#endregion
1049
+ //#region src/cli/output/render.ts
1050
+ var render_exports = /* @__PURE__ */ __exportAll({
1051
+ agentSessionIdPayload: () => agentSessionIdPayload,
1052
+ formatPromptSessionBannerLine: () => formatPromptSessionBannerLine,
1053
+ printAgentSessionsByFormat: () => printAgentSessionsByFormat,
1054
+ printClosedSessionByFormat: () => printClosedSessionByFormat,
1055
+ printCreatedSessionBanner: () => printCreatedSessionBanner,
1056
+ printEnsuredSessionByFormat: () => printEnsuredSessionByFormat,
1057
+ printNewSessionByFormat: () => printNewSessionByFormat,
1058
+ printPromptSessionBanner: () => printPromptSessionBanner,
1059
+ printPruneResultByFormat: () => printPruneResultByFormat,
1060
+ printQueuedPromptByFormat: () => printQueuedPromptByFormat,
1061
+ printSessionsByFormat: () => printSessionsByFormat
1062
+ });
1063
+ function formatSessionLabel(record) {
1064
+ return record.name ?? "cwd";
1065
+ }
1066
+ function formatRoutedFrom(sessionCwd, currentCwd) {
1067
+ const relative = path.relative(sessionCwd, currentCwd);
1068
+ if (!relative || relative === ".") return;
1069
+ return relative.startsWith(".") ? relative : `.${path.sep}${relative}`;
1070
+ }
1071
+ async function resolveSessionConnectionStatus(record) {
1072
+ return (await probeQueueOwnerHealth(record.acpxRecordId)).healthy ? "connected" : "needs reconnect";
1073
+ }
1074
+ function printSessionsByFormat(sessions, format) {
1075
+ if (format === "json") {
1076
+ process.stdout.write(`${JSON.stringify(sessions)}\n`);
1077
+ return;
1078
+ }
1079
+ if (format === "quiet") {
1080
+ printQuietSessions(sessions);
1081
+ return;
1082
+ }
1083
+ if (sessions.length === 0) {
1084
+ process.stdout.write("No sessions\n");
1085
+ return;
1086
+ }
1087
+ for (const session of sessions) {
1088
+ const closedMarker = session.closed ? " [closed]" : "";
1089
+ process.stdout.write(`${session.acpxRecordId}${closedMarker}\t${session.name ?? "-"}\t${session.cwd}\t${session.lastUsedAt}\n`);
1090
+ }
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
+ }
1122
+ function printClosedSessionByFormat(record, format) {
1123
+ if (emitJsonResult(format, {
1124
+ action: "session_closed",
1125
+ acpxRecordId: record.acpxRecordId,
1126
+ acpxSessionId: record.acpSessionId,
1127
+ agentSessionId: record.agentSessionId
1128
+ })) return;
1129
+ if (format === "quiet") return;
1130
+ process.stdout.write(`${record.acpxRecordId}\n`);
1131
+ }
1132
+ function printNewSessionByFormat(record, replaced, format) {
1133
+ if (emitJsonResult(format, {
1134
+ action: "session_ensured",
1135
+ created: true,
1136
+ acpxRecordId: record.acpxRecordId,
1137
+ acpxSessionId: record.acpSessionId,
1138
+ agentSessionId: record.agentSessionId,
1139
+ name: record.name,
1140
+ replacedSessionId: replaced?.acpxRecordId
1141
+ })) return;
1142
+ if (format === "quiet") {
1143
+ process.stdout.write(`${record.acpxRecordId}\n`);
1144
+ return;
1145
+ }
1146
+ if (replaced) {
1147
+ process.stdout.write(`${record.acpxRecordId}\t(replaced ${replaced.acpxRecordId})\n`);
1148
+ return;
1149
+ }
1150
+ process.stdout.write(`${record.acpxRecordId}\n`);
1151
+ }
1152
+ function printEnsuredSessionByFormat(record, created, format) {
1153
+ if (emitJsonResult(format, {
1154
+ action: "session_ensured",
1155
+ created,
1156
+ acpxRecordId: record.acpxRecordId,
1157
+ acpxSessionId: record.acpSessionId,
1158
+ agentSessionId: record.agentSessionId,
1159
+ name: record.name
1160
+ })) return;
1161
+ if (format === "quiet") {
1162
+ process.stdout.write(`${record.acpxRecordId}\n`);
1163
+ return;
1164
+ }
1165
+ const action = created ? "created" : "existing";
1166
+ process.stdout.write(`${record.acpxRecordId}\t(${action})\n`);
1167
+ }
1168
+ function printQueuedPromptByFormat(result, format) {
1169
+ if (emitJsonResult(format, {
1170
+ action: "prompt_queued",
1171
+ acpxRecordId: result.sessionId,
1172
+ requestId: result.requestId
1173
+ })) return;
1174
+ if (format === "quiet") return;
1175
+ process.stdout.write(`[queued] ${result.requestId}\n`);
1176
+ }
1177
+ function formatPromptSessionBannerLine(record, currentCwd, connectionStatus = "needs reconnect") {
1178
+ const label = formatSessionLabel(record);
1179
+ const normalizedSessionCwd = path.resolve(record.cwd);
1180
+ const normalizedCurrentCwd = path.resolve(currentCwd);
1181
+ const routedFrom = normalizedSessionCwd === normalizedCurrentCwd ? void 0 : formatRoutedFrom(normalizedSessionCwd, normalizedCurrentCwd);
1182
+ const status = connectionStatus;
1183
+ if (routedFrom) return `[acpx] session ${label} (${record.acpxRecordId}) · ${normalizedSessionCwd} (routed from ${routedFrom}) · agent ${status}`;
1184
+ return `[acpx] session ${label} (${record.acpxRecordId}) · ${normalizedSessionCwd} · agent ${status}`;
1185
+ }
1186
+ async function printPromptSessionBanner(record, currentCwd, format, jsonStrict = false) {
1187
+ if (format === "quiet" || jsonStrict && format === "json") return;
1188
+ const status = await resolveSessionConnectionStatus(record);
1189
+ process.stderr.write(`${formatPromptSessionBannerLine(record, currentCwd, status)}\n`);
1190
+ }
1191
+ function printCreatedSessionBanner(record, agentName, format, jsonStrict = false) {
1192
+ if (format === "quiet" || jsonStrict && format === "json") return;
1193
+ const label = formatSessionLabel(record);
1194
+ process.stderr.write(`[acpx] created session ${label} (${record.acpxRecordId})\n`);
1195
+ process.stderr.write(`[acpx] agent: ${agentName}\n`);
1196
+ process.stderr.write(`[acpx] cwd: ${record.cwd}\n`);
1197
+ }
1198
+ function formatBytes(bytes) {
1199
+ if (bytes >= 1073741824) return `${(bytes / 1073741824).toFixed(1)} GB`;
1200
+ if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(1)} MB`;
1201
+ if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
1202
+ return `${bytes} B`;
1203
+ }
1204
+ function printPruneResultByFormat(result, format) {
1205
+ const count = result.pruned.length;
1206
+ if (emitPruneJsonResult(result, format, count)) return;
1207
+ if (format === "quiet") {
1208
+ printQuietPruneResult(result.pruned);
1209
+ return;
1210
+ }
1211
+ if (count === 0) {
1212
+ process.stdout.write(result.dryRun ? "[DRY RUN] No sessions to prune\n" : "No sessions pruned\n");
1213
+ return;
1214
+ }
1215
+ process.stdout.write(`${formatPruneSummaryLine(result, count)}\n`);
1216
+ for (const record of result.pruned) {
1217
+ const label = record.name ? ` (${record.name})` : "";
1218
+ process.stdout.write(` ${record.acpxRecordId}${label}\t${record.closedAt ?? record.lastUsedAt}\n`);
1219
+ }
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
+ }
1238
+ function agentSessionIdPayload(agentSessionId) {
1239
+ const normalized = normalizeRuntimeSessionId(agentSessionId);
1240
+ if (!normalized) return {};
1241
+ return { agentSessionId: normalized };
1242
+ }
1243
+ //#endregion
950
1244
  //#region src/cli/status-command.ts
951
1245
  function formatUptime(startedAt) {
952
1246
  if (!startedAt) return;
@@ -982,63 +1276,115 @@ async function handleStatus(explicitAgentName, flags, command, config) {
982
1276
  name: resolveSessionNameFromFlags(flags, command)
983
1277
  });
984
1278
  if (!record) {
985
- if (emitJsonResult(globalFlags.format, {
986
- action: "status_snapshot",
987
- status: "no-session",
988
- summary: "no active session"
989
- })) return;
990
- if (globalFlags.format === "quiet") {
991
- process.stdout.write("no-session\n");
992
- return;
993
- }
994
- process.stdout.write("session: -\n");
995
- process.stdout.write(`agent: ${agent.agentCommand}\n`);
996
- process.stdout.write("pid: -\n");
997
- process.stdout.write("status: no-session\n");
998
- process.stdout.write("model: -\n");
999
- process.stdout.write("mode: -\n");
1000
- process.stdout.write("uptime: -\n");
1001
- process.stdout.write("lastPromptTime: -\n");
1279
+ printMissingStatus(globalFlags.format, agent.agentCommand);
1280
+ return;
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");
1002
1292
  return;
1003
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) {
1004
1304
  const health = await probeQueueOwnerHealth(record.acpxRecordId);
1005
1305
  const statusState = resolveStatusState(record, health);
1006
- const running = statusState === "running";
1007
- const dead = statusState === "dead";
1008
- 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 {
1009
1320
  sessionId: record.acpxRecordId,
1010
1321
  agentCommand: record.agentCommand,
1011
- pid: health.pid ?? record.pid ?? null,
1322
+ pid: statusPid(health),
1012
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 {
1013
1336
  model: record.acpx?.current_model_id ?? null,
1014
1337
  mode: record.acpx?.current_mode_id ?? null,
1015
- availableModels: record.acpx?.available_models ?? null,
1016
- uptime: running ? formatUptime(record.agentStartedAt) ?? null : null,
1017
- lastPromptTime: record.lastPromptAt ?? null,
1018
- exitCode: running ? null : record.lastAgentExitCode ?? null,
1019
- signal: running ? null : record.lastAgentExitSignal ?? null,
1020
- ...agentSessionIdPayload(record.agentSessionId)
1338
+ availableModels: record.acpx?.available_models ?? null
1021
1339
  };
1022
- 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 = {
1023
1365
  action: "status_snapshot",
1024
1366
  status: running ? "alive" : statusState,
1025
- pid: payload.pid ?? void 0,
1026
1367
  summary: statusSummary(statusState),
1027
- model: payload.model ?? void 0,
1028
- mode: payload.mode ?? void 0,
1029
- availableModels: payload.availableModels ?? void 0,
1030
- uptime: payload.uptime ?? void 0,
1031
- lastPromptTime: payload.lastPromptTime ?? void 0,
1032
- exitCode: dead ? payload.exitCode ?? void 0 : void 0,
1033
- signal: dead ? payload.signal ?? void 0 : void 0,
1034
1368
  acpxRecordId: record.acpxRecordId,
1035
1369
  acpxSessionId: record.acpSessionId,
1036
1370
  agentSessionId: record.agentSessionId
1037
- })) return;
1038
- if (globalFlags.format === "quiet") {
1039
- process.stdout.write(`${payload.status}\n`);
1040
- 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);
1041
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) {
1042
1388
  process.stdout.write(`session: ${payload.sessionId}\n`);
1043
1389
  if ("agentSessionId" in payload) process.stdout.write(`agentSessionId: ${payload.agentSessionId}\n`);
1044
1390
  process.stdout.write(`agent: ${payload.agentCommand}\n`);
@@ -1048,10 +1394,11 @@ async function handleStatus(explicitAgentName, flags, command, config) {
1048
1394
  process.stdout.write(`mode: ${payload.mode ?? "-"}\n`);
1049
1395
  process.stdout.write(`uptime: ${payload.uptime ?? "-"}\n`);
1050
1396
  process.stdout.write(`lastPromptTime: ${payload.lastPromptTime ?? "-"}\n`);
1051
- if (dead) {
1052
- process.stdout.write(`exitCode: ${payload.exitCode ?? "-"}\n`);
1053
- process.stdout.write(`signal: ${payload.signal ?? "-"}\n`);
1054
- }
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`);
1055
1402
  }
1056
1403
  function registerStatusCommand(parent, explicitAgentName, config, description) {
1057
1404
  const statusCommand = parent.command("status").description(description);
@@ -1062,18 +1409,22 @@ function registerStatusCommand(parent, explicitAgentName, config, description) {
1062
1409
  }
1063
1410
  //#endregion
1064
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
+ }
1065
1415
  function registerSessionsCommand(parent, explicitAgentName, config) {
1066
1416
  const sessionsCommand = parent.command("sessions").description("List, ensure, create, or close sessions for this agent");
1067
- sessionsCommand.action(async function() {
1068
- await handleSessionsList(explicitAgentName, this, config);
1417
+ addSessionsListOptions(sessionsCommand);
1418
+ sessionsCommand.action(async function(flags) {
1419
+ await handleSessionsList(explicitAgentName, flags, this, config);
1069
1420
  });
1070
- sessionsCommand.command("list").description("List sessions").action(async function() {
1071
- await handleSessionsList(explicitAgentName, this, config);
1421
+ addSessionsListOptions(sessionsCommand.command("list")).description("List sessions").action(async function(flags) {
1422
+ await handleSessionsList(explicitAgentName, flags, this, config);
1072
1423
  });
1073
- sessionsCommand.command("new").description("Create a fresh session for current cwd").option("--name <name>", "Session name", parseSessionName).option("--resume-session <id>", "Resume existing ACP session id", (value) => parseNonEmptyValue("Resume session id", value)).action(async function(flags) {
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) {
1074
1425
  await handleSessionsNew(explicitAgentName, flags, this, config);
1075
1426
  });
1076
- sessionsCommand.command("ensure").description("Ensure a session exists for current cwd or ancestor").option("--name <name>", "Session name", parseSessionName).option("--resume-session <id>", "Resume existing ACP session id", (value) => parseNonEmptyValue("Resume session id", value)).action(async function(flags) {
1427
+ sessionsCommand.command("ensure").description("Ensure a session exists for current cwd or ancestor").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) {
1077
1428
  await handleSessionsEnsure(explicitAgentName, flags, this, config);
1078
1429
  });
1079
1430
  sessionsCommand.command("close").description("Close session for current cwd").argument("[name]", "Session name", parseSessionName).action(async function(name) {
@@ -1140,7 +1491,7 @@ function registerAgentCommand(program, agentName, config) {
1140
1491
  }
1141
1492
  function registerFlowCommand(program, config) {
1142
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) {
1143
- const { handleFlowRun } = await import("./cli-T-Z-9x6a.js");
1494
+ const { handleFlowRun } = await import("./cli-Bf3yjqzE.js");
1144
1495
  await handleFlowRun(file, flags, this, config);
1145
1496
  });
1146
1497
  }
@@ -1172,33 +1523,63 @@ function parseQueueOwnerPayload(raw) {
1172
1523
  sessionId: record.sessionId,
1173
1524
  permissionMode: record.permissionMode
1174
1525
  };
1526
+ assignQueueOwnerTransportOptions(options, record);
1527
+ assignQueueOwnerScalarOptions(options, record);
1528
+ assignQueueOwnerSessionOptions(options, record.sessionOptions);
1529
+ return options;
1530
+ }
1531
+ function assignQueueOwnerTransportOptions(options, record) {
1175
1532
  const parsedMcpServers = parseOptionalMcpServers(record.mcpServers, "queue owner payload");
1176
1533
  if (parsedMcpServers) options.mcpServers = parsedMcpServers;
1177
- if (typeof record.nonInteractivePermissions === "string") options.nonInteractivePermissions = record.nonInteractivePermissions === "deny" || record.nonInteractivePermissions === "fail" ? record.nonInteractivePermissions : void 0;
1178
1534
  if (record.authCredentials && typeof record.authCredentials === "object") {
1179
1535
  const entries = Object.entries(record.authCredentials).filter(([, value]) => typeof value === "string");
1180
1536
  options.authCredentials = Object.fromEntries(entries);
1181
1537
  }
1538
+ }
1539
+ function assignQueueOwnerScalarOptions(options, record) {
1540
+ if (record.nonInteractivePermissions === "deny" || record.nonInteractivePermissions === "fail") options.nonInteractivePermissions = record.nonInteractivePermissions;
1182
1541
  if (record.authPolicy === "skip" || record.authPolicy === "fail") options.authPolicy = record.authPolicy;
1183
- if (typeof record.terminal === "boolean") options.terminal = record.terminal;
1184
- if (typeof record.suppressSdkConsoleErrors === "boolean") options.suppressSdkConsoleErrors = record.suppressSdkConsoleErrors;
1185
- if (typeof record.verbose === "boolean") options.verbose = record.verbose;
1186
- if (typeof record.ttlMs === "number" && Number.isFinite(record.ttlMs)) options.ttlMs = record.ttlMs;
1187
- if (typeof record.maxQueueDepth === "number" && Number.isFinite(record.maxQueueDepth)) options.maxQueueDepth = Math.max(1, Math.round(record.maxQueueDepth));
1188
- if (typeof record.promptRetries === "number" && Number.isFinite(record.promptRetries)) options.promptRetries = Math.max(0, Math.round(record.promptRetries));
1189
- const sessionOpts = asRecord(record.sessionOptions);
1190
- if (sessionOpts) {
1191
- options.sessionOptions = {};
1192
- if (typeof sessionOpts.model === "string" && sessionOpts.model.trim().length > 0) options.sessionOptions.model = sessionOpts.model;
1193
- if (Array.isArray(sessionOpts.allowedTools)) options.sessionOptions.allowedTools = sessionOpts.allowedTools.filter((tool) => typeof tool === "string");
1194
- if (typeof sessionOpts.maxTurns === "number" && Number.isFinite(sessionOpts.maxTurns)) options.sessionOptions.maxTurns = Math.max(1, Math.round(sessionOpts.maxTurns));
1195
- if (typeof sessionOpts.systemPrompt === "string") options.sessionOptions.systemPrompt = sessionOpts.systemPrompt;
1196
- else {
1197
- const systemPrompt = asRecord(sessionOpts.systemPrompt);
1198
- if (typeof systemPrompt?.append === "string") options.sessionOptions.systemPrompt = { append: systemPrompt.append };
1199
- }
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;
1200
1580
  }
1201
- return options;
1581
+ const systemPrompt = asRecord(value);
1582
+ if (typeof systemPrompt?.append === "string") options.systemPrompt = { append: systemPrompt.append };
1202
1583
  }
1203
1584
  async function runQueueOwnerFromEnv(env) {
1204
1585
  const payload = env.ACPX_QUEUE_OWNER_PAYLOAD;
@@ -1233,13 +1614,16 @@ function resolveVersionFromAncestors(startDir) {
1233
1614
  }
1234
1615
  }
1235
1616
  function resolveAcpxVersion(params) {
1236
- const env = params?.env ?? process.env;
1237
- const envPackageName = parseVersion(env.npm_package_name);
1238
- const envVersion = parseVersion(env.npm_package_version);
1239
- if (envPackageName === "acpx" && envVersion) return envVersion;
1617
+ const envVersion = resolvePackageEnvVersion(params?.env ?? process.env);
1618
+ if (envVersion) return envVersion;
1240
1619
  if (params?.packageJsonPath) return readPackageVersion(params.packageJsonPath) ?? UNKNOWN_VERSION;
1241
1620
  return resolveVersionFromAncestors(MODULE_DIR) ?? UNKNOWN_VERSION;
1242
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
+ }
1243
1627
  function getAcpxVersion() {
1244
1628
  if (cachedVersion) return cachedVersion;
1245
1629
  cachedVersion = resolveAcpxVersion();
@@ -1259,6 +1643,36 @@ const TOP_LEVEL_VERBS = new Set([
1259
1643
  "config",
1260
1644
  "help"
1261
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);
1262
1676
  let skillflagModulePromise;
1263
1677
  function loadSkillflagModule() {
1264
1678
  skillflagModulePromise ??= import("skillflag");
@@ -1267,31 +1681,48 @@ function loadSkillflagModule() {
1267
1681
  function shouldMaybeHandleSkillflag(argv) {
1268
1682
  return argv.some((token) => token === "--skill" || token.startsWith("--skill="));
1269
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
+ }
1270
1718
  function detectAgentToken(argv) {
1271
1719
  let hasAgentOverride = false;
1272
1720
  for (let index = 0; index < argv.length; index += 1) {
1273
1721
  const token = argv[index];
1274
- if (token === "--") break;
1275
- if (!token.startsWith("-") || token === "-") return {
1276
- token,
1277
- hasAgentOverride
1278
- };
1279
- if (token === "--agent") {
1280
- hasAgentOverride = true;
1281
- index += 1;
1282
- continue;
1283
- }
1284
- if (token.startsWith("--agent=")) {
1285
- hasAgentOverride = true;
1286
- continue;
1287
- }
1288
- if (token === "--cwd" || token === "--auth-policy" || token === "--non-interactive-permissions" || token === "--format" || token === "--model" || token === "--allowed-tools" || token === "--max-turns" || token === "--timeout" || token === "--ttl" || token === "--file") {
1289
- index += 1;
1290
- continue;
1291
- }
1292
- if (token.startsWith("--cwd=") || token.startsWith("--auth-policy=") || token.startsWith("--non-interactive-permissions=") || 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;
1293
- if (token === "--approve-all" || token === "--approve-reads" || token === "--deny-all" || token === "--json-strict" || token === "--verbose" || token === "--suppress-reads") continue;
1294
- 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;
1295
1726
  }
1296
1727
  return { hasAgentOverride };
1297
1728
  }
@@ -1317,24 +1748,52 @@ function detectRequestedOutputFormat(argv, fallback) {
1317
1748
  for (let index = 0; index < argv.length; index += 1) {
1318
1749
  const token = argv[index];
1319
1750
  if (token === "--") break;
1320
- if (token === "--json-strict" || token.startsWith("--json-strict=")) return "json";
1321
- if (token === "--format") {
1322
- const raw = argv[index + 1];
1323
- if (raw && OUTPUT_FORMATS.includes(raw)) detectedFormat = raw;
1324
- continue;
1325
- }
1326
- if (token.startsWith("--format=")) {
1327
- const raw = token.slice(9).trim();
1328
- if (OUTPUT_FORMATS.includes(raw)) detectedFormat = raw;
1329
- }
1751
+ if (isJsonStrictToken(token)) return "json";
1752
+ const format = readFormatFlagValue(token, argv[index + 1]);
1753
+ if (format) detectedFormat = format;
1330
1754
  }
1331
1755
  return detectedFormat;
1332
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
+ }
1333
1771
  function detectJsonStrict(argv) {
1334
1772
  for (let index = 0; index < argv.length; index += 1) {
1335
1773
  const token = argv[index];
1336
1774
  if (token === "--") break;
1337
- 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;
1338
1797
  }
1339
1798
  return false;
1340
1799
  }
@@ -1364,43 +1823,69 @@ async function emitRequestedError(error, normalized, outputPolicy) {
1364
1823
  async function runWithOutputPolicy(_outputPolicy, run) {
1365
1824
  return await run();
1366
1825
  }
1367
- async function main(argv = process.argv) {
1826
+ async function handleQueueOwnerCommand(argv) {
1368
1827
  installPerfMetricsCapture({
1369
1828
  argv: argv.slice(2),
1370
1829
  role: argv[2] === "__queue-owner" ? "queue_owner" : "cli"
1371
1830
  });
1372
- if (argv.includes("--version") || argv.includes("-V")) {
1373
- process.stdout.write(`${getAcpxVersion()}\n`);
1374
- return;
1375
- }
1376
- if (argv[2] === "__queue-owner") try {
1831
+ if (argv[2] !== "__queue-owner") return false;
1832
+ try {
1377
1833
  await runQueueOwnerFromEnv(process.env);
1378
- return;
1834
+ return true;
1379
1835
  } catch (error) {
1380
1836
  const message = error instanceof Error ? error.message : String(error);
1381
1837
  process.stderr.write(`[acpx] queue owner failed: ${message}\n`);
1382
1838
  process.exit(EXIT_CODES.ERROR);
1839
+ return true;
1383
1840
  }
1384
- if (shouldMaybeHandleSkillflag(argv)) {
1385
- const { findSkillsRoot, maybeHandleSkillflag } = await loadSkillflagModule();
1386
- await maybeHandleSkillflag(argv, {
1387
- skillsRoot: findSkillsRoot(import.meta.url),
1388
- 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"
1389
1865
  });
1866
+ await emitRequestedError(error, normalized, requestedOutputPolicy);
1867
+ process.exit(exitCodeForOutputErrorCode(normalized.code));
1390
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) {
1391
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);
1392
1882
  const config = await loadResolvedConfig(detectInitialCwd(rawArgs));
1393
1883
  const requestedJsonStrict = detectJsonStrict(rawArgs);
1394
1884
  const requestedOutputPolicy = {
1395
1885
  ...resolveOutputPolicy(detectRequestedOutputFormat(rawArgs, config.format), requestedJsonStrict),
1396
1886
  suppressReads: rawArgs.some((token) => token === "--suppress-reads")
1397
1887
  };
1398
- const program = new Command();
1399
- program.name("acpx").description("Headless CLI client for the Agent Client Protocol").version(getAcpxVersion()).enablePositionalOptions().showHelpAfterError();
1400
- if (requestedJsonStrict) program.configureOutput({
1401
- writeOut: () => {},
1402
- writeErr: () => {}
1403
- });
1888
+ const program = createProgram(requestedJsonStrict);
1404
1889
  addGlobalFlags(program);
1405
1890
  configurePublicCli({
1406
1891
  program,
@@ -1424,19 +1909,7 @@ async function main(argv = process.argv) {
1424
1909
  try {
1425
1910
  await program.parseAsync(argv);
1426
1911
  } catch (error) {
1427
- if (error instanceof CommanderError) {
1428
- if (error.code === "commander.helpDisplayed" || error.code === "commander.version") process.exit(EXIT_CODES.SUCCESS);
1429
- const normalized = normalizeOutputError(error, {
1430
- defaultCode: "USAGE",
1431
- origin: "cli"
1432
- });
1433
- await emitRequestedError(error, normalized, requestedOutputPolicy);
1434
- process.exit(exitCodeForOutputErrorCode(normalized.code));
1435
- }
1436
- if (error instanceof InterruptedError) process.exit(EXIT_CODES.INTERRUPTED);
1437
- const normalized = normalizeOutputError(error, { origin: "cli" });
1438
- await emitRequestedError(error, normalized, requestedOutputPolicy);
1439
- process.exit(exitCodeForOutputErrorCode(normalized.code));
1912
+ await handleProgramParseError(error, requestedOutputPolicy);
1440
1913
  }
1441
1914
  });
1442
1915
  } finally {
@@ -1445,8 +1918,12 @@ async function main(argv = process.argv) {
1445
1918
  }
1446
1919
  //#endregion
1447
1920
  //#region src/cli.ts
1448
- const queueOwnerArgOverride = buildQueueOwnerArgOverride(fileURLToPath(import.meta.url));
1449
- if (queueOwnerArgOverride) process.env.ACPX_QUEUE_OWNER_ARGS ??= queueOwnerArgOverride;
1921
+ function installBrokenPipeHandler(stream) {
1922
+ stream.on("error", (error) => {
1923
+ if (error.code === "EPIPE") process.exit(0);
1924
+ throw error;
1925
+ });
1926
+ }
1450
1927
  function isCliEntrypoint(argv) {
1451
1928
  const entry = argv[1];
1452
1929
  if (!entry) return false;
@@ -1457,7 +1934,13 @@ function isCliEntrypoint(argv) {
1457
1934
  return false;
1458
1935
  }
1459
1936
  }
1460
- 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
+ }
1461
1944
  //#endregion
1462
1945
  export { formatPromptSessionBannerLine, parseAllowedTools, parseMaxTurns, parseTtlSeconds };
1463
1946