acpx 0.15.1 → 0.17.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 (47) hide show
  1. package/README.md +2 -0
  2. package/dist/agent-registry-DU6mhZBL.js +785 -0
  3. package/dist/agent-registry-DU6mhZBL.js.map +1 -0
  4. package/dist/agent-registry.d.ts +70 -0
  5. package/dist/agent-registry.d.ts.map +1 -0
  6. package/dist/agent-registry.js +2 -0
  7. package/dist/{cli-BHAT_D3V.js → cli-CiyfEC7L.js} +7 -14
  8. package/dist/cli-CiyfEC7L.js.map +1 -0
  9. package/dist/cli.d.ts +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +160 -349
  12. package/dist/cli.js.map +1 -1
  13. package/dist/{client-Cvz6msGc.d.ts → client-C6NUFqr-.d.ts} +21 -13
  14. package/dist/client-C6NUFqr-.d.ts.map +1 -0
  15. package/dist/{flows-BOI1XkMp.js → flows-CTOdIk-m.js} +208 -279
  16. package/dist/flows-CTOdIk-m.js.map +1 -0
  17. package/dist/flows.d.ts +6 -17
  18. package/dist/flows.d.ts.map +1 -1
  19. package/dist/flows.js +1 -1
  20. package/dist/{flags-BHcZWTov.js → invocation-options-DbCcOAzM.js} +83 -58
  21. package/dist/invocation-options-DbCcOAzM.js.map +1 -0
  22. package/dist/ipc-D3akHMEq.js +3350 -0
  23. package/dist/ipc-D3akHMEq.js.map +1 -0
  24. package/dist/output-BPPjvJTI.js +980 -0
  25. package/dist/output-BPPjvJTI.js.map +1 -0
  26. package/dist/{live-checkpoint-sB7dFOYR.js → queue-owner-runtime--IbbndGz.js} +5359 -4574
  27. package/dist/queue-owner-runtime--IbbndGz.js.map +1 -0
  28. package/dist/runtime.d.ts +197 -27
  29. package/dist/runtime.d.ts.map +1 -1
  30. package/dist/runtime.js +864 -409
  31. package/dist/runtime.js.map +1 -1
  32. package/dist/{session-options-DyIGRNfu.d.ts → session-options-Dp6mzNSy.d.ts} +8 -6
  33. package/dist/session-options-Dp6mzNSy.d.ts.map +1 -0
  34. package/dist/session-watch--UX5dh00.js +76 -0
  35. package/dist/session-watch--UX5dh00.js.map +1 -0
  36. package/dist/watch-BbBxO-kb.js +32 -0
  37. package/dist/watch-BbBxO-kb.js.map +1 -0
  38. package/package.json +27 -25
  39. package/skills/acpx/SKILL.md +24 -19
  40. package/dist/cli-BHAT_D3V.js.map +0 -1
  41. package/dist/client-Cvz6msGc.d.ts.map +0 -1
  42. package/dist/flags-BHcZWTov.js.map +0 -1
  43. package/dist/flows-BOI1XkMp.js.map +0 -1
  44. package/dist/live-checkpoint-sB7dFOYR.js.map +0 -1
  45. package/dist/output-8-D6Gd4Z.js +0 -4714
  46. package/dist/output-8-D6Gd4Z.js.map +0 -1
  47. package/dist/session-options-DyIGRNfu.d.ts.map +0 -1
package/dist/cli.js CHANGED
@@ -1,15 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import { a as runSessionQueueOwner, c as buildQueueOwnerArgOverride, g as __exportAll, h as isProcessAlive, l as flushPerfMetricsCapture, n as getTextErrorRemediationHints, o as runOnce, p as probeQueueOwnerHealth, t as createOutputFormatter, u as installPerfMetricsCapture } from "./output-8-D6Gd4Z.js";
3
- import { $t as AgentSpawnError, At as DEFAULT_AGENT_NAME, Ct as parsePromptSource, Dt as TimeoutError, Et as InterruptedError, G as listSessions, H as findSession, It as exitCodeForOutputErrorCode, Jt as OUTPUT_FORMATS, L as getAcpxVersion, Mt as normalizeAgentName$1, P as renderArgvIdentity, Qt as AcpxOperationalError, St as mergePromptSourceWithText, Tt as textPrompt, U as findSessionByDirectoryWalk, V as findGitRepositoryRoot, Wt as EXIT_CODES, X as writeSessionRecord, _t as isAcpJsonRpcMessage, bt as PromptInputValidationError, ct as serializeSessionRecordForDisk, dt as defaultSessionEventLog, ht as sessionEventSegmentPath, jt as listBuiltInAgents, lt as normalizeRuntimeSessionId, mt as sessionEventLockPath, pt as sessionEventActivePath, q as normalizeName, st as parseSessionRecord, zt as normalizeOutputError } from "./live-checkpoint-sB7dFOYR.js";
4
- import { C as loadPermissionPolicySpec, S as toTimerMilliseconds, _ as resolveAgentInvocation, a as addSessionOption, b as resolvePermissionMode, c as parseDaysOlderThan, d as parseNonEmptyValue, f as parseOutputFormat$1, g as parseTtlSeconds, h as parseTimeoutSeconds, i as addSessionNameOption, l as parseHistoryLimit, m as parseSessionName, n as addGlobalFlags, p as parsePruneBeforeDate, r as addPromptInputOption, s as parseAllowedTools, t as addExecConfigOption, u as parseMaxTurns, v as resolveGlobalFlags, x as resolveSessionNameFromFlags, y as resolveOutputPolicy } from "./flags-BHcZWTov.js";
2
+ import { n as getTextErrorRemediationHints, o as __exportAll, t as createOutputFormatter } from "./output-BPPjvJTI.js";
3
+ import { A as listSessions, At as AgentSpawnError, C as textPrompt, D as findSession, E as findGitRepositoryRoot, I as writeSessionRecord, M as normalizeName, O as findSessionByDirectoryWalk, Ot as AcpxOperationalError, R as parseSessionRecord, V as normalizeAgentSessionId, b as mergePromptSourceWithText, bt as EXIT_CODES, ct as defaultSessionEventLog, dt as sessionEventLockPath, ht as isProcessAlive, pt as writePrivateFile, u as probeQueueOwnerHealth, ut as sessionEventActivePath, v as PromptInputValidationError, wt as OUTPUT_FORMATS, x as parsePromptSource, z as serializeSessionRecordForDisk } from "./ipc-D3akHMEq.js";
4
+ import { X as getAcpxVersion, ct as normalizeOutputError, d as flushPerfMetricsCapture, et as listSessionEvents, f as installPerfMetricsCapture, i as runOnce, n as runSessionQueueOwner, nt as InterruptedError, rt as TimeoutError, s as DISCARD_OUTPUT_FORMATTER, st as exitCodeForOutputErrorCode, tt as isLegacyZedCodexAcpInvocation, u as buildQueueOwnerArgOverride } from "./queue-owner-runtime--IbbndGz.js";
5
+ import { O as renderArgvIdentity, i as DEFAULT_AGENT_NAME, l as normalizeAgentName$1, s as listBuiltInAgents } from "./agent-registry-DU6mhZBL.js";
6
+ import { C as resolvePermissionMode, S as resolveOutputPolicy, T as toTimerMilliseconds, _ as parseSessionName, a as addGlobalFlags, b as resolveAgentInvocation, c as addSessionOption, d as parseDaysOlderThan, f as parseHistoryLimit, g as parsePruneBeforeDate, h as parseOutputFormat$1, i as addExecConfigOption, m as parseNonEmptyValue, n as sessionConnectionOptions, o as addPromptInputOption, p as parseMaxTurns, r as sessionOptionsFromGlobalFlags, s as addSessionNameOption, t as resolvePermissionPolicyFromFlags, u as parseAllowedTools, v as parseTimeoutSeconds, w as resolveSessionNameFromFlags, x as resolveGlobalFlags, y as parseTtlSeconds } from "./invocation-options-DbCcOAzM.js";
5
7
  import { realpathSync } from "node:fs";
6
8
  import { fileURLToPath, pathToFileURL } from "node:url";
7
9
  import path from "node:path";
8
10
  import { Command, CommanderError, InvalidArgumentError, Option } from "commander";
9
11
  import fs$1 from "node:fs/promises";
10
12
  import os from "node:os";
11
- import { createHash, randomUUID } from "node:crypto";
12
13
  import { ZodError, z } from "zod";
14
+ import { createHash, randomUUID } from "node:crypto";
15
+ import { text } from "node:stream/consumers";
13
16
  import { performance } from "node:perf_hooks";
14
17
  //#region src/cli-public.ts
15
18
  function configurePublicCli(options) {
@@ -51,11 +54,6 @@ Examples:
51
54
  acpx --agent ./my-custom-server "do something"`);
52
55
  }
53
56
  //#endregion
54
- //#region src/acp/codex-compat.ts
55
- function isLegacyZedCodexAcpInvocation(agentCommand) {
56
- return /@zed-industries\/codex-acp\b/u.test(agentCommand);
57
- }
58
- //#endregion
59
57
  //#region src/session/export.ts
60
58
  var SessionExportError = class extends AcpxOperationalError {
61
59
  code;
@@ -119,25 +117,6 @@ async function isSessionActive(record) {
119
117
  if (record.closed) return false;
120
118
  return isProcessAlive(record.pid) || await hasLiveEventLock(record.acpxRecordId);
121
119
  }
122
- async function readHistoryFile(filePath) {
123
- const payload = await fs$1.readFile(filePath, "utf8").catch((error) => {
124
- if (error.code === "ENOENT") return "";
125
- throw error;
126
- });
127
- const history = [];
128
- for (const line of payload.split("\n").filter((entry) => entry.trim().length > 0)) try {
129
- const parsed = JSON.parse(line);
130
- if (isAcpJsonRpcMessage(parsed)) history.push(parsed);
131
- } catch {}
132
- return history;
133
- }
134
- async function readSessionHistory(record) {
135
- const history = [];
136
- const maxSegments = Number.isInteger(record.eventLog.max_segments) ? record.eventLog.max_segments : 0;
137
- for (let segment = maxSegments; segment >= 1; segment -= 1) history.push(...await readHistoryFile(sessionEventSegmentPath(record.acpxRecordId, segment)));
138
- history.push(...await readHistoryFile(sessionEventActivePath(record.acpxRecordId)));
139
- return history;
140
- }
141
120
  function cwdRelativeToHome(cwd, home) {
142
121
  const relative = path.relative(home, cwd);
143
122
  if (relative.length === 0) return ".";
@@ -174,10 +153,23 @@ async function exportSession(sessionLookup, outputPath) {
174
153
  updated_at: record.lastUsedAt,
175
154
  state: serializeSessionRecordForArchive(record, cwdRelative)
176
155
  },
177
- history: await readSessionHistory(record)
156
+ history: await listSessionEvents(record.acpxRecordId, record.eventLog.max_segments)
178
157
  };
179
- await fs$1.mkdir(path.dirname(path.resolve(outputPath)), { recursive: true });
180
- await fs$1.writeFile(outputPath, `${JSON.stringify(exported, null, 2)}\n`, "utf8");
158
+ const target = await resolveExportTarget(outputPath);
159
+ await writePrivateFile(target, `${JSON.stringify(exported, null, 2)}\n`, { privateDirectory: false });
160
+ }
161
+ async function resolveExportTarget(filePath) {
162
+ for (let hops = 0; hops < 40; hops += 1) {
163
+ const stat = await fs$1.lstat(filePath).catch((error) => {
164
+ if (error.code === "ENOENT") return;
165
+ throw error;
166
+ });
167
+ if (!stat || stat.isFile()) return filePath;
168
+ if (!stat.isSymbolicLink()) throw new Error("Session export output must be a regular file");
169
+ const target = await fs$1.readlink(filePath);
170
+ filePath = path.isAbsolute(target) ? target : `${path.dirname(filePath)}${path.sep}${target}`;
171
+ }
172
+ throw new Error("Too many symbolic links in session export output");
181
173
  }
182
174
  function normalizeAgentName(agentName) {
183
175
  const normalized = agentName?.trim().toLowerCase();
@@ -362,7 +354,7 @@ async function importSession(archivePath, options = {}) {
362
354
  await writeSessionRecord(newRecord);
363
355
  if (parsed.history.length > 0) {
364
356
  const history = parsed.history;
365
- await fs$1.writeFile(sessionEventActivePath(newRecordId), `${history.map((entry) => JSON.stringify(entry)).join("\n")}\n`, "utf8");
357
+ await writePrivateFile(sessionEventActivePath(newRecordId), `${history.map((entry) => JSON.stringify(entry)).join("\n")}\n`);
366
358
  }
367
359
  return {
368
360
  record_id: newRecordId,
@@ -377,6 +369,28 @@ function emitJsonResult(format, payload) {
377
369
  return true;
378
370
  }
379
371
  //#endregion
372
+ //#region src/cli/prompt-input.ts
373
+ async function readPromptInput(filePath, promptText, cwd, positionalLabel = "argument") {
374
+ try {
375
+ if (filePath) return await readPromptFile(filePath, promptText, cwd);
376
+ const joined = promptText.trim();
377
+ if (joined.length > 0) return textPrompt(joined);
378
+ if (process.stdin.isTTY) throw new InvalidArgumentError(`Prompt is required (pass as ${positionalLabel}, --file, or pipe via stdin)`);
379
+ const prompt = parsePromptSource(await text(process.stdin));
380
+ if (prompt.length === 0) throw new InvalidArgumentError("Prompt from stdin is empty");
381
+ return prompt;
382
+ } catch (error) {
383
+ if (error instanceof PromptInputValidationError) throw new InvalidArgumentError(error.message);
384
+ throw error;
385
+ }
386
+ }
387
+ async function readPromptFile(filePath, promptText, cwd) {
388
+ const source = filePath === "-" ? await text(process.stdin) : await fs$1.readFile(path.resolve(cwd, filePath), "utf8");
389
+ const prompt = mergePromptSourceWithText(source, promptText);
390
+ if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
391
+ return prompt;
392
+ }
393
+ //#endregion
380
394
  //#region src/cli/command-handlers.ts
381
395
  var NoSessionError = class extends Error {
382
396
  constructor(message) {
@@ -388,42 +402,17 @@ let sessionModulePromise;
388
402
  let outputModulePromise;
389
403
  let outputRenderModulePromise;
390
404
  function loadSessionModule() {
391
- sessionModulePromise ??= import("./output-8-D6Gd4Z.js").then((n) => n.i);
405
+ sessionModulePromise ??= import("./output-BPPjvJTI.js").then((n) => n.a);
392
406
  return sessionModulePromise;
393
407
  }
394
408
  function loadOutputModule() {
395
- outputModulePromise ??= import("./output-8-D6Gd4Z.js").then((n) => n.r);
409
+ outputModulePromise ??= import("./output-BPPjvJTI.js").then((n) => n.r);
396
410
  return outputModulePromise;
397
411
  }
398
412
  function loadOutputRenderModule() {
399
413
  outputRenderModulePromise ??= Promise.resolve().then(() => render_exports);
400
414
  return outputRenderModulePromise;
401
415
  }
402
- async function readPromptInputFromStdin() {
403
- let data = "";
404
- for await (const chunk of process.stdin) data += String(chunk);
405
- return data;
406
- }
407
- async function readPrompt(promptParts, filePath, cwd) {
408
- try {
409
- if (filePath) return await readPromptFromFile(filePath, cwd, promptParts);
410
- const joined = promptParts.join(" ").trim();
411
- if (joined.length > 0) return textPrompt(joined);
412
- if (process.stdin.isTTY) throw new InvalidArgumentError("Prompt is required (pass as argument, --file, or pipe via stdin)");
413
- const prompt = parsePromptSource(await readPromptInputFromStdin());
414
- if (prompt.length === 0) throw new InvalidArgumentError("Prompt from stdin is empty");
415
- return prompt;
416
- } catch (error) {
417
- if (error instanceof PromptInputValidationError) throw new InvalidArgumentError(error.message);
418
- throw error;
419
- }
420
- }
421
- async function readPromptFromFile(filePath, cwd, promptParts) {
422
- const source = filePath === "-" ? await readPromptInputFromStdin() : await fs$1.readFile(path.resolve(cwd, filePath), "utf8");
423
- const prompt = mergePromptSourceWithText(source, promptParts.join(" "));
424
- if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
425
- return prompt;
426
- }
427
416
  function applyPermissionExitCode(result, quietOutput) {
428
417
  const stats = result.permissionStats;
429
418
  const deniedOrCancelled = stats.denied + stats.cancelled;
@@ -447,40 +436,17 @@ function resolveRequestedOutputPolicy(globalFlags) {
447
436
  suppressReads: globalFlags.suppressReads === true
448
437
  };
449
438
  }
450
- function sessionOptionsFromGlobalFlags$1(globalFlags) {
451
- return {
452
- model: globalFlags.model,
453
- allowedTools: globalFlags.allowedTools,
454
- maxTurns: globalFlags.maxTurns,
455
- systemPrompt: globalFlags.systemPrompt
456
- };
457
- }
458
- async function resolvePermissionPolicyFromFlags$1(globalFlags) {
459
- try {
460
- return await loadPermissionPolicySpec(globalFlags.permissionPolicy, globalFlags.cwd);
461
- } catch (error) {
462
- const message = error instanceof Error ? error.message : String(error);
463
- throw new InvalidArgumentError(`Invalid permission policy: ${message}`);
464
- }
465
- }
466
439
  function buildSessionStartOptions(params) {
467
440
  return {
441
+ ...sessionConnectionOptions(params.globalFlags, params.config),
468
442
  agentCommand: params.agent.agentCommand,
469
443
  agentArgv: params.agent.agentArgv,
470
444
  cwd: params.agent.cwd,
471
445
  name: params.flags.name,
472
446
  resumeSessionId: params.flags.resumeSession,
473
- mcpServers: params.config.mcpServers,
474
447
  permissionMode: params.permissionMode,
475
- nonInteractivePermissions: params.globalFlags.nonInteractivePermissions,
476
448
  permissionPolicy: params.permissionPolicy,
477
- authCredentials: params.config.auth,
478
- authPolicy: params.globalFlags.authPolicy,
479
- fs: params.globalFlags.fs,
480
- terminal: params.globalFlags.terminal,
481
- timeoutMs: params.globalFlags.timeout,
482
- verbose: params.globalFlags.verbose,
483
- sessionOptions: sessionOptionsFromGlobalFlags$1(params.globalFlags),
449
+ sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags),
484
450
  onModelWarning: params.globalFlags.jsonStrict ? void 0 : (message) => process.stderr.write(`[acpx] warning: ${message}\n`)
485
451
  };
486
452
  }
@@ -520,8 +486,8 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
520
486
  const globalFlags = resolveGlobalFlags(command, config);
521
487
  const outputPolicy = resolveRequestedOutputPolicy(globalFlags);
522
488
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
523
- const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
524
- const prompt = await readPrompt(promptParts, flags.file, globalFlags.cwd);
489
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
490
+ const prompt = await readPromptInput(flags.file, promptParts.join(" "), globalFlags.cwd);
525
491
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
526
492
  const [{ createOutputFormatter }, { printPromptSessionBanner, printQueuedPromptByFormat }, { sendSession }] = await Promise.all([
527
493
  loadOutputModule(),
@@ -535,33 +501,21 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
535
501
  });
536
502
  await printPromptSessionBanner(record, agent.cwd, outputPolicy.format, outputPolicy.jsonStrict);
537
503
  const result = await sendSession({
504
+ ...sessionConnectionOptions(globalFlags, config),
538
505
  sessionId: record.acpxRecordId,
539
506
  prompt,
540
- mcpServers: config.mcpServers,
541
507
  mcpConfigPath: config.mcpConfigPath,
542
508
  mcpConfigFingerprint: config.mcpConfigFingerprint,
543
509
  permissionMode,
544
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
545
510
  permissionPolicy,
546
- authCredentials: config.auth,
547
- authPolicy: globalFlags.authPolicy,
548
- fs: globalFlags.fs,
549
- terminal: globalFlags.terminal,
550
511
  outputFormatter,
551
512
  errorEmissionPolicy: { queueErrorAlreadyEmitted: outputPolicy.queueErrorAlreadyEmitted },
552
513
  suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,
553
- timeoutMs: globalFlags.timeout,
554
514
  ttlMs: globalFlags.ttl,
555
515
  maxQueueDepth: config.queueMaxDepth,
556
516
  promptRetries: globalFlags.promptRetries,
557
- verbose: globalFlags.verbose,
558
517
  waitForCompletion: flags.wait !== false,
559
- sessionOptions: {
560
- model: globalFlags.model,
561
- allowedTools: globalFlags.allowedTools,
562
- maxTurns: globalFlags.maxTurns,
563
- systemPrompt: globalFlags.systemPrompt
564
- }
518
+ sessionOptions: sessionOptionsFromGlobalFlags(globalFlags)
565
519
  });
566
520
  if ("queued" in result) {
567
521
  printQueuedPromptByFormat(result, outputPolicy.format);
@@ -587,36 +541,24 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
587
541
  const globalFlags = resolveGlobalFlags(command, config);
588
542
  const outputPolicy = resolveRequestedOutputPolicy(globalFlags);
589
543
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
590
- const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
591
- const prompt = await readPrompt(promptParts, flags.file, globalFlags.cwd);
544
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
545
+ const prompt = await readPromptInput(flags.file, promptParts.join(" "), globalFlags.cwd);
592
546
  const [{ createOutputFormatter }, { runOnce }] = await Promise.all([loadOutputModule(), loadSessionModule()]);
593
547
  const outputFormatter = createOutputFormatter(outputPolicy.format, { suppressReads: outputPolicy.suppressReads });
594
548
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
595
549
  applyPermissionExitCode(await runOnce({
550
+ ...sessionConnectionOptions(globalFlags, config),
596
551
  agentCommand: agent.agentCommand,
597
552
  agentArgv: agent.agentArgv,
598
553
  cwd: agent.cwd,
599
554
  prompt,
600
- mcpServers: config.mcpServers,
601
555
  permissionMode,
602
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
603
556
  permissionPolicy,
604
- authCredentials: config.auth,
605
- authPolicy: globalFlags.authPolicy,
606
- fs: globalFlags.fs,
607
- terminal: globalFlags.terminal,
608
557
  outputFormatter,
609
558
  errorEmissionPolicy: { queueErrorAlreadyEmitted: outputPolicy.queueErrorAlreadyEmitted },
610
559
  suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,
611
- timeoutMs: globalFlags.timeout,
612
- verbose: globalFlags.verbose,
613
560
  promptRetries: globalFlags.promptRetries,
614
- sessionOptions: {
615
- model: globalFlags.model,
616
- allowedTools: globalFlags.allowedTools,
617
- maxTurns: globalFlags.maxTurns,
618
- systemPrompt: globalFlags.systemPrompt
619
- },
561
+ sessionOptions: sessionOptionsFromGlobalFlags(globalFlags),
620
562
  configOptions: flags.configOption
621
563
  }), outputPolicy.format === "quiet" ? outputFormatter : void 0);
622
564
  }
@@ -690,17 +632,11 @@ async function handleSetMode(explicitAgentName, modeId, flags, command, config)
690
632
  const globalFlags = resolveGlobalFlags(command, config);
691
633
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
692
634
  const { setSessionMode } = await loadSessionModule();
635
+ const record = await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, resolveSessionNameFromFlags(flags, command));
693
636
  const result = await setSessionMode({
694
- sessionId: (await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, resolveSessionNameFromFlags(flags, command))).acpxRecordId,
695
- modeId,
696
- mcpServers: config.mcpServers,
697
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
698
- authCredentials: config.auth,
699
- authPolicy: globalFlags.authPolicy,
700
- fs: globalFlags.fs,
701
- terminal: globalFlags.terminal,
702
- timeoutMs: globalFlags.timeout,
703
- verbose: globalFlags.verbose
637
+ ...sessionConnectionOptions(globalFlags, config),
638
+ sessionId: record.acpxRecordId,
639
+ modeId
704
640
  });
705
641
  if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] session reconnect failed, started fresh session: ${result.loadError}\n`);
706
642
  printSetModeResultByFormat(modeId, result, globalFlags.format);
@@ -709,17 +645,11 @@ async function handleSetModel(explicitAgentName, modelId, flags, command, config
709
645
  const globalFlags = resolveGlobalFlags(command, config);
710
646
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
711
647
  const { setSessionModel } = await loadSessionModule();
648
+ const record = await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, resolveSessionNameFromFlags(flags, command));
712
649
  const result = await setSessionModel({
713
- sessionId: (await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, resolveSessionNameFromFlags(flags, command))).acpxRecordId,
714
- modelId,
715
- mcpServers: config.mcpServers,
716
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
717
- authCredentials: config.auth,
718
- authPolicy: globalFlags.authPolicy,
719
- fs: globalFlags.fs,
720
- terminal: globalFlags.terminal,
721
- timeoutMs: globalFlags.timeout,
722
- verbose: globalFlags.verbose
650
+ ...sessionConnectionOptions(globalFlags, config),
651
+ sessionId: record.acpxRecordId,
652
+ modelId
723
653
  });
724
654
  if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] session reconnect failed, started fresh session: ${result.loadError}\n`);
725
655
  printSetModelResultByFormat(modelId, result, globalFlags.format);
@@ -733,43 +663,30 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
733
663
  }
734
664
  const resolvedConfigId = resolveCompatibleConfigId(agent, configId);
735
665
  const { setSessionConfigOption } = await loadSessionModule();
666
+ const record = await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, resolveSessionNameFromFlags(flags, command));
736
667
  const result = await setSessionConfigOption({
737
- sessionId: (await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, resolveSessionNameFromFlags(flags, command))).acpxRecordId,
668
+ ...sessionConnectionOptions(globalFlags, config),
669
+ sessionId: record.acpxRecordId,
738
670
  configId: resolvedConfigId,
739
- value,
740
- mcpServers: config.mcpServers,
741
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
742
- authCredentials: config.auth,
743
- authPolicy: globalFlags.authPolicy,
744
- fs: globalFlags.fs,
745
- terminal: globalFlags.terminal,
746
- timeoutMs: globalFlags.timeout,
747
- verbose: globalFlags.verbose
671
+ value
748
672
  });
749
673
  if (globalFlags.verbose && result.loadError) process.stderr.write(`[acpx] session reconnect failed, started fresh session: ${result.loadError}\n`);
750
674
  printSetConfigOptionResultByFormat(configId, value, result, globalFlags.format);
751
675
  }
752
676
  async function tryListAgentSessions(agent, flags, globalFlags, config) {
753
677
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
754
- const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
678
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
755
679
  const { listAgentSessions } = await loadSessionModule();
756
680
  try {
757
681
  return await listAgentSessions({
682
+ ...sessionConnectionOptions(globalFlags, config),
758
683
  agentCommand: agent.agentCommand,
759
684
  agentArgv: agent.agentArgv,
760
685
  cwd: agent.cwd,
761
686
  cursor: flags.cursor,
762
687
  filterCwd: resolveSessionListFilterCwd(flags, agent.cwd),
763
- mcpServers: config.mcpServers,
764
688
  permissionMode,
765
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
766
- permissionPolicy,
767
- authCredentials: config.auth,
768
- authPolicy: globalFlags.authPolicy,
769
- fs: globalFlags.fs,
770
- terminal: globalFlags.terminal,
771
- timeoutMs: globalFlags.timeout,
772
- verbose: globalFlags.verbose
689
+ permissionPolicy
773
690
  });
774
691
  } catch (error) {
775
692
  if (error instanceof AgentSpawnError) return "spawn-failed";
@@ -808,7 +725,7 @@ async function handleSessionsClose(explicitAgentName, sessionName, command, conf
808
725
  async function handleSessionsNew(explicitAgentName, flags, command, config) {
809
726
  const globalFlags = resolveGlobalFlags(command, config);
810
727
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
811
- const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
728
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
812
729
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
813
730
  const [{ createSession, closeSession }, { printCreatedSessionBanner, printNewSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
814
731
  const replaced = await findSession({
@@ -838,7 +755,7 @@ async function handleSessionsNew(explicitAgentName, flags, command, config) {
838
755
  async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
839
756
  const globalFlags = resolveGlobalFlags(command, config);
840
757
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
841
- const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
758
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
842
759
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
843
760
  const [{ ensureSession }, { printCreatedSessionBanner, printEnsuredSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
844
761
  const result = await ensureSession(buildSessionStartOptions({
@@ -960,6 +877,26 @@ async function handleSessionsHistory(explicitAgentName, sessionName, flags, comm
960
877
  const globalFlags = resolveGlobalFlags(command, config);
961
878
  printSessionHistoryByFormat(await findScopedSessionOrThrow(resolveAgentInvocation(explicitAgentName, globalFlags, config), sessionName), flags.limit, globalFlags.format);
962
879
  }
880
+ async function handleSessionsWatch(explicitAgentName, flags, command, config) {
881
+ const globalFlags = resolveGlobalFlags(command, config);
882
+ const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
883
+ const scope = {
884
+ agentCommand: agent.agentCommand,
885
+ cwd: agent.cwd,
886
+ name: flags.name,
887
+ readOnly: true
888
+ };
889
+ const record = await findSession(scope) ?? await findSession({
890
+ ...scope,
891
+ includeClosed: true
892
+ });
893
+ if (!record) throw new Error(missingScopedSessionMessage(agent, flags.name));
894
+ const { runSessionWatch } = await import("./session-watch--UX5dh00.js");
895
+ await runSessionWatch(record, {
896
+ cursor: flags.cursor,
897
+ policy: resolveRequestedOutputPolicy(globalFlags)
898
+ });
899
+ }
963
900
  async function handleSessionsExport(explicitAgentName, sessionName, flags, command, config) {
964
901
  const globalFlags = resolveGlobalFlags(command, config);
965
902
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
@@ -1017,13 +954,6 @@ async function handleSessionsPrune(explicitAgentName, flags, command, config) {
1017
954
  //#region src/cli/compare-command.ts
1018
955
  const DEFAULT_COMPARE_TIMEOUT_MS = 3e5;
1019
956
  const FINAL_MESSAGE_PREVIEW_CHARS = 200;
1020
- var CaptureFormatter = class {
1021
- setContext(_context) {}
1022
- onAcpMessage(_message) {}
1023
- onError(params) {}
1024
- onPermissionEscalation(_event) {}
1025
- flush() {}
1026
- };
1027
957
  function asRecord$2(value) {
1028
958
  return Boolean(value) && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1029
959
  }
@@ -1042,34 +972,6 @@ function truncate(value, maxChars) {
1042
972
  if (value.length <= maxChars) return value;
1043
973
  return `${value.slice(0, Math.max(0, maxChars - 3))}...`;
1044
974
  }
1045
- async function readStdin() {
1046
- let data = "";
1047
- for await (const chunk of process.stdin) data += String(chunk);
1048
- return data;
1049
- }
1050
- async function readPromptFile(filePath, promptText, cwd) {
1051
- const source = filePath === "-" ? await readStdin() : await fs$1.readFile(path.resolve(cwd, filePath), "utf8");
1052
- const prompt = mergePromptSourceWithText(source, promptText);
1053
- if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
1054
- return prompt;
1055
- }
1056
- async function readPromptFromStdin() {
1057
- if (process.stdin.isTTY) throw new InvalidArgumentError("Prompt is required (pass as final argument, --file, or pipe via stdin)");
1058
- const prompt = parsePromptSource(await readStdin());
1059
- if (prompt.length === 0) throw new InvalidArgumentError("Prompt from stdin is empty");
1060
- return prompt;
1061
- }
1062
- async function readPromptInput(filePath, promptText, cwd) {
1063
- try {
1064
- if (filePath) return await readPromptFile(filePath, promptText, cwd);
1065
- const joined = promptText.trim();
1066
- if (joined.length > 0) return textPrompt(joined);
1067
- return await readPromptFromStdin();
1068
- } catch (error) {
1069
- if (error instanceof PromptInputValidationError) throw new InvalidArgumentError(error.message);
1070
- throw error;
1071
- }
1072
- }
1073
975
  function promptTokensAfterDoubleDash(command) {
1074
976
  const commandName = command.name();
1075
977
  const commandIndex = process.argv.findIndex((token, index) => index >= 2 && token === commandName);
@@ -1126,22 +1028,6 @@ function captureSessionUpdate(notification, capture) {
1126
1028
  function rowStatusFromPermissionStats(stats) {
1127
1029
  return stats.denied + stats.cancelled > 0 ? "permission_denied" : "ok";
1128
1030
  }
1129
- function sessionOptionsFromGlobalFlags(globalFlags) {
1130
- return {
1131
- model: globalFlags.model,
1132
- allowedTools: globalFlags.allowedTools,
1133
- maxTurns: globalFlags.maxTurns,
1134
- systemPrompt: globalFlags.systemPrompt
1135
- };
1136
- }
1137
- async function resolvePermissionPolicyFromFlags(globalFlags) {
1138
- try {
1139
- return await loadPermissionPolicySpec(globalFlags.permissionPolicy, globalFlags.cwd);
1140
- } catch (error) {
1141
- const message = error instanceof Error ? error.message : String(error);
1142
- throw new InvalidArgumentError(`Invalid permission policy: ${message}`);
1143
- }
1144
- }
1145
1031
  function buildSuccessRow(agentName, result, capture, startedAt) {
1146
1032
  const permissionStats = result.permissionStats;
1147
1033
  return {
@@ -1177,30 +1063,22 @@ function buildErrorRow(agentName, caught, capture, startedAt) {
1177
1063
  async function runAgentForCompare(params) {
1178
1064
  const capture = {
1179
1065
  finalMessage: "",
1180
- usage: {},
1181
- errors: []
1066
+ usage: {}
1182
1067
  };
1183
- const formatter = new CaptureFormatter();
1184
1068
  const t0 = performance.now();
1185
1069
  try {
1186
1070
  const agent = resolveAgentInvocation(params.agentName, params.globalFlags, params.config);
1187
1071
  const result = await runOnce({
1072
+ ...sessionConnectionOptions(params.globalFlags, params.config),
1188
1073
  agentCommand: agent.agentCommand,
1189
1074
  agentArgv: agent.agentArgv,
1190
1075
  cwd: agent.cwd,
1191
1076
  prompt: params.prompt,
1192
- mcpServers: params.config.mcpServers,
1193
1077
  permissionMode: resolvePermissionMode(params.globalFlags, params.config.defaultPermissions),
1194
- nonInteractivePermissions: params.globalFlags.nonInteractivePermissions,
1195
1078
  permissionPolicy: params.permissionPolicy,
1196
- authCredentials: params.config.auth,
1197
- authPolicy: params.globalFlags.authPolicy,
1198
- fs: params.globalFlags.fs,
1199
- terminal: params.globalFlags.terminal,
1200
- outputFormatter: formatter,
1079
+ outputFormatter: DISCARD_OUTPUT_FORMATTER,
1201
1080
  suppressSdkConsoleErrors: true,
1202
1081
  timeoutMs: params.globalFlags.timeout ?? DEFAULT_COMPARE_TIMEOUT_MS,
1203
- verbose: params.globalFlags.verbose,
1204
1082
  promptRetries: params.globalFlags.promptRetries,
1205
1083
  sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags),
1206
1084
  onSessionUpdate: (notification) => captureSessionUpdate(notification, capture)
@@ -1283,7 +1161,7 @@ function registerCompareCommand(program, config) {
1283
1161
  const outputPolicy = resolveOutputPolicy(flags.json === true ? "json" : globalFlags.format, globalFlags.jsonStrict === true);
1284
1162
  const promptFile = resolvePromptFile(flags);
1285
1163
  const { agents, promptText } = splitCompareArgs(args, promptFile, this);
1286
- const prompt = await readPromptInput(promptFile, promptText, globalFlags.cwd);
1164
+ const prompt = await readPromptInput(promptFile, promptText, globalFlags.cwd, "final argument");
1287
1165
  const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
1288
1166
  const rows = [];
1289
1167
  for (const agentName of agents) rows.push(await runAgentForCompare({
@@ -1307,21 +1185,19 @@ function parseNonEmptyString(value, path) {
1307
1185
  if (typeof value !== "string" || value.trim().length === 0) throw new Error(`Invalid ${path}: expected non-empty string`);
1308
1186
  return value.trim();
1309
1187
  }
1310
- function parseHeaders(value, path) {
1188
+ function parseNameValuePairs(value, path) {
1311
1189
  if (value == null) return [];
1312
1190
  if (!Array.isArray(value)) throw new Error(`Invalid ${path}: expected array`);
1313
- const headers = [];
1314
- for (const [index, rawHeader] of value.entries()) {
1315
- const headerRecord = asRecord$1(rawHeader);
1316
- if (!headerRecord) throw new Error(`Invalid ${path}[${index}]: expected object`);
1317
- const name = parseNonEmptyString(headerRecord.name, `${path}[${index}].name`);
1318
- const headerValue = parseNonEmptyString(headerRecord.value, `${path}[${index}].value`);
1319
- headers.push({
1320
- name,
1321
- value: headerValue
1191
+ const entries = [];
1192
+ for (const [index, rawEntry] of value.entries()) {
1193
+ const entry = asRecord$1(rawEntry);
1194
+ if (!entry) throw new Error(`Invalid ${path}[${index}]: expected object`);
1195
+ entries.push({
1196
+ name: parseNonEmptyString(entry.name, `${path}[${index}].name`),
1197
+ value: parseNonEmptyString(entry.value, `${path}[${index}].value`)
1322
1198
  });
1323
1199
  }
1324
- return headers;
1200
+ return entries;
1325
1201
  }
1326
1202
  function parseArgs(value, path) {
1327
1203
  if (value == null) return [];
@@ -1333,22 +1209,6 @@ function parseArgs(value, path) {
1333
1209
  }
1334
1210
  return args;
1335
1211
  }
1336
- function parseEnv(value, path) {
1337
- if (value == null) return [];
1338
- if (!Array.isArray(value)) throw new Error(`Invalid ${path}: expected array`);
1339
- const env = [];
1340
- for (const [index, rawEntry] of value.entries()) {
1341
- const entry = asRecord$1(rawEntry);
1342
- if (!entry) throw new Error(`Invalid ${path}[${index}]: expected object`);
1343
- const name = parseNonEmptyString(entry.name, `${path}[${index}].name`);
1344
- const envValue = parseNonEmptyString(entry.value, `${path}[${index}].value`);
1345
- env.push({
1346
- name,
1347
- value: envValue
1348
- });
1349
- }
1350
- return env;
1351
- }
1352
1212
  function parseMeta(value, path) {
1353
1213
  if (value === void 0) return;
1354
1214
  if (value === null) return null;
@@ -1366,7 +1226,7 @@ function parseHttpServer(serverRecord, path, type, name, _meta) {
1366
1226
  type,
1367
1227
  name,
1368
1228
  url: parseNonEmptyString(serverRecord.url, `${path}.url`),
1369
- headers: parseHeaders(serverRecord.headers, `${path}.headers`),
1229
+ headers: parseNameValuePairs(serverRecord.headers, `${path}.headers`),
1370
1230
  _meta
1371
1231
  };
1372
1232
  }
@@ -1375,7 +1235,7 @@ function parseStdioServer(serverRecord, path, name, _meta) {
1375
1235
  name,
1376
1236
  command: parseNonEmptyString(serverRecord.command, `${path}.command`),
1377
1237
  args: parseArgs(serverRecord.args, `${path}.args`),
1378
- env: parseEnv(serverRecord.env, `${path}.env`),
1238
+ env: parseNameValuePairs(serverRecord.env, `${path}.env`),
1379
1239
  _meta
1380
1240
  };
1381
1241
  }
@@ -1488,7 +1348,7 @@ function parseArgvAgentEntry(raw, name, sourcePath) {
1488
1348
  if (Object.prototype.hasOwnProperty.call(raw, "command") || Object.prototype.hasOwnProperty.call(raw, "args")) throw new Error(`Invalid config agents.${name} in ${sourcePath}: use argv alone, not command or args`);
1489
1349
  const argv = parseAgentArgv(raw.argv, name, sourcePath);
1490
1350
  return {
1491
- command: renderArgv(argv),
1351
+ command: renderArgvIdentity(argv),
1492
1352
  argv
1493
1353
  };
1494
1354
  }
@@ -1524,9 +1384,6 @@ function parseAgentArgs(value, agentName, sourcePath) {
1524
1384
  function quoteCommandArg(value) {
1525
1385
  return JSON.stringify(value);
1526
1386
  }
1527
- function renderArgv(argv) {
1528
- return renderArgvIdentity(argv);
1529
- }
1530
1387
  function parseAuth(value, sourcePath) {
1531
1388
  if (value == null) return;
1532
1389
  if (!isObject(value)) throw new Error(`Invalid config auth in ${sourcePath}: expected object`);
@@ -1572,18 +1429,6 @@ async function loadExplicitMcpConfig(cwd, configuredPath) {
1572
1429
  config: result.config
1573
1430
  };
1574
1431
  }
1575
- function mergeAgents(globalAgents, projectAgents) {
1576
- return {
1577
- ...globalAgents,
1578
- ...projectAgents
1579
- };
1580
- }
1581
- function mergeAuth(globalAuth, projectAuth) {
1582
- return {
1583
- ...globalAuth,
1584
- ...projectAuth
1585
- };
1586
- }
1587
1432
  async function loadResolvedConfig(cwd, options = {}) {
1588
1433
  const globalPath = defaultGlobalConfigPath();
1589
1434
  const projectPath = projectConfigPath(cwd);
@@ -1594,11 +1439,29 @@ async function loadResolvedConfig(cwd, options = {}) {
1594
1439
  ]);
1595
1440
  const globalConfig = globalResult.config;
1596
1441
  const projectConfig = projectResult.config;
1597
- const scalar = resolveScalarConfigValues(projectConfig, projectPath, globalConfig, globalPath);
1598
- const agents = mergeAgents(parseAgents(globalConfig?.agents, globalPath), parseAgents(projectConfig?.agents, projectPath));
1599
- const auth = mergeAuth(parseAuth(globalConfig?.auth, globalPath), parseAuth(projectConfig?.auth, projectPath));
1442
+ function resolveScalar(key, parse, fallback) {
1443
+ return parse(projectConfig?.[key], projectPath) ?? parse(globalConfig?.[key], globalPath) ?? fallback;
1444
+ }
1445
+ const scalar = {
1446
+ defaultAgent: resolveScalar("defaultAgent", parseDefaultAgent, DEFAULT_AGENT_NAME),
1447
+ defaultPermissions: resolveScalar("defaultPermissions", parsePermissionMode, DEFAULT_PERMISSION_MODE),
1448
+ nonInteractivePermissions: resolveScalar("nonInteractivePermissions", parseNonInteractivePermissionPolicy, DEFAULT_NON_INTERACTIVE_PERMISSION_POLICY),
1449
+ authPolicy: resolveScalar("authPolicy", parseAuthPolicy, DEFAULT_AUTH_POLICY),
1450
+ ttlMs: resolveScalar("ttl", parseTtlMs, DEFAULT_TTL_MS),
1451
+ timeoutMs: resolveTimeoutMs(projectConfig, projectPath, globalConfig, globalPath),
1452
+ queueMaxDepth: resolveScalar("queueMaxDepth", parseQueueMaxDepth, DEFAULT_QUEUE_MAX_DEPTH),
1453
+ format: resolveScalar("format", parseOutputFormat, DEFAULT_OUTPUT_FORMAT)
1454
+ };
1455
+ const agents = {
1456
+ ...parseAgents(globalConfig?.agents, globalPath),
1457
+ ...parseAgents(projectConfig?.agents, projectPath)
1458
+ };
1459
+ const auth = {
1460
+ ...parseAuth(globalConfig?.auth, globalPath),
1461
+ ...parseAuth(projectConfig?.auth, projectPath)
1462
+ };
1600
1463
  const mcpServers = resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath, explicitMcp.config, explicitMcp.path);
1601
- const disableExec = resolveDisableExec(projectConfig, projectPath, globalConfig, globalPath);
1464
+ const disableExec = resolveScalar("disableExec", parseDisableExec, DEFAULT_DISABLE_EXEC);
1602
1465
  return {
1603
1466
  ...scalar,
1604
1467
  agents,
@@ -1613,39 +1476,6 @@ async function loadResolvedConfig(cwd, options = {}) {
1613
1476
  hasProjectConfig: projectResult.exists
1614
1477
  };
1615
1478
  }
1616
- function resolveScalarConfigValues(projectConfig, projectPath, globalConfig, globalPath) {
1617
- return {
1618
- defaultAgent: resolveDefaultAgent(projectConfig, projectPath, globalConfig, globalPath),
1619
- defaultPermissions: resolveDefaultPermissions(projectConfig, projectPath, globalConfig, globalPath),
1620
- nonInteractivePermissions: resolveNonInteractivePermissions(projectConfig, projectPath, globalConfig, globalPath),
1621
- authPolicy: resolveAuthPolicy(projectConfig, projectPath, globalConfig, globalPath),
1622
- ttlMs: resolveTtlMs(projectConfig, projectPath, globalConfig, globalPath),
1623
- timeoutMs: resolveTimeoutMs(projectConfig, projectPath, globalConfig, globalPath),
1624
- queueMaxDepth: resolveQueueMaxDepth(projectConfig, projectPath, globalConfig, globalPath),
1625
- format: resolveFormat(projectConfig, projectPath, globalConfig, globalPath)
1626
- };
1627
- }
1628
- function resolveDefaultAgent(projectConfig, projectPath, globalConfig, globalPath) {
1629
- return parseDefaultAgent(projectConfig?.defaultAgent, projectPath) ?? parseDefaultAgent(globalConfig?.defaultAgent, globalPath) ?? "codex";
1630
- }
1631
- function resolveDefaultPermissions(projectConfig, projectPath, globalConfig, globalPath) {
1632
- return parsePermissionMode(projectConfig?.defaultPermissions, projectPath) ?? parsePermissionMode(globalConfig?.defaultPermissions, globalPath) ?? DEFAULT_PERMISSION_MODE;
1633
- }
1634
- function resolveNonInteractivePermissions(projectConfig, projectPath, globalConfig, globalPath) {
1635
- return parseNonInteractivePermissionPolicy(projectConfig?.nonInteractivePermissions, projectPath) ?? parseNonInteractivePermissionPolicy(globalConfig?.nonInteractivePermissions, globalPath) ?? DEFAULT_NON_INTERACTIVE_PERMISSION_POLICY;
1636
- }
1637
- function resolveAuthPolicy(projectConfig, projectPath, globalConfig, globalPath) {
1638
- return parseAuthPolicy(projectConfig?.authPolicy, projectPath) ?? parseAuthPolicy(globalConfig?.authPolicy, globalPath) ?? DEFAULT_AUTH_POLICY;
1639
- }
1640
- function resolveTtlMs(projectConfig, projectPath, globalConfig, globalPath) {
1641
- return parseTtlMs(projectConfig?.ttl, projectPath) ?? parseTtlMs(globalConfig?.ttl, globalPath) ?? DEFAULT_TTL_MS;
1642
- }
1643
- function resolveQueueMaxDepth(projectConfig, projectPath, globalConfig, globalPath) {
1644
- return parseQueueMaxDepth(projectConfig?.queueMaxDepth, projectPath) ?? parseQueueMaxDepth(globalConfig?.queueMaxDepth, globalPath) ?? DEFAULT_QUEUE_MAX_DEPTH;
1645
- }
1646
- function resolveFormat(projectConfig, projectPath, globalConfig, globalPath) {
1647
- return parseOutputFormat(projectConfig?.format, projectPath) ?? parseOutputFormat(globalConfig?.format, globalPath) ?? DEFAULT_OUTPUT_FORMAT;
1648
- }
1649
1479
  function hasConfigKey(config, key) {
1650
1480
  return config != null && Object.prototype.hasOwnProperty.call(config, key);
1651
1481
  }
@@ -1659,9 +1489,6 @@ function resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath,
1659
1489
  if (hasConfigKey(globalConfig, "mcpServers")) return parseMcpServers(globalConfig?.mcpServers, globalPath);
1660
1490
  return [];
1661
1491
  }
1662
- function resolveDisableExec(projectConfig, projectPath, globalConfig, globalPath) {
1663
- return parseDisableExec(projectConfig?.disableExec, projectPath) ?? parseDisableExec(globalConfig?.disableExec, globalPath) ?? DEFAULT_DISABLE_EXEC;
1664
- }
1665
1492
  function toConfigDisplay(config) {
1666
1493
  const agents = {};
1667
1494
  for (const [name, agent] of Object.entries(config.agents)) agents[name] = agent.argv ? { argv: [...agent.argv] } : { command: agent.command };
@@ -1681,7 +1508,10 @@ function toConfigDisplay(config) {
1681
1508
  }
1682
1509
  async function initGlobalConfigFile() {
1683
1510
  const configPath = defaultGlobalConfigPath();
1684
- await fs$1.mkdir(path.dirname(configPath), { recursive: true });
1511
+ await fs$1.mkdir(path.dirname(configPath), {
1512
+ recursive: true,
1513
+ mode: 448
1514
+ });
1685
1515
  try {
1686
1516
  await fs$1.access(configPath);
1687
1517
  return {
@@ -1704,7 +1534,8 @@ async function initGlobalConfigFile() {
1704
1534
  try {
1705
1535
  await fs$1.writeFile(configPath, `${JSON.stringify(payload, null, 2)}\n`, {
1706
1536
  encoding: "utf8",
1707
- flag: "wx"
1537
+ flag: "wx",
1538
+ mode: 384
1708
1539
  });
1709
1540
  } catch (error) {
1710
1541
  if (error.code === "EEXIST") return {
@@ -1968,7 +1799,7 @@ function formatPruneSummaryLine(result, count) {
1968
1799
  return `${prefix} ${count} session${count === 1 ? "" : "s"}${bytesSuffix}`;
1969
1800
  }
1970
1801
  function agentSessionIdPayload(agentSessionId) {
1971
- const normalized = normalizeRuntimeSessionId(agentSessionId);
1802
+ const normalized = normalizeAgentSessionId(agentSessionId);
1972
1803
  if (!normalized) return {};
1973
1804
  return { agentSessionId: normalized };
1974
1805
  }
@@ -2181,6 +2012,9 @@ function registerSessionsCommand(parent, explicitAgentName, config) {
2181
2012
  sessionsCommand.command("read").description("Read full session history").argument("[name]", "Session name", parseSessionName).option("--tail <count>", "Show only the last N entries instead of all history", parseHistoryLimit).action(async function(name, flags) {
2182
2013
  await handleSessionsHistory(explicitAgentName, name, { limit: flags.tail ?? 0 }, this, config);
2183
2014
  });
2015
+ sessionsCommand.command("watch").description("Replay and follow session events without affecting the active turn").option("-s, --name <name>", "Session name", parseSessionName).option("--cursor <cursor>", "Resume after a session watch cursor", (value) => parseNonEmptyValue("Cursor", value)).action(async function(flags) {
2016
+ await handleSessionsWatch(explicitAgentName, flags, this, config);
2017
+ });
2184
2018
  sessionsCommand.command("export").description("Export a portable session archive").argument("[name]", "Session name", parseSessionName).requiredOption("--output <path>", "Output archive path", (value) => parseNonEmptyValue("Output path", value)).addOption(new LocalAttributeOption("--cwd <cwd>", "Session cwd to export", "sourceCwd").argParser((value) => parseNonEmptyValue("Session cwd", value))).action(async function(name, flags) {
2185
2019
  await handleSessionsExport(explicitAgentName, name, flags, this, config);
2186
2020
  });
@@ -2240,7 +2074,7 @@ function registerAgentCommand(program, agentName, config) {
2240
2074
  }
2241
2075
  function registerFlowCommand(program, config) {
2242
2076
  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) {
2243
- const { handleFlowRun } = await import("./cli-BHAT_D3V.js");
2077
+ const { handleFlowRun } = await import("./cli-CiyfEC7L.js");
2244
2078
  await handleFlowRun(file, flags, this, config);
2245
2079
  });
2246
2080
  }
@@ -2259,15 +2093,19 @@ function registerDefaultCommands(program, config) {
2259
2093
  registerFlowCommand(program, config);
2260
2094
  }
2261
2095
  //#endregion
2262
- //#region src/cli/queue/owner-env.ts
2263
- const QUEUE_OWNER_PAYLOAD_FILE_ENV = "ACPX_QUEUE_OWNER_PAYLOAD_FILE";
2264
- const QUEUE_OWNER_PAYLOAD_ENV = "ACPX_QUEUE_OWNER_PAYLOAD";
2096
+ //#region src/session/queue/owner-input.ts
2265
2097
  function asRecord(value) {
2266
2098
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
2267
2099
  return value;
2268
2100
  }
2269
2101
  function parseQueueOwnerPayload(raw) {
2270
- const record = asRecord(JSON.parse(raw));
2102
+ let parsed;
2103
+ try {
2104
+ parsed = JSON.parse(raw);
2105
+ } catch {
2106
+ throw new Error("queue owner payload must be valid JSON");
2107
+ }
2108
+ const record = asRecord(parsed);
2271
2109
  if (!record) throw new Error("queue owner payload must be an object");
2272
2110
  if (typeof record.sessionId !== "string" || record.sessionId.trim().length === 0) throw new Error("queue owner payload missing sessionId");
2273
2111
  if (record.permissionMode !== "approve-all" && record.permissionMode !== "approve-reads" && record.permissionMode !== "deny-all") throw new Error("queue owner payload has invalid permissionMode");
@@ -2343,30 +2181,10 @@ function assignSessionEnv(options, value) {
2343
2181
  const entries = Object.entries(env).filter((entry) => typeof entry[1] === "string");
2344
2182
  if (entries.length > 0) options.env = Object.fromEntries(entries);
2345
2183
  }
2346
- async function runQueueOwnerFromEnv(env) {
2347
- const options = parseQueueOwnerPayload(await readQueueOwnerPayloadFromEnv(env));
2348
- await runSessionQueueOwner(options);
2349
- }
2350
- async function readQueueOwnerPayloadFromEnv(env) {
2351
- const payloadFile = env[QUEUE_OWNER_PAYLOAD_FILE_ENV];
2352
- if (payloadFile) {
2353
- const payload = await fs$1.readFile(payloadFile, "utf8");
2354
- await cleanupQueueOwnerPayloadFile(payloadFile).catch(() => {});
2355
- return payload;
2356
- }
2357
- const payload = env[QUEUE_OWNER_PAYLOAD_ENV];
2358
- if (!payload) throw new Error(`missing ${QUEUE_OWNER_PAYLOAD_ENV}`);
2359
- return payload;
2360
- }
2361
- async function cleanupQueueOwnerPayloadFile(payloadFile) {
2362
- if (!isQueueOwnerPayloadFile(payloadFile)) return;
2363
- await fs$1.unlink(payloadFile).catch(() => {});
2364
- await fs$1.rmdir(path.dirname(payloadFile)).catch(() => {});
2365
- }
2366
- function isQueueOwnerPayloadFile(payloadFile) {
2367
- const resolved = path.resolve(payloadFile);
2368
- const payloadDir = path.dirname(resolved);
2369
- return path.dirname(payloadDir) === path.resolve(os.tmpdir()) && path.basename(payloadDir).startsWith("acpx-queue-owner-") && path.basename(resolved) === "payload.json";
2184
+ async function runQueueOwnerFromStdin() {
2185
+ const payload = await text(process.stdin);
2186
+ if (!payload) throw new Error("queue owner startup payload is empty");
2187
+ await runSessionQueueOwner(parseQueueOwnerPayload(payload));
2370
2188
  }
2371
2189
  //#endregion
2372
2190
  //#region src/cli-core.ts
@@ -2608,9 +2426,6 @@ async function emitRequestedError(error, normalized, outputPolicy) {
2608
2426
  if (outputPolicy.format === "text") for (const hint of getTextErrorRemediationHints(normalized)) process.stderr.write(`${hint}\n`);
2609
2427
  }
2610
2428
  }
2611
- async function runWithOutputPolicy(_outputPolicy, run) {
2612
- return await run();
2613
- }
2614
2429
  async function handleQueueOwnerCommand(argv) {
2615
2430
  installPerfMetricsCapture({
2616
2431
  argv: argv.slice(2),
@@ -2618,7 +2433,7 @@ async function handleQueueOwnerCommand(argv) {
2618
2433
  });
2619
2434
  if (argv[2] !== "__queue-owner") return false;
2620
2435
  try {
2621
- await runQueueOwnerFromEnv(process.env);
2436
+ await runQueueOwnerFromStdin();
2622
2437
  return true;
2623
2438
  } catch (error) {
2624
2439
  const message = error instanceof Error ? error.message : String(error);
@@ -2700,13 +2515,9 @@ async function main(argv = process.argv) {
2700
2515
  throw error;
2701
2516
  });
2702
2517
  try {
2703
- await runWithOutputPolicy(requestedOutputPolicy, async () => {
2704
- try {
2705
- await program.parseAsync(normalizedArgv);
2706
- } catch (error) {
2707
- await handleProgramParseError(error, requestedOutputPolicy);
2708
- }
2709
- });
2518
+ await program.parseAsync(normalizedArgv);
2519
+ } catch (error) {
2520
+ await handleProgramParseError(error, requestedOutputPolicy);
2710
2521
  } finally {
2711
2522
  flushPerfMetricsCapture();
2712
2523
  }