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.
- package/README.md +25 -19
- package/dist/{cli-8dP_TqBp.js → cli-D4XUKXcD.js} +5 -5
- package/dist/{cli-8dP_TqBp.js.map → cli-D4XUKXcD.js.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +429 -88
- package/dist/cli.js.map +1 -1
- package/dist/{client-C4iJBO0j.d.ts → client-DIlpCkHw.d.ts} +38 -5
- package/dist/client-DIlpCkHw.d.ts.map +1 -0
- package/dist/{flags--2oX_ubW.js → flags-Dvgmpq_l.js} +5 -5
- package/dist/flags-Dvgmpq_l.js.map +1 -0
- package/dist/{flows-e4umXVbY.js → flows-Cvsc-_AW.js} +4 -3
- package/dist/flows-Cvsc-_AW.js.map +1 -0
- package/dist/flows.d.ts +1 -1
- package/dist/flows.d.ts.map +1 -1
- package/dist/flows.js +1 -1
- package/dist/{live-checkpoint-CuFft_Nd.js → live-checkpoint-BWkYxMeS.js} +848 -207
- package/dist/live-checkpoint-BWkYxMeS.js.map +1 -0
- package/dist/{output-Di77Yugq.js → output-BEv_BB7T.js} +359 -141
- package/dist/output-BEv_BB7T.js.map +1 -0
- package/dist/runtime.d.ts +71 -5
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +192 -35
- package/dist/runtime.js.map +1 -1
- package/dist/{session-options-Bh1bIqQ2.d.ts → session-options-jkYbBxGE.d.ts} +27 -2
- package/dist/session-options-jkYbBxGE.d.ts.map +1 -0
- package/package.json +21 -20
- package/skills/acpx/SKILL.md +58 -3
- package/dist/client-C4iJBO0j.d.ts.map +0 -1
- package/dist/flags--2oX_ubW.js.map +0 -1
- package/dist/flows-e4umXVbY.js.map +0 -1
- package/dist/live-checkpoint-CuFft_Nd.js.map +0 -1
- package/dist/output-Di77Yugq.js.map +0 -1
- 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-
|
|
3
|
-
import {
|
|
4
|
-
import { _ as
|
|
5
|
-
import {
|
|
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-
|
|
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-
|
|
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
|
|
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([
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
1956
|
-
const
|
|
1957
|
-
if (!
|
|
1958
|
-
|
|
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
|
-
|
|
1961
|
-
|
|
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
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
const
|
|
1981
|
-
|
|
1982
|
-
|
|
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
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
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
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
return
|
|
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
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
if (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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),
|