acpx 0.10.0 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +25 -19
  2. package/dist/{cli-8dP_TqBp.js → cli-D4XUKXcD.js} +5 -5
  3. package/dist/{cli-8dP_TqBp.js.map → cli-D4XUKXcD.js.map} +1 -1
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +429 -88
  7. package/dist/cli.js.map +1 -1
  8. package/dist/{client-C4iJBO0j.d.ts → client-DIlpCkHw.d.ts} +38 -5
  9. package/dist/client-DIlpCkHw.d.ts.map +1 -0
  10. package/dist/{flags--2oX_ubW.js → flags-Dvgmpq_l.js} +5 -5
  11. package/dist/flags-Dvgmpq_l.js.map +1 -0
  12. package/dist/{flows-e4umXVbY.js → flows-Cvsc-_AW.js} +4 -3
  13. package/dist/flows-Cvsc-_AW.js.map +1 -0
  14. package/dist/flows.d.ts +1 -1
  15. package/dist/flows.d.ts.map +1 -1
  16. package/dist/flows.js +1 -1
  17. package/dist/{live-checkpoint-CuFft_Nd.js → live-checkpoint-BWkYxMeS.js} +848 -207
  18. package/dist/live-checkpoint-BWkYxMeS.js.map +1 -0
  19. package/dist/{output-Di77Yugq.js → output-BEv_BB7T.js} +359 -141
  20. package/dist/output-BEv_BB7T.js.map +1 -0
  21. package/dist/runtime.d.ts +71 -5
  22. package/dist/runtime.d.ts.map +1 -1
  23. package/dist/runtime.js +192 -35
  24. package/dist/runtime.js.map +1 -1
  25. package/dist/{session-options-Bh1bIqQ2.d.ts → session-options-jkYbBxGE.d.ts} +27 -2
  26. package/dist/session-options-jkYbBxGE.d.ts.map +1 -0
  27. package/package.json +21 -20
  28. package/skills/acpx/SKILL.md +58 -3
  29. package/dist/client-C4iJBO0j.d.ts.map +0 -1
  30. package/dist/flags--2oX_ubW.js.map +0 -1
  31. package/dist/flows-e4umXVbY.js.map +0 -1
  32. package/dist/live-checkpoint-CuFft_Nd.js.map +0 -1
  33. package/dist/output-Di77Yugq.js.map +0 -1
  34. package/dist/session-options-Bh1bIqQ2.d.ts.map +0 -1
package/dist/cli.js CHANGED
@@ -1,15 +1,16 @@
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, p as probeQueueOwnerHealth, t as createOutputFormatter, u as installPerfMetricsCapture } from "./output-Di77Yugq.js";
3
- import { $ as defaultSessionEventLog, A as findGitRepositoryRoot, At as EXIT_CODES, I as normalizeName, M as findSessionByDirectoryWalk, P as listSessions, Pt as OUTPUT_FORMATS, Rt as AcpxOperationalError, St as exitCodeForOutputErrorCode, Tt as normalizeOutputError, X as serializeSessionRecordForDisk, Y as parseSessionRecord, Z as normalizeRuntimeSessionId, at as isAcpJsonRpcMessage, bt as normalizeAgentName$1, ct as PromptInputValidationError, dt as parsePromptSource, j as findSession, mt as InterruptedError, nt as sessionEventLockPath, pt as textPrompt, rt as sessionEventSegmentPath, tt as sessionEventActivePath, ut as mergePromptSourceWithText, vt as DEFAULT_AGENT_NAME, yt as listBuiltInAgents, z as writeSessionRecord, zt as AgentSpawnError } from "./live-checkpoint-CuFft_Nd.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--2oX_ubW.js";
5
- import { readFileSync, realpathSync } from "node:fs";
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-BEv_BB7T.js";
3
+ import { At as listBuiltInAgents, Et as TimeoutError, G as listSessions, Gt as OUTPUT_FORMATS, H as findSession, It as normalizeOutputError, L as getAcpxVersion, Nt as exitCodeForOutputErrorCode, St as parsePromptSource, Tt as InterruptedError, U as findSessionByDirectoryWalk, V as findGitRepositoryRoot, Vt as EXIT_CODES, X as writeSessionRecord, Xt as AgentSpawnError, Yt as AcpxOperationalError, ct as normalizeRuntimeSessionId, ft as sessionEventActivePath, gt as isAcpJsonRpcMessage, jt as normalizeAgentName$1, kt as DEFAULT_AGENT_NAME, mt as sessionEventSegmentPath, ot as parseSessionRecord, pt as sessionEventLockPath, q as normalizeName, st as serializeSessionRecordForDisk, ut as defaultSessionEventLog, wt as textPrompt, xt as mergePromptSourceWithText, yt as PromptInputValidationError } from "./live-checkpoint-BWkYxMeS.js";
4
+ import { _ as resolveGlobalFlags, b as resolveSessionNameFromFlags, c as parseHistoryLimit, d as parseOutputFormat$1, f as parsePruneBeforeDate, g as resolveAgentInvocation, h as parseTtlSeconds, i as addSessionOption, l as parseMaxTurns, m as parseTimeoutSeconds, n as addPromptInputOption, o as parseAllowedTools, p as parseSessionName, r as addSessionNameOption, s as parseDaysOlderThan, t as addGlobalFlags, u as parseNonEmptyValue, v as resolveOutputPolicy, x as loadPermissionPolicySpec, y as resolvePermissionMode } from "./flags-Dvgmpq_l.js";
5
+ import { realpathSync } from "node:fs";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import path from "node:path";
8
8
  import { Command, CommanderError, InvalidArgumentError, Option } from "commander";
9
9
  import fs$1 from "node:fs/promises";
10
10
  import os from "node:os";
11
- import { randomUUID } from "node:crypto";
11
+ import { createHash, randomUUID } from "node:crypto";
12
12
  import { ZodError, z } from "zod";
13
+ import { performance } from "node:perf_hooks";
13
14
  //#region src/cli-public.ts
14
15
  function configurePublicCli(options) {
15
16
  const builtInAgents = options.listBuiltInAgents(options.config.agents);
@@ -386,11 +387,11 @@ let sessionModulePromise;
386
387
  let outputModulePromise;
387
388
  let outputRenderModulePromise;
388
389
  function loadSessionModule() {
389
- sessionModulePromise ??= import("./output-Di77Yugq.js").then((n) => n.i);
390
+ sessionModulePromise ??= import("./output-BEv_BB7T.js").then((n) => n.i);
390
391
  return sessionModulePromise;
391
392
  }
392
393
  function loadOutputModule() {
393
- outputModulePromise ??= import("./output-Di77Yugq.js").then((n) => n.r);
394
+ outputModulePromise ??= import("./output-BEv_BB7T.js").then((n) => n.r);
394
395
  return outputModulePromise;
395
396
  }
396
397
  function loadOutputRenderModule() {
@@ -436,7 +437,7 @@ function resolveRequestedOutputPolicy(globalFlags) {
436
437
  suppressReads: globalFlags.suppressReads === true
437
438
  };
438
439
  }
439
- function sessionOptionsFromGlobalFlags(globalFlags) {
440
+ function sessionOptionsFromGlobalFlags$1(globalFlags) {
440
441
  return {
441
442
  model: globalFlags.model,
442
443
  allowedTools: globalFlags.allowedTools,
@@ -444,7 +445,7 @@ function sessionOptionsFromGlobalFlags(globalFlags) {
444
445
  systemPrompt: globalFlags.systemPrompt
445
446
  };
446
447
  }
447
- async function resolvePermissionPolicyFromFlags(globalFlags) {
448
+ async function resolvePermissionPolicyFromFlags$1(globalFlags) {
448
449
  try {
449
450
  return await loadPermissionPolicySpec(globalFlags.permissionPolicy, globalFlags.cwd);
450
451
  } catch (error) {
@@ -466,7 +467,8 @@ function buildSessionStartOptions(params) {
466
467
  terminal: params.globalFlags.terminal,
467
468
  timeoutMs: params.globalFlags.timeout,
468
469
  verbose: params.globalFlags.verbose,
469
- sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags)
470
+ sessionOptions: sessionOptionsFromGlobalFlags$1(params.globalFlags),
471
+ onModelWarning: params.globalFlags.jsonStrict ? void 0 : (message) => process.stderr.write(`[acpx] warning: ${message}\n`)
470
472
  };
471
473
  }
472
474
  function resolveSessionListFilterCwd(flags, agentCwd) {
@@ -505,7 +507,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
505
507
  const globalFlags = resolveGlobalFlags(command, config);
506
508
  const outputPolicy = resolveRequestedOutputPolicy(globalFlags);
507
509
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
508
- const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
510
+ const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
509
511
  const prompt = await readPrompt(promptParts, flags.file, globalFlags.cwd);
510
512
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
511
513
  const [{ createOutputFormatter }, { printPromptSessionBanner, printQueuedPromptByFormat }, { sendSession }] = await Promise.all([
@@ -513,7 +515,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
513
515
  loadOutputRenderModule(),
514
516
  loadSessionModule()
515
517
  ]);
516
- const record = await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, flags.session);
518
+ const record = await findRoutedSessionOrThrow(agent.agentCommand, agent.agentName, agent.cwd, resolveSessionNameFromFlags(flags, command));
517
519
  const outputFormatter = createOutputFormatter(outputPolicy.format, {
518
520
  jsonContext: { sessionId: record.acpxRecordId },
519
521
  suppressReads: outputPolicy.suppressReads
@@ -523,6 +525,8 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
523
525
  sessionId: record.acpxRecordId,
524
526
  prompt,
525
527
  mcpServers: config.mcpServers,
528
+ mcpConfigPath: config.mcpConfigPath,
529
+ mcpConfigFingerprint: config.mcpConfigFingerprint,
526
530
  permissionMode,
527
531
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
528
532
  permissionPolicy,
@@ -569,7 +573,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
569
573
  const globalFlags = resolveGlobalFlags(command, config);
570
574
  const outputPolicy = resolveRequestedOutputPolicy(globalFlags);
571
575
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
572
- const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
576
+ const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
573
577
  const prompt = await readPrompt(promptParts, flags.file, globalFlags.cwd);
574
578
  const [{ createOutputFormatter }, { runOnce }] = await Promise.all([loadOutputModule(), loadSessionModule()]);
575
579
  const outputFormatter = createOutputFormatter(outputPolicy.format, { suppressReads: outputPolicy.suppressReads });
@@ -726,7 +730,7 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
726
730
  }
727
731
  async function tryListAgentSessions(agent, flags, globalFlags, config) {
728
732
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
729
- const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
733
+ const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
730
734
  const { listAgentSessions } = await loadSessionModule();
731
735
  try {
732
736
  return await listAgentSessions({
@@ -781,7 +785,7 @@ async function handleSessionsClose(explicitAgentName, sessionName, command, conf
781
785
  async function handleSessionsNew(explicitAgentName, flags, command, config) {
782
786
  const globalFlags = resolveGlobalFlags(command, config);
783
787
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
784
- const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
788
+ const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
785
789
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
786
790
  const [{ createSession, closeSession }, { printCreatedSessionBanner, printNewSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
787
791
  const replaced = await findSession({
@@ -811,7 +815,7 @@ async function handleSessionsNew(explicitAgentName, flags, command, config) {
811
815
  async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
812
816
  const globalFlags = resolveGlobalFlags(command, config);
813
817
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
814
- const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
818
+ const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
815
819
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
816
820
  const [{ ensureSession }, { printCreatedSessionBanner, printEnsuredSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
817
821
  const result = await ensureSession(buildSessionStartOptions({
@@ -987,6 +991,285 @@ async function handleSessionsPrune(explicitAgentName, flags, command, config) {
987
991
  }), globalFlags.format);
988
992
  }
989
993
  //#endregion
994
+ //#region src/cli/compare-command.ts
995
+ const DEFAULT_COMPARE_TIMEOUT_MS = 3e5;
996
+ const FINAL_MESSAGE_PREVIEW_CHARS = 200;
997
+ var CaptureFormatter = class {
998
+ setContext(_context) {}
999
+ onAcpMessage(_message) {}
1000
+ onError(params) {}
1001
+ onPermissionEscalation(_event) {}
1002
+ flush() {}
1003
+ };
1004
+ function asRecord$2(value) {
1005
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value) ? value : void 0;
1006
+ }
1007
+ function numberField(source, keys) {
1008
+ if (!source) return null;
1009
+ for (const key of keys) {
1010
+ const value = source[key];
1011
+ if (typeof value === "number" && Number.isFinite(value)) return value;
1012
+ }
1013
+ return null;
1014
+ }
1015
+ function collapseWhitespace(value) {
1016
+ return value.replace(/\s+/g, " ").trim();
1017
+ }
1018
+ function truncate(value, maxChars) {
1019
+ if (value.length <= maxChars) return value;
1020
+ return `${value.slice(0, Math.max(0, maxChars - 3))}...`;
1021
+ }
1022
+ async function readStdin() {
1023
+ let data = "";
1024
+ for await (const chunk of process.stdin) data += String(chunk);
1025
+ return data;
1026
+ }
1027
+ async function readPromptFile(filePath, promptText, cwd) {
1028
+ const prompt = mergePromptSourceWithText(filePath === "-" ? await readStdin() : await fs$1.readFile(path.resolve(cwd, filePath), "utf8"), promptText);
1029
+ if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
1030
+ return prompt;
1031
+ }
1032
+ async function readPromptFromStdin() {
1033
+ if (process.stdin.isTTY) throw new InvalidArgumentError("Prompt is required (pass as final argument, --file, or pipe via stdin)");
1034
+ const prompt = parsePromptSource(await readStdin());
1035
+ if (prompt.length === 0) throw new InvalidArgumentError("Prompt from stdin is empty");
1036
+ return prompt;
1037
+ }
1038
+ async function readPromptInput(filePath, promptText, cwd) {
1039
+ try {
1040
+ if (filePath) return await readPromptFile(filePath, promptText, cwd);
1041
+ const joined = promptText.trim();
1042
+ if (joined.length > 0) return textPrompt(joined);
1043
+ return await readPromptFromStdin();
1044
+ } catch (error) {
1045
+ if (error instanceof PromptInputValidationError) throw new InvalidArgumentError(error.message);
1046
+ throw error;
1047
+ }
1048
+ }
1049
+ function promptTokensAfterDoubleDash(command) {
1050
+ const commandName = command.name();
1051
+ const commandIndex = process.argv.findIndex((token, index) => index >= 2 && token === commandName);
1052
+ if (commandIndex < 0) return [];
1053
+ const delimiterIndex = process.argv.findIndex((token, index) => index > commandIndex && token === "--");
1054
+ return delimiterIndex < 0 ? [] : process.argv.slice(delimiterIndex + 1);
1055
+ }
1056
+ function splitCompareArgs(args, filePath, command) {
1057
+ if (filePath) {
1058
+ if (args.length === 0) throw new InvalidArgumentError("At least one agent is required");
1059
+ return {
1060
+ agents: args,
1061
+ promptText: ""
1062
+ };
1063
+ }
1064
+ const promptTokens = promptTokensAfterDoubleDash(command);
1065
+ if (promptTokens.length > 0) {
1066
+ const agents = args.slice(0, -promptTokens.length);
1067
+ if (agents.length === 0) throw new InvalidArgumentError("At least one agent is required");
1068
+ return {
1069
+ agents,
1070
+ promptText: promptTokens.join(" ")
1071
+ };
1072
+ }
1073
+ if (args.length < 2) throw new InvalidArgumentError("Usage: acpx compare <agent>... '<prompt>'");
1074
+ return {
1075
+ agents: args.slice(0, -1),
1076
+ promptText: args[args.length - 1] ?? ""
1077
+ };
1078
+ }
1079
+ function captureUsage(update, capture) {
1080
+ const source = asRecord$2(asRecord$2(update._meta)?.usage) ?? update;
1081
+ capture.usage = {
1082
+ input_tokens: numberField(source, ["input_tokens", "inputTokens"]) ?? void 0,
1083
+ output_tokens: numberField(source, ["output_tokens", "outputTokens"]) ?? void 0,
1084
+ total_tokens: numberField(source, [
1085
+ "total_tokens",
1086
+ "totalTokens",
1087
+ "size",
1088
+ "used"
1089
+ ]) ?? void 0
1090
+ };
1091
+ }
1092
+ function captureSessionUpdate(notification, capture) {
1093
+ const update = asRecord$2(notification.update);
1094
+ if (!update) return;
1095
+ if (update.sessionUpdate === "agent_message_chunk") {
1096
+ const content = asRecord$2(update.content);
1097
+ if (content?.type === "text" && typeof content.text === "string") capture.finalMessage += content.text;
1098
+ return;
1099
+ }
1100
+ if (update.sessionUpdate === "usage_update") captureUsage(update, capture);
1101
+ }
1102
+ function rowStatusFromPermissionStats(stats) {
1103
+ return stats.denied + stats.cancelled > 0 ? "permission_denied" : "ok";
1104
+ }
1105
+ function sessionOptionsFromGlobalFlags(globalFlags) {
1106
+ return {
1107
+ model: globalFlags.model,
1108
+ allowedTools: globalFlags.allowedTools,
1109
+ maxTurns: globalFlags.maxTurns,
1110
+ systemPrompt: globalFlags.systemPrompt
1111
+ };
1112
+ }
1113
+ async function resolvePermissionPolicyFromFlags(globalFlags) {
1114
+ try {
1115
+ return await loadPermissionPolicySpec(globalFlags.permissionPolicy, globalFlags.cwd);
1116
+ } catch (error) {
1117
+ throw new InvalidArgumentError(`Invalid permission policy: ${error instanceof Error ? error.message : String(error)}`);
1118
+ }
1119
+ }
1120
+ function buildSuccessRow(agentName, result, capture, startedAt) {
1121
+ const permissionStats = result.permissionStats;
1122
+ return {
1123
+ agent: agentName,
1124
+ status: result.stopReason === "cancelled" ? "cancelled" : rowStatusFromPermissionStats(permissionStats),
1125
+ stop_reason: result.stopReason,
1126
+ wall_ms: Math.round(performance.now() - startedAt),
1127
+ input_tokens: capture.usage.input_tokens ?? null,
1128
+ output_tokens: capture.usage.output_tokens ?? null,
1129
+ total_tokens: capture.usage.total_tokens ?? null,
1130
+ final_message: truncate(collapseWhitespace(capture.finalMessage), FINAL_MESSAGE_PREVIEW_CHARS),
1131
+ error: null,
1132
+ permission_requests: permissionStats.requested,
1133
+ permission_denied: permissionStats.denied + permissionStats.cancelled
1134
+ };
1135
+ }
1136
+ function buildErrorRow(agentName, caught, capture, startedAt) {
1137
+ return {
1138
+ agent: agentName,
1139
+ status: caught instanceof TimeoutError ? "cancelled" : "error",
1140
+ stop_reason: null,
1141
+ wall_ms: Math.round(performance.now() - startedAt),
1142
+ input_tokens: capture.usage.input_tokens ?? null,
1143
+ output_tokens: capture.usage.output_tokens ?? null,
1144
+ total_tokens: capture.usage.total_tokens ?? null,
1145
+ final_message: truncate(collapseWhitespace(capture.finalMessage), FINAL_MESSAGE_PREVIEW_CHARS),
1146
+ error: truncate(collapseWhitespace(caught instanceof Error ? caught.message : String(caught)), FINAL_MESSAGE_PREVIEW_CHARS),
1147
+ permission_requests: 0,
1148
+ permission_denied: 0
1149
+ };
1150
+ }
1151
+ async function runAgentForCompare(params) {
1152
+ const capture = {
1153
+ finalMessage: "",
1154
+ usage: {},
1155
+ errors: []
1156
+ };
1157
+ const formatter = new CaptureFormatter();
1158
+ const t0 = performance.now();
1159
+ try {
1160
+ const agent = resolveAgentInvocation(params.agentName, params.globalFlags, params.config);
1161
+ const result = await runOnce({
1162
+ agentCommand: agent.agentCommand,
1163
+ cwd: agent.cwd,
1164
+ prompt: params.prompt,
1165
+ mcpServers: params.config.mcpServers,
1166
+ permissionMode: resolvePermissionMode(params.globalFlags, params.config.defaultPermissions),
1167
+ nonInteractivePermissions: params.globalFlags.nonInteractivePermissions,
1168
+ permissionPolicy: params.permissionPolicy,
1169
+ authCredentials: params.config.auth,
1170
+ authPolicy: params.globalFlags.authPolicy,
1171
+ terminal: params.globalFlags.terminal,
1172
+ outputFormatter: formatter,
1173
+ suppressSdkConsoleErrors: true,
1174
+ timeoutMs: params.globalFlags.timeout ?? DEFAULT_COMPARE_TIMEOUT_MS,
1175
+ verbose: params.globalFlags.verbose,
1176
+ promptRetries: params.globalFlags.promptRetries,
1177
+ sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags),
1178
+ onSessionUpdate: (notification) => captureSessionUpdate(notification, capture)
1179
+ });
1180
+ return buildSuccessRow(params.agentName, result, capture, t0);
1181
+ } catch (caught) {
1182
+ return buildErrorRow(params.agentName, caught, capture, t0);
1183
+ }
1184
+ }
1185
+ function formatCell(value) {
1186
+ if (value == null || value === "") return "-";
1187
+ if (typeof value === "string") return collapseWhitespace(value);
1188
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
1189
+ return collapseWhitespace(JSON.stringify(value));
1190
+ }
1191
+ function renderTable(rows) {
1192
+ const headers = [
1193
+ "agent",
1194
+ "status",
1195
+ "wall_ms",
1196
+ "input",
1197
+ "output",
1198
+ "total",
1199
+ "permissions",
1200
+ "stop_reason",
1201
+ "final_message",
1202
+ "error"
1203
+ ];
1204
+ const body = rows.map((row) => [
1205
+ row.agent,
1206
+ row.status,
1207
+ row.wall_ms,
1208
+ row.input_tokens,
1209
+ row.output_tokens,
1210
+ row.total_tokens,
1211
+ `${row.permission_denied}/${row.permission_requests}`,
1212
+ row.stop_reason,
1213
+ row.final_message,
1214
+ row.error
1215
+ ]);
1216
+ const widths = headers.map((header, index) => Math.max(header.length, ...body.map((cells) => formatCell(cells[index]).length)));
1217
+ const formatRow = (cells) => cells.map((cell, index) => truncate(formatCell(cell), widths[index] ?? 24).padEnd(widths[index] ?? 24)).join(" ").trimEnd();
1218
+ return [
1219
+ formatRow(headers),
1220
+ widths.map((width) => "-".repeat(width)).join(" "),
1221
+ ...body.map(formatRow)
1222
+ ].join("\n");
1223
+ }
1224
+ function printRows(rows, format) {
1225
+ if (format === "json") {
1226
+ process.stdout.write(`${JSON.stringify(rows)}\n`);
1227
+ return;
1228
+ }
1229
+ if (format === "quiet") {
1230
+ for (const row of rows) process.stdout.write(`${row.agent}\t${row.status}\n`);
1231
+ return;
1232
+ }
1233
+ process.stdout.write(`${renderTable(rows)}\n`);
1234
+ }
1235
+ function updateCompareExitCode(rows) {
1236
+ if (rows.some((row) => row.status === "error")) {
1237
+ process.exitCode = EXIT_CODES.ERROR;
1238
+ return;
1239
+ }
1240
+ if (rows.some((row) => row.status === "permission_denied")) {
1241
+ process.exitCode = EXIT_CODES.PERMISSION_DENIED;
1242
+ return;
1243
+ }
1244
+ if (rows.some((row) => row.status === "cancelled")) process.exitCode = EXIT_CODES.TIMEOUT;
1245
+ }
1246
+ function resolvePromptFile(flags) {
1247
+ if (flags.file && flags.promptFile && flags.file !== flags.promptFile) throw new InvalidArgumentError("Use only one prompt file flag: --file or --prompt-file");
1248
+ return flags.file ?? flags.promptFile;
1249
+ }
1250
+ function registerCompareCommand(program, config) {
1251
+ program.command("compare").description("Run one prompt across multiple agents and summarize the results").argument("<args...>", "Agents followed by prompt text, or agents with --file").option("--cwd <dir>", "Target workspace").option("--approve-all", "Auto-approve all permission requests").option("--approve-reads", "Auto-approve read/search requests and prompt for writes").option("--deny-all", "Deny all permission requests").option("--timeout <seconds>", "Per-agent timeout in seconds", parseTimeoutSeconds).option("--format <fmt>", "Output format: text, json, quiet", parseOutputFormat$1).option("--json", "Alias for --format json").option("-f, --file <path>", "Read prompt text from file path (use - for stdin)", (value) => parseNonEmptyValue("Prompt file", value)).option("--prompt-file <path>", "Alias for --file", (value) => parseNonEmptyValue("Prompt file", value)).action(async function(args, flags) {
1252
+ if (config.disableExec) throw new Error("compare subcommand is disabled by configuration (disableExec: true)");
1253
+ const globalFlags = resolveGlobalFlags(this, config);
1254
+ if (globalFlags.agent) throw new InvalidArgumentError("Do not combine compare with --agent; pass agent names");
1255
+ const outputPolicy = resolveOutputPolicy(flags.json === true ? "json" : globalFlags.format, globalFlags.jsonStrict === true);
1256
+ const promptFile = resolvePromptFile(flags);
1257
+ const { agents, promptText } = splitCompareArgs(args, promptFile, this);
1258
+ const prompt = await readPromptInput(promptFile, promptText, globalFlags.cwd);
1259
+ const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
1260
+ const rows = [];
1261
+ for (const agentName of agents) rows.push(await runAgentForCompare({
1262
+ agentName,
1263
+ prompt,
1264
+ config,
1265
+ globalFlags,
1266
+ permissionPolicy
1267
+ }));
1268
+ printRows(rows, outputPolicy.format);
1269
+ updateCompareExitCode(rows);
1270
+ });
1271
+ }
1272
+ //#endregion
990
1273
  //#region src/mcp-servers.ts
991
1274
  function asRecord$1(value) {
992
1275
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
@@ -1090,7 +1373,6 @@ function parseOptionalMcpServers(value, sourcePath, fieldName = "mcpServers") {
1090
1373
  }
1091
1374
  //#endregion
1092
1375
  //#region src/cli/config.ts
1093
- const DEFAULT_TIMEOUT_MS = void 0;
1094
1376
  const DEFAULT_TTL_MS = 3e5;
1095
1377
  const DEFAULT_PERMISSION_MODE = "approve-reads";
1096
1378
  const DEFAULT_NON_INTERACTIVE_PERMISSION_POLICY = "deny";
@@ -1098,14 +1380,14 @@ const DEFAULT_AUTH_POLICY = "skip";
1098
1380
  const DEFAULT_OUTPUT_FORMAT = "text";
1099
1381
  const DEFAULT_QUEUE_MAX_DEPTH = 16;
1100
1382
  const DEFAULT_DISABLE_EXEC = false;
1101
- const VALID_PERMISSION_MODES = new Set([
1383
+ const VALID_PERMISSION_MODES = /* @__PURE__ */ new Set([
1102
1384
  "approve-all",
1103
1385
  "approve-reads",
1104
1386
  "deny-all"
1105
1387
  ]);
1106
- const VALID_NON_INTERACTIVE_PERMISSION_POLICIES = new Set(["deny", "fail"]);
1107
- const VALID_AUTH_POLICIES = new Set(["skip", "fail"]);
1108
- const VALID_OUTPUT_FORMATS = new Set([
1388
+ const VALID_NON_INTERACTIVE_PERMISSION_POLICIES = /* @__PURE__ */ new Set(["deny", "fail"]);
1389
+ const VALID_AUTH_POLICIES = /* @__PURE__ */ new Set(["skip", "fail"]);
1390
+ const VALID_OUTPUT_FORMATS = /* @__PURE__ */ new Set([
1109
1391
  "text",
1110
1392
  "json",
1111
1393
  "quiet"
@@ -1218,6 +1500,16 @@ async function readConfigFile(filePath) {
1218
1500
  throw error;
1219
1501
  }
1220
1502
  }
1503
+ async function loadExplicitMcpConfig(cwd, configuredPath) {
1504
+ if (!configuredPath) return {};
1505
+ const resolvedPath = path.resolve(cwd, configuredPath);
1506
+ const result = await readConfigFile(resolvedPath);
1507
+ if (!result.exists) throw new Error(`MCP config file not found: ${resolvedPath}`);
1508
+ return {
1509
+ path: resolvedPath,
1510
+ config: result.config
1511
+ };
1512
+ }
1221
1513
  function mergeAgents(globalAgents, projectAgents) {
1222
1514
  return {
1223
1515
  ...globalAgents,
@@ -1230,16 +1522,20 @@ function mergeAuth(globalAuth, projectAuth) {
1230
1522
  ...projectAuth
1231
1523
  };
1232
1524
  }
1233
- async function loadResolvedConfig(cwd) {
1525
+ async function loadResolvedConfig(cwd, options = {}) {
1234
1526
  const globalPath = defaultGlobalConfigPath();
1235
1527
  const projectPath = projectConfigPath(cwd);
1236
- const [globalResult, projectResult] = await Promise.all([readConfigFile(globalPath), readConfigFile(projectPath)]);
1528
+ const [globalResult, projectResult, explicitMcp] = await Promise.all([
1529
+ readConfigFile(globalPath),
1530
+ readConfigFile(projectPath),
1531
+ loadExplicitMcpConfig(cwd, options.mcpConfigPath)
1532
+ ]);
1237
1533
  const globalConfig = globalResult.config;
1238
1534
  const projectConfig = projectResult.config;
1239
1535
  const scalar = resolveScalarConfigValues(projectConfig, projectPath, globalConfig, globalPath);
1240
1536
  const agents = mergeAgents(parseAgents(globalConfig?.agents, globalPath), parseAgents(projectConfig?.agents, projectPath));
1241
1537
  const auth = mergeAuth(parseAuth(globalConfig?.auth, globalPath), parseAuth(projectConfig?.auth, projectPath));
1242
- const mcpServers = resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath);
1538
+ const mcpServers = resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath, explicitMcp.config, explicitMcp.path);
1243
1539
  const disableExec = resolveDisableExec(projectConfig, projectPath, globalConfig, globalPath);
1244
1540
  return {
1245
1541
  ...scalar,
@@ -1249,6 +1545,8 @@ async function loadResolvedConfig(cwd) {
1249
1545
  mcpServers,
1250
1546
  globalPath,
1251
1547
  projectPath,
1548
+ mcpConfigPath: explicitMcp.path,
1549
+ mcpConfigFingerprint: explicitMcp.path ? createHash("sha256").update(JSON.stringify(mcpServers)).digest("hex") : void 0,
1252
1550
  hasGlobalConfig: globalResult.exists,
1253
1551
  hasProjectConfig: projectResult.exists
1254
1552
  };
@@ -1292,9 +1590,9 @@ function hasConfigKey(config, key) {
1292
1590
  function resolveTimeoutMs(projectConfig, projectPath, globalConfig, globalPath) {
1293
1591
  if (hasConfigKey(projectConfig, "timeout")) return parseTimeoutMs(projectConfig?.timeout, projectPath);
1294
1592
  if (hasConfigKey(globalConfig, "timeout")) return parseTimeoutMs(globalConfig?.timeout, globalPath);
1295
- return DEFAULT_TIMEOUT_MS;
1296
1593
  }
1297
- function resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath) {
1594
+ function resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath, mcpConfig, mcpConfigPath) {
1595
+ if (mcpConfigPath) return parseMcpServers(mcpConfig?.mcpServers, mcpConfigPath);
1298
1596
  if (hasConfigKey(projectConfig, "mcpServers")) return parseMcpServers(projectConfig?.mcpServers, projectPath);
1299
1597
  if (hasConfigKey(globalConfig, "mcpServers")) return parseMcpServers(globalConfig?.mcpServers, globalPath);
1300
1598
  return [];
@@ -1341,7 +1639,18 @@ async function initGlobalConfigFile() {
1341
1639
  agents: {},
1342
1640
  auth: {}
1343
1641
  };
1344
- await fs$1.writeFile(configPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
1642
+ try {
1643
+ await fs$1.writeFile(configPath, `${JSON.stringify(payload, null, 2)}\n`, {
1644
+ encoding: "utf8",
1645
+ flag: "wx"
1646
+ });
1647
+ } catch (error) {
1648
+ if (error.code === "EEXIST") return {
1649
+ path: configPath,
1650
+ created: false
1651
+ };
1652
+ throw error;
1653
+ }
1345
1654
  return {
1346
1655
  path: configPath,
1347
1656
  created: true
@@ -1355,7 +1664,8 @@ async function handleConfigShow(command, config) {
1355
1664
  ...toConfigDisplay(config),
1356
1665
  paths: {
1357
1666
  global: config.globalPath,
1358
- project: config.projectPath
1667
+ project: config.projectPath,
1668
+ ...config.mcpConfigPath ? { mcp: config.mcpConfigPath } : {}
1359
1669
  },
1360
1670
  loaded: {
1361
1671
  global: config.hasGlobalConfig,
@@ -1862,7 +2172,7 @@ function registerAgentCommand(program, agentName, config) {
1862
2172
  }
1863
2173
  function registerFlowCommand(program, config) {
1864
2174
  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) {
1865
- const { handleFlowRun } = await import("./cli-8dP_TqBp.js");
2175
+ const { handleFlowRun } = await import("./cli-D4XUKXcD.js");
1866
2176
  await handleFlowRun(file, flags, this, config);
1867
2177
  });
1868
2178
  }
@@ -1877,10 +2187,13 @@ function registerDefaultCommands(program, config) {
1877
2187
  });
1878
2188
  registerSessionsCommand(program, void 0, config);
1879
2189
  registerConfigCommand(program, config);
2190
+ registerCompareCommand(program, config);
1880
2191
  registerFlowCommand(program, config);
1881
2192
  }
1882
2193
  //#endregion
1883
2194
  //#region src/cli/queue/owner-env.ts
2195
+ const QUEUE_OWNER_PAYLOAD_FILE_ENV = "ACPX_QUEUE_OWNER_PAYLOAD_FILE";
2196
+ const QUEUE_OWNER_PAYLOAD_ENV = "ACPX_QUEUE_OWNER_PAYLOAD";
1884
2197
  function asRecord(value) {
1885
2198
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
1886
2199
  return value;
@@ -1902,6 +2215,8 @@ function parseQueueOwnerPayload(raw) {
1902
2215
  function assignQueueOwnerTransportOptions(options, record) {
1903
2216
  const parsedMcpServers = parseOptionalMcpServers(record.mcpServers, "queue owner payload");
1904
2217
  if (parsedMcpServers) options.mcpServers = parsedMcpServers;
2218
+ if (typeof record.mcpConfigPath === "string" && record.mcpConfigPath.length > 0) options.mcpConfigPath = record.mcpConfigPath;
2219
+ if (typeof record.mcpConfigFingerprint === "string" && record.mcpConfigFingerprint.length > 0) options.mcpConfigFingerprint = record.mcpConfigFingerprint;
1905
2220
  if (record.authCredentials && typeof record.authCredentials === "object") {
1906
2221
  const entries = Object.entries(record.authCredentials).filter(([, value]) => typeof value === "string");
1907
2222
  options.authCredentials = Object.fromEntries(entries);
@@ -1934,6 +2249,7 @@ function assignQueueOwnerSessionOptions(options, rawSessionOptions) {
1934
2249
  assignSessionAllowedTools(options.sessionOptions, sessionOpts.allowedTools);
1935
2250
  assignSessionMaxTurns(options.sessionOptions, sessionOpts.maxTurns);
1936
2251
  assignSessionSystemPrompt(options.sessionOptions, sessionOpts.systemPrompt);
2252
+ assignSessionEnv(options.sessionOptions, sessionOpts.env);
1937
2253
  }
1938
2254
  function assignSessionModel(options, value) {
1939
2255
  if (typeof value === "string" && value.trim().length > 0) options.model = value;
@@ -1952,60 +2268,43 @@ function assignSessionSystemPrompt(options, value) {
1952
2268
  const systemPrompt = asRecord(value);
1953
2269
  if (typeof systemPrompt?.append === "string") options.systemPrompt = { append: systemPrompt.append };
1954
2270
  }
1955
- async function runQueueOwnerFromEnv(env) {
1956
- const payload = env.ACPX_QUEUE_OWNER_PAYLOAD;
1957
- if (!payload) throw new Error("missing ACPX_QUEUE_OWNER_PAYLOAD");
1958
- await runSessionQueueOwner(parseQueueOwnerPayload(payload));
2271
+ function assignSessionEnv(options, value) {
2272
+ const env = asRecord(value);
2273
+ if (!env) return;
2274
+ const entries = Object.entries(env).filter((entry) => typeof entry[1] === "string");
2275
+ if (entries.length > 0) options.env = Object.fromEntries(entries);
1959
2276
  }
1960
- //#endregion
1961
- //#region src/version.ts
1962
- const UNKNOWN_VERSION = "0.0.0-unknown";
1963
- const MODULE_DIR = path.dirname(fileURLToPath(import.meta.url));
1964
- let cachedVersion = null;
1965
- function parseVersion(value) {
1966
- if (typeof value !== "string") return null;
1967
- const trimmed = value.trim();
1968
- return trimmed.length > 0 ? trimmed : null;
1969
- }
1970
- function readPackageVersion(packageJsonPath) {
1971
- try {
1972
- return parseVersion(JSON.parse(readFileSync(packageJsonPath, "utf8")).version);
1973
- } catch {
1974
- return null;
1975
- }
2277
+ async function runQueueOwnerFromEnv(env) {
2278
+ await runSessionQueueOwner(parseQueueOwnerPayload(await readQueueOwnerPayloadFromEnv(env)));
1976
2279
  }
1977
- function resolveVersionFromAncestors(startDir) {
1978
- let current = startDir;
1979
- while (true) {
1980
- const packageVersion = readPackageVersion(path.join(current, "package.json"));
1981
- if (packageVersion) return packageVersion;
1982
- const parent = path.dirname(current);
1983
- if (parent === current) return null;
1984
- current = parent;
2280
+ async function readQueueOwnerPayloadFromEnv(env) {
2281
+ const payloadFile = env[QUEUE_OWNER_PAYLOAD_FILE_ENV];
2282
+ if (payloadFile) {
2283
+ const payload = await fs$1.readFile(payloadFile, "utf8");
2284
+ await cleanupQueueOwnerPayloadFile(payloadFile).catch(() => {});
2285
+ return payload;
1985
2286
  }
2287
+ const payload = env[QUEUE_OWNER_PAYLOAD_ENV];
2288
+ if (!payload) throw new Error(`missing ${QUEUE_OWNER_PAYLOAD_ENV}`);
2289
+ return payload;
1986
2290
  }
1987
- function resolveAcpxVersion(params) {
1988
- const envVersion = resolvePackageEnvVersion(params?.env ?? process.env);
1989
- if (envVersion) return envVersion;
1990
- if (params?.packageJsonPath) return readPackageVersion(params.packageJsonPath) ?? UNKNOWN_VERSION;
1991
- return resolveVersionFromAncestors(MODULE_DIR) ?? UNKNOWN_VERSION;
1992
- }
1993
- function resolvePackageEnvVersion(env) {
1994
- const envPackageName = parseVersion(env.npm_package_name);
1995
- const envVersion = parseVersion(env.npm_package_version);
1996
- return envPackageName === "acpx" ? envVersion : null;
2291
+ async function cleanupQueueOwnerPayloadFile(payloadFile) {
2292
+ if (!isQueueOwnerPayloadFile(payloadFile)) return;
2293
+ await fs$1.unlink(payloadFile).catch(() => {});
2294
+ await fs$1.rmdir(path.dirname(payloadFile)).catch(() => {});
1997
2295
  }
1998
- function getAcpxVersion() {
1999
- if (cachedVersion) return cachedVersion;
2000
- cachedVersion = resolveAcpxVersion();
2001
- return cachedVersion;
2296
+ function isQueueOwnerPayloadFile(payloadFile) {
2297
+ const resolved = path.resolve(payloadFile);
2298
+ const payloadDir = path.dirname(resolved);
2299
+ return path.dirname(payloadDir) === path.resolve(os.tmpdir()) && path.basename(payloadDir).startsWith("acpx-queue-owner-") && path.basename(resolved) === "payload.json";
2002
2300
  }
2003
2301
  //#endregion
2004
2302
  //#region src/cli-core.ts
2005
- const TOP_LEVEL_VERBS = new Set([
2303
+ const TOP_LEVEL_VERBS = /* @__PURE__ */ new Set([
2006
2304
  "prompt",
2007
2305
  "exec",
2008
2306
  "cancel",
2307
+ "compare",
2009
2308
  "flow",
2010
2309
  "set-mode",
2011
2310
  "set",
@@ -2029,10 +2328,11 @@ const TOP_LEVEL_VERSION_VALUE_FLAG_VALUES = [
2029
2328
  "--append-system-prompt",
2030
2329
  "--prompt-retries",
2031
2330
  "--timeout",
2032
- "--ttl"
2331
+ "--ttl",
2332
+ "--mcp-config"
2033
2333
  ];
2034
2334
  const TOP_LEVEL_VERSION_VALUE_FLAGS = new Set(TOP_LEVEL_VERSION_VALUE_FLAG_VALUES);
2035
- const TOP_LEVEL_VERSION_BOOLEAN_FLAGS = new Set([
2335
+ const TOP_LEVEL_VERSION_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
2036
2336
  "--approve-all",
2037
2337
  "--approve-reads",
2038
2338
  "--deny-all",
@@ -2100,31 +2400,69 @@ function detectAgentToken(argv) {
2100
2400
  function detectInitialCwd(argv) {
2101
2401
  for (let index = 0; index < argv.length; index += 1) {
2102
2402
  const token = argv[index];
2103
- if (token === "--cwd") {
2104
- const next = argv[index + 1];
2105
- if (next && next !== "--") return path.resolve(next);
2106
- break;
2107
- }
2108
- if (token.startsWith("--cwd=")) {
2109
- const value = token.slice(6).trim();
2110
- if (value.length > 0) return path.resolve(value);
2111
- break;
2112
- }
2113
- if (token === "--") break;
2403
+ const scan = classifyTopLevelFlagScan(token);
2404
+ if (scan.stop) break;
2405
+ const cwd = readCwdFlagValue(token, argv[index + 1]);
2406
+ if (cwd) return path.resolve(cwd);
2407
+ if (isCwdFlagToken(token)) break;
2408
+ if (scan.skipNext) index += 1;
2114
2409
  }
2115
2410
  return process.cwd();
2116
2411
  }
2412
+ function detectMcpConfigPath(argv, cwd) {
2413
+ for (let index = 0; index < argv.length; index += 1) {
2414
+ const scan = scanMcpConfigToken(argv[index], argv[index + 1], cwd);
2415
+ if (scan.stop) return scan.path;
2416
+ if (scan.skipNext) index += 1;
2417
+ }
2418
+ }
2419
+ function scanMcpConfigToken(token, nextToken, cwd) {
2420
+ if (token === "--" || !token.startsWith("-") || token === "-") return { stop: true };
2421
+ if (token === "--mcp-config") return {
2422
+ path: resolveMcpConfigPath(nextToken, cwd),
2423
+ stop: true
2424
+ };
2425
+ if (token.startsWith("--mcp-config=")) return {
2426
+ path: resolveMcpConfigPath(token.slice(13), cwd),
2427
+ stop: true
2428
+ };
2429
+ return { skipNext: TOP_LEVEL_VERSION_VALUE_FLAGS.has(token) };
2430
+ }
2431
+ function resolveMcpConfigPath(value, cwd) {
2432
+ const trimmed = value?.trim();
2433
+ return trimmed && trimmed !== "--" ? path.resolve(cwd, trimmed) : void 0;
2434
+ }
2435
+ function isCwdFlagToken(token) {
2436
+ return token === "--cwd" || token.startsWith("--cwd=");
2437
+ }
2438
+ function readCwdFlagValue(token, nextToken) {
2439
+ const value = (token === "--cwd" ? nextToken : readInlineFlagValue(token, "--cwd"))?.trim();
2440
+ if (!value || value === "--") return;
2441
+ return value;
2442
+ }
2117
2443
  function detectRequestedOutputFormat(argv, fallback) {
2118
2444
  let detectedFormat = fallback;
2119
2445
  for (let index = 0; index < argv.length; index += 1) {
2120
2446
  const token = argv[index];
2121
- if (token === "--") break;
2447
+ const scan = classifyTopLevelFlagScan(token);
2448
+ if (scan.stop) break;
2122
2449
  if (isJsonStrictToken(token)) return "json";
2123
2450
  const format = readFormatFlagValue(token, argv[index + 1]);
2124
2451
  if (format) detectedFormat = format;
2452
+ if (scan.skipNext) index += 1;
2125
2453
  }
2126
2454
  return detectedFormat;
2127
2455
  }
2456
+ function classifyTopLevelFlagScan(token) {
2457
+ if (token === "--" || !token.startsWith("-") || token === "-") return {
2458
+ stop: true,
2459
+ skipNext: false
2460
+ };
2461
+ return {
2462
+ stop: false,
2463
+ skipNext: TOP_LEVEL_VERSION_VALUE_FLAGS.has(token)
2464
+ };
2465
+ }
2128
2466
  function readFormatFlagValue(token, nextToken) {
2129
2467
  const raw = token === "--format" ? nextToken : readInlineFlagValue(token, "--format");
2130
2468
  return isOutputFormat(raw) ? raw : void 0;
@@ -2142,8 +2480,10 @@ function isJsonStrictToken(token) {
2142
2480
  function detectJsonStrict(argv) {
2143
2481
  for (let index = 0; index < argv.length; index += 1) {
2144
2482
  const token = argv[index];
2145
- if (token === "--") break;
2483
+ const scan = classifyTopLevelFlagScan(token);
2484
+ if (scan.stop) break;
2146
2485
  if (isJsonStrictToken(token)) return true;
2486
+ if (scan.skipNext) index += 1;
2147
2487
  }
2148
2488
  return false;
2149
2489
  }
@@ -2255,7 +2595,8 @@ async function main(argv = process.argv) {
2255
2595
  return;
2256
2596
  }
2257
2597
  await maybeHandleSkillflag(normalizedArgv);
2258
- const config = await loadResolvedConfig(detectInitialCwd(rawArgs));
2598
+ const initialCwd = detectInitialCwd(rawArgs);
2599
+ const config = await loadResolvedConfig(initialCwd, { mcpConfigPath: detectMcpConfigPath(rawArgs, initialCwd) });
2259
2600
  const requestedJsonStrict = detectJsonStrict(rawArgs);
2260
2601
  const requestedOutputPolicy = {
2261
2602
  ...resolveOutputPolicy(detectRequestedOutputFormat(rawArgs, config.format), requestedJsonStrict),