acpx 0.10.0 → 0.11.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.
- package/README.md +22 -19
- package/dist/{cli-8dP_TqBp.js → cli-CC2w0U-A.js} +4 -4
- package/dist/{cli-8dP_TqBp.js.map → cli-CC2w0U-A.js.map} +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +299 -61
- package/dist/cli.js.map +1 -1
- package/dist/{client-C4iJBO0j.d.ts → client-j3sLnpcM.d.ts} +27 -4
- package/dist/client-j3sLnpcM.d.ts.map +1 -0
- package/dist/{flags--2oX_ubW.js → flags-BKjjl3tF.js} +4 -4
- package/dist/flags-BKjjl3tF.js.map +1 -0
- package/dist/{flows-e4umXVbY.js → flows-BabqiU0u.js} +4 -3
- package/dist/flows-BabqiU0u.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-BZrk9Mjz.js} +646 -164
- package/dist/live-checkpoint-BZrk9Mjz.js.map +1 -0
- package/dist/{output-Di77Yugq.js → output-D_BGt1YI.js} +170 -88
- package/dist/output-D_BGt1YI.js.map +1 -0
- package/dist/runtime.d.ts +71 -5
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +188 -32
- package/dist/runtime.js.map +1 -1
- package/dist/{session-options-Bh1bIqQ2.d.ts → session-options-Co1oGEK8.d.ts} +15 -2
- package/dist/{session-options-Bh1bIqQ2.d.ts.map → session-options-Co1oGEK8.d.ts.map} +1 -1
- package/package.json +17 -17
- package/skills/acpx/SKILL.md +55 -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/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
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-D_BGt1YI.js";
|
|
3
|
+
import { B as listSessions, Bt as OUTPUT_FORMATS, Et as normalizeAgentName$1, G as writeSessionRecord, Gt as AgentSpawnError, H as normalizeName, I as findGitRepositoryRoot, It as EXIT_CODES, L as findSession, M as getAcpxVersion, Ot as exitCodeForOutputErrorCode, R as findSessionByDirectoryWalk, Tt as listBuiltInAgents, Wt as AcpxOperationalError, _t as parsePromptSource, at as defaultSessionEventLog, bt as InterruptedError, ct as sessionEventLockPath, dt as isAcpJsonRpcMessage, gt as mergePromptSourceWithText, jt as normalizeOutputError, lt as sessionEventSegmentPath, mt as PromptInputValidationError, nt as serializeSessionRecordForDisk, rt as normalizeRuntimeSessionId, st as sessionEventActivePath, tt as parseSessionRecord, wt as DEFAULT_AGENT_NAME, xt as TimeoutError, yt as textPrompt } from "./live-checkpoint-BZrk9Mjz.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-BKjjl3tF.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";
|
|
@@ -10,6 +10,7 @@ import fs$1 from "node:fs/promises";
|
|
|
10
10
|
import os from "node:os";
|
|
11
11
|
import { 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-D_BGt1YI.js").then((n) => n.i);
|
|
390
391
|
return sessionModulePromise;
|
|
391
392
|
}
|
|
392
393
|
function loadOutputModule() {
|
|
393
|
-
outputModulePromise ??= import("./output-
|
|
394
|
+
outputModulePromise ??= import("./output-D_BGt1YI.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
|
|
@@ -569,7 +571,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
|
|
|
569
571
|
const globalFlags = resolveGlobalFlags(command, config);
|
|
570
572
|
const outputPolicy = resolveRequestedOutputPolicy(globalFlags);
|
|
571
573
|
const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
|
|
572
|
-
const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
|
|
574
|
+
const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
|
|
573
575
|
const prompt = await readPrompt(promptParts, flags.file, globalFlags.cwd);
|
|
574
576
|
const [{ createOutputFormatter }, { runOnce }] = await Promise.all([loadOutputModule(), loadSessionModule()]);
|
|
575
577
|
const outputFormatter = createOutputFormatter(outputPolicy.format, { suppressReads: outputPolicy.suppressReads });
|
|
@@ -726,7 +728,7 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
|
|
|
726
728
|
}
|
|
727
729
|
async function tryListAgentSessions(agent, flags, globalFlags, config) {
|
|
728
730
|
const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
|
|
729
|
-
const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
|
|
731
|
+
const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
|
|
730
732
|
const { listAgentSessions } = await loadSessionModule();
|
|
731
733
|
try {
|
|
732
734
|
return await listAgentSessions({
|
|
@@ -781,7 +783,7 @@ async function handleSessionsClose(explicitAgentName, sessionName, command, conf
|
|
|
781
783
|
async function handleSessionsNew(explicitAgentName, flags, command, config) {
|
|
782
784
|
const globalFlags = resolveGlobalFlags(command, config);
|
|
783
785
|
const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
|
|
784
|
-
const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
|
|
786
|
+
const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
|
|
785
787
|
const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
|
|
786
788
|
const [{ createSession, closeSession }, { printCreatedSessionBanner, printNewSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
|
|
787
789
|
const replaced = await findSession({
|
|
@@ -811,7 +813,7 @@ async function handleSessionsNew(explicitAgentName, flags, command, config) {
|
|
|
811
813
|
async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
|
|
812
814
|
const globalFlags = resolveGlobalFlags(command, config);
|
|
813
815
|
const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
|
|
814
|
-
const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
|
|
816
|
+
const permissionPolicy = await resolvePermissionPolicyFromFlags$1(globalFlags);
|
|
815
817
|
const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
|
|
816
818
|
const [{ ensureSession }, { printCreatedSessionBanner, printEnsuredSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
|
|
817
819
|
const result = await ensureSession(buildSessionStartOptions({
|
|
@@ -987,6 +989,285 @@ async function handleSessionsPrune(explicitAgentName, flags, command, config) {
|
|
|
987
989
|
}), globalFlags.format);
|
|
988
990
|
}
|
|
989
991
|
//#endregion
|
|
992
|
+
//#region src/cli/compare-command.ts
|
|
993
|
+
const DEFAULT_COMPARE_TIMEOUT_MS = 3e5;
|
|
994
|
+
const FINAL_MESSAGE_PREVIEW_CHARS = 200;
|
|
995
|
+
var CaptureFormatter = class {
|
|
996
|
+
setContext(_context) {}
|
|
997
|
+
onAcpMessage(_message) {}
|
|
998
|
+
onError(params) {}
|
|
999
|
+
onPermissionEscalation(_event) {}
|
|
1000
|
+
flush() {}
|
|
1001
|
+
};
|
|
1002
|
+
function asRecord$2(value) {
|
|
1003
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
1004
|
+
}
|
|
1005
|
+
function numberField(source, keys) {
|
|
1006
|
+
if (!source) return null;
|
|
1007
|
+
for (const key of keys) {
|
|
1008
|
+
const value = source[key];
|
|
1009
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1010
|
+
}
|
|
1011
|
+
return null;
|
|
1012
|
+
}
|
|
1013
|
+
function collapseWhitespace(value) {
|
|
1014
|
+
return value.replace(/\s+/g, " ").trim();
|
|
1015
|
+
}
|
|
1016
|
+
function truncate(value, maxChars) {
|
|
1017
|
+
if (value.length <= maxChars) return value;
|
|
1018
|
+
return `${value.slice(0, Math.max(0, maxChars - 3))}...`;
|
|
1019
|
+
}
|
|
1020
|
+
async function readStdin() {
|
|
1021
|
+
let data = "";
|
|
1022
|
+
for await (const chunk of process.stdin) data += String(chunk);
|
|
1023
|
+
return data;
|
|
1024
|
+
}
|
|
1025
|
+
async function readPromptFile(filePath, promptText, cwd) {
|
|
1026
|
+
const prompt = mergePromptSourceWithText(filePath === "-" ? await readStdin() : await fs$1.readFile(path.resolve(cwd, filePath), "utf8"), promptText);
|
|
1027
|
+
if (prompt.length === 0) throw new InvalidArgumentError("Prompt from --file is empty");
|
|
1028
|
+
return prompt;
|
|
1029
|
+
}
|
|
1030
|
+
async function readPromptFromStdin() {
|
|
1031
|
+
if (process.stdin.isTTY) throw new InvalidArgumentError("Prompt is required (pass as final argument, --file, or pipe via stdin)");
|
|
1032
|
+
const prompt = parsePromptSource(await readStdin());
|
|
1033
|
+
if (prompt.length === 0) throw new InvalidArgumentError("Prompt from stdin is empty");
|
|
1034
|
+
return prompt;
|
|
1035
|
+
}
|
|
1036
|
+
async function readPromptInput(filePath, promptText, cwd) {
|
|
1037
|
+
try {
|
|
1038
|
+
if (filePath) return await readPromptFile(filePath, promptText, cwd);
|
|
1039
|
+
const joined = promptText.trim();
|
|
1040
|
+
if (joined.length > 0) return textPrompt(joined);
|
|
1041
|
+
return await readPromptFromStdin();
|
|
1042
|
+
} catch (error) {
|
|
1043
|
+
if (error instanceof PromptInputValidationError) throw new InvalidArgumentError(error.message);
|
|
1044
|
+
throw error;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
function promptTokensAfterDoubleDash(command) {
|
|
1048
|
+
const commandName = command.name();
|
|
1049
|
+
const commandIndex = process.argv.findIndex((token, index) => index >= 2 && token === commandName);
|
|
1050
|
+
if (commandIndex < 0) return [];
|
|
1051
|
+
const delimiterIndex = process.argv.findIndex((token, index) => index > commandIndex && token === "--");
|
|
1052
|
+
return delimiterIndex < 0 ? [] : process.argv.slice(delimiterIndex + 1);
|
|
1053
|
+
}
|
|
1054
|
+
function splitCompareArgs(args, filePath, command) {
|
|
1055
|
+
if (filePath) {
|
|
1056
|
+
if (args.length === 0) throw new InvalidArgumentError("At least one agent is required");
|
|
1057
|
+
return {
|
|
1058
|
+
agents: args,
|
|
1059
|
+
promptText: ""
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
const promptTokens = promptTokensAfterDoubleDash(command);
|
|
1063
|
+
if (promptTokens.length > 0) {
|
|
1064
|
+
const agents = args.slice(0, -promptTokens.length);
|
|
1065
|
+
if (agents.length === 0) throw new InvalidArgumentError("At least one agent is required");
|
|
1066
|
+
return {
|
|
1067
|
+
agents,
|
|
1068
|
+
promptText: promptTokens.join(" ")
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
if (args.length < 2) throw new InvalidArgumentError("Usage: acpx compare <agent>... '<prompt>'");
|
|
1072
|
+
return {
|
|
1073
|
+
agents: args.slice(0, -1),
|
|
1074
|
+
promptText: args[args.length - 1] ?? ""
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
function captureUsage(update, capture) {
|
|
1078
|
+
const source = asRecord$2(asRecord$2(update._meta)?.usage) ?? update;
|
|
1079
|
+
capture.usage = {
|
|
1080
|
+
input_tokens: numberField(source, ["input_tokens", "inputTokens"]) ?? void 0,
|
|
1081
|
+
output_tokens: numberField(source, ["output_tokens", "outputTokens"]) ?? void 0,
|
|
1082
|
+
total_tokens: numberField(source, [
|
|
1083
|
+
"total_tokens",
|
|
1084
|
+
"totalTokens",
|
|
1085
|
+
"size",
|
|
1086
|
+
"used"
|
|
1087
|
+
]) ?? void 0
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
function captureSessionUpdate(notification, capture) {
|
|
1091
|
+
const update = asRecord$2(notification.update);
|
|
1092
|
+
if (!update) return;
|
|
1093
|
+
if (update.sessionUpdate === "agent_message_chunk") {
|
|
1094
|
+
const content = asRecord$2(update.content);
|
|
1095
|
+
if (content?.type === "text" && typeof content.text === "string") capture.finalMessage += content.text;
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
if (update.sessionUpdate === "usage_update") captureUsage(update, capture);
|
|
1099
|
+
}
|
|
1100
|
+
function rowStatusFromPermissionStats(stats) {
|
|
1101
|
+
return stats.denied + stats.cancelled > 0 ? "permission_denied" : "ok";
|
|
1102
|
+
}
|
|
1103
|
+
function sessionOptionsFromGlobalFlags(globalFlags) {
|
|
1104
|
+
return {
|
|
1105
|
+
model: globalFlags.model,
|
|
1106
|
+
allowedTools: globalFlags.allowedTools,
|
|
1107
|
+
maxTurns: globalFlags.maxTurns,
|
|
1108
|
+
systemPrompt: globalFlags.systemPrompt
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
async function resolvePermissionPolicyFromFlags(globalFlags) {
|
|
1112
|
+
try {
|
|
1113
|
+
return await loadPermissionPolicySpec(globalFlags.permissionPolicy, globalFlags.cwd);
|
|
1114
|
+
} catch (error) {
|
|
1115
|
+
throw new InvalidArgumentError(`Invalid permission policy: ${error instanceof Error ? error.message : String(error)}`);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
function buildSuccessRow(agentName, result, capture, startedAt) {
|
|
1119
|
+
const permissionStats = result.permissionStats;
|
|
1120
|
+
return {
|
|
1121
|
+
agent: agentName,
|
|
1122
|
+
status: result.stopReason === "cancelled" ? "cancelled" : rowStatusFromPermissionStats(permissionStats),
|
|
1123
|
+
stop_reason: result.stopReason,
|
|
1124
|
+
wall_ms: Math.round(performance.now() - startedAt),
|
|
1125
|
+
input_tokens: capture.usage.input_tokens ?? null,
|
|
1126
|
+
output_tokens: capture.usage.output_tokens ?? null,
|
|
1127
|
+
total_tokens: capture.usage.total_tokens ?? null,
|
|
1128
|
+
final_message: truncate(collapseWhitespace(capture.finalMessage), FINAL_MESSAGE_PREVIEW_CHARS),
|
|
1129
|
+
error: null,
|
|
1130
|
+
permission_requests: permissionStats.requested,
|
|
1131
|
+
permission_denied: permissionStats.denied + permissionStats.cancelled
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
function buildErrorRow(agentName, caught, capture, startedAt) {
|
|
1135
|
+
return {
|
|
1136
|
+
agent: agentName,
|
|
1137
|
+
status: caught instanceof TimeoutError ? "cancelled" : "error",
|
|
1138
|
+
stop_reason: null,
|
|
1139
|
+
wall_ms: Math.round(performance.now() - startedAt),
|
|
1140
|
+
input_tokens: capture.usage.input_tokens ?? null,
|
|
1141
|
+
output_tokens: capture.usage.output_tokens ?? null,
|
|
1142
|
+
total_tokens: capture.usage.total_tokens ?? null,
|
|
1143
|
+
final_message: truncate(collapseWhitespace(capture.finalMessage), FINAL_MESSAGE_PREVIEW_CHARS),
|
|
1144
|
+
error: truncate(collapseWhitespace(caught instanceof Error ? caught.message : String(caught)), FINAL_MESSAGE_PREVIEW_CHARS),
|
|
1145
|
+
permission_requests: 0,
|
|
1146
|
+
permission_denied: 0
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
async function runAgentForCompare(params) {
|
|
1150
|
+
const capture = {
|
|
1151
|
+
finalMessage: "",
|
|
1152
|
+
usage: {},
|
|
1153
|
+
errors: []
|
|
1154
|
+
};
|
|
1155
|
+
const formatter = new CaptureFormatter();
|
|
1156
|
+
const t0 = performance.now();
|
|
1157
|
+
try {
|
|
1158
|
+
const agent = resolveAgentInvocation(params.agentName, params.globalFlags, params.config);
|
|
1159
|
+
const result = await runOnce({
|
|
1160
|
+
agentCommand: agent.agentCommand,
|
|
1161
|
+
cwd: agent.cwd,
|
|
1162
|
+
prompt: params.prompt,
|
|
1163
|
+
mcpServers: params.config.mcpServers,
|
|
1164
|
+
permissionMode: resolvePermissionMode(params.globalFlags, params.config.defaultPermissions),
|
|
1165
|
+
nonInteractivePermissions: params.globalFlags.nonInteractivePermissions,
|
|
1166
|
+
permissionPolicy: params.permissionPolicy,
|
|
1167
|
+
authCredentials: params.config.auth,
|
|
1168
|
+
authPolicy: params.globalFlags.authPolicy,
|
|
1169
|
+
terminal: params.globalFlags.terminal,
|
|
1170
|
+
outputFormatter: formatter,
|
|
1171
|
+
suppressSdkConsoleErrors: true,
|
|
1172
|
+
timeoutMs: params.globalFlags.timeout ?? DEFAULT_COMPARE_TIMEOUT_MS,
|
|
1173
|
+
verbose: params.globalFlags.verbose,
|
|
1174
|
+
promptRetries: params.globalFlags.promptRetries,
|
|
1175
|
+
sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags),
|
|
1176
|
+
onSessionUpdate: (notification) => captureSessionUpdate(notification, capture)
|
|
1177
|
+
});
|
|
1178
|
+
return buildSuccessRow(params.agentName, result, capture, t0);
|
|
1179
|
+
} catch (caught) {
|
|
1180
|
+
return buildErrorRow(params.agentName, caught, capture, t0);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
function formatCell(value) {
|
|
1184
|
+
if (value == null || value === "") return "-";
|
|
1185
|
+
if (typeof value === "string") return collapseWhitespace(value);
|
|
1186
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
1187
|
+
return collapseWhitespace(JSON.stringify(value));
|
|
1188
|
+
}
|
|
1189
|
+
function renderTable(rows) {
|
|
1190
|
+
const headers = [
|
|
1191
|
+
"agent",
|
|
1192
|
+
"status",
|
|
1193
|
+
"wall_ms",
|
|
1194
|
+
"input",
|
|
1195
|
+
"output",
|
|
1196
|
+
"total",
|
|
1197
|
+
"permissions",
|
|
1198
|
+
"stop_reason",
|
|
1199
|
+
"final_message",
|
|
1200
|
+
"error"
|
|
1201
|
+
];
|
|
1202
|
+
const body = rows.map((row) => [
|
|
1203
|
+
row.agent,
|
|
1204
|
+
row.status,
|
|
1205
|
+
row.wall_ms,
|
|
1206
|
+
row.input_tokens,
|
|
1207
|
+
row.output_tokens,
|
|
1208
|
+
row.total_tokens,
|
|
1209
|
+
`${row.permission_denied}/${row.permission_requests}`,
|
|
1210
|
+
row.stop_reason,
|
|
1211
|
+
row.final_message,
|
|
1212
|
+
row.error
|
|
1213
|
+
]);
|
|
1214
|
+
const widths = headers.map((header, index) => Math.max(header.length, ...body.map((cells) => formatCell(cells[index]).length)));
|
|
1215
|
+
const formatRow = (cells) => cells.map((cell, index) => truncate(formatCell(cell), widths[index] ?? 24).padEnd(widths[index] ?? 24)).join(" ").trimEnd();
|
|
1216
|
+
return [
|
|
1217
|
+
formatRow(headers),
|
|
1218
|
+
widths.map((width) => "-".repeat(width)).join(" "),
|
|
1219
|
+
...body.map(formatRow)
|
|
1220
|
+
].join("\n");
|
|
1221
|
+
}
|
|
1222
|
+
function printRows(rows, format) {
|
|
1223
|
+
if (format === "json") {
|
|
1224
|
+
process.stdout.write(`${JSON.stringify(rows)}\n`);
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
if (format === "quiet") {
|
|
1228
|
+
for (const row of rows) process.stdout.write(`${row.agent}\t${row.status}\n`);
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
process.stdout.write(`${renderTable(rows)}\n`);
|
|
1232
|
+
}
|
|
1233
|
+
function updateCompareExitCode(rows) {
|
|
1234
|
+
if (rows.some((row) => row.status === "error")) {
|
|
1235
|
+
process.exitCode = EXIT_CODES.ERROR;
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
if (rows.some((row) => row.status === "permission_denied")) {
|
|
1239
|
+
process.exitCode = EXIT_CODES.PERMISSION_DENIED;
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
if (rows.some((row) => row.status === "cancelled")) process.exitCode = EXIT_CODES.TIMEOUT;
|
|
1243
|
+
}
|
|
1244
|
+
function resolvePromptFile(flags) {
|
|
1245
|
+
if (flags.file && flags.promptFile && flags.file !== flags.promptFile) throw new InvalidArgumentError("Use only one prompt file flag: --file or --prompt-file");
|
|
1246
|
+
return flags.file ?? flags.promptFile;
|
|
1247
|
+
}
|
|
1248
|
+
function registerCompareCommand(program, config) {
|
|
1249
|
+
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) {
|
|
1250
|
+
if (config.disableExec) throw new Error("compare subcommand is disabled by configuration (disableExec: true)");
|
|
1251
|
+
const globalFlags = resolveGlobalFlags(this, config);
|
|
1252
|
+
if (globalFlags.agent) throw new InvalidArgumentError("Do not combine compare with --agent; pass agent names");
|
|
1253
|
+
const outputPolicy = resolveOutputPolicy(flags.json === true ? "json" : globalFlags.format, globalFlags.jsonStrict === true);
|
|
1254
|
+
const promptFile = resolvePromptFile(flags);
|
|
1255
|
+
const { agents, promptText } = splitCompareArgs(args, promptFile, this);
|
|
1256
|
+
const prompt = await readPromptInput(promptFile, promptText, globalFlags.cwd);
|
|
1257
|
+
const permissionPolicy = await resolvePermissionPolicyFromFlags(globalFlags);
|
|
1258
|
+
const rows = [];
|
|
1259
|
+
for (const agentName of agents) rows.push(await runAgentForCompare({
|
|
1260
|
+
agentName,
|
|
1261
|
+
prompt,
|
|
1262
|
+
config,
|
|
1263
|
+
globalFlags,
|
|
1264
|
+
permissionPolicy
|
|
1265
|
+
}));
|
|
1266
|
+
printRows(rows, outputPolicy.format);
|
|
1267
|
+
updateCompareExitCode(rows);
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
//#endregion
|
|
990
1271
|
//#region src/mcp-servers.ts
|
|
991
1272
|
function asRecord$1(value) {
|
|
992
1273
|
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
@@ -1090,7 +1371,6 @@ function parseOptionalMcpServers(value, sourcePath, fieldName = "mcpServers") {
|
|
|
1090
1371
|
}
|
|
1091
1372
|
//#endregion
|
|
1092
1373
|
//#region src/cli/config.ts
|
|
1093
|
-
const DEFAULT_TIMEOUT_MS = void 0;
|
|
1094
1374
|
const DEFAULT_TTL_MS = 3e5;
|
|
1095
1375
|
const DEFAULT_PERMISSION_MODE = "approve-reads";
|
|
1096
1376
|
const DEFAULT_NON_INTERACTIVE_PERMISSION_POLICY = "deny";
|
|
@@ -1292,7 +1572,6 @@ function hasConfigKey(config, key) {
|
|
|
1292
1572
|
function resolveTimeoutMs(projectConfig, projectPath, globalConfig, globalPath) {
|
|
1293
1573
|
if (hasConfigKey(projectConfig, "timeout")) return parseTimeoutMs(projectConfig?.timeout, projectPath);
|
|
1294
1574
|
if (hasConfigKey(globalConfig, "timeout")) return parseTimeoutMs(globalConfig?.timeout, globalPath);
|
|
1295
|
-
return DEFAULT_TIMEOUT_MS;
|
|
1296
1575
|
}
|
|
1297
1576
|
function resolveMcpServers(projectConfig, projectPath, globalConfig, globalPath) {
|
|
1298
1577
|
if (hasConfigKey(projectConfig, "mcpServers")) return parseMcpServers(projectConfig?.mcpServers, projectPath);
|
|
@@ -1862,7 +2141,7 @@ function registerAgentCommand(program, agentName, config) {
|
|
|
1862
2141
|
}
|
|
1863
2142
|
function registerFlowCommand(program, config) {
|
|
1864
2143
|
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-
|
|
2144
|
+
const { handleFlowRun } = await import("./cli-CC2w0U-A.js");
|
|
1866
2145
|
await handleFlowRun(file, flags, this, config);
|
|
1867
2146
|
});
|
|
1868
2147
|
}
|
|
@@ -1877,6 +2156,7 @@ function registerDefaultCommands(program, config) {
|
|
|
1877
2156
|
});
|
|
1878
2157
|
registerSessionsCommand(program, void 0, config);
|
|
1879
2158
|
registerConfigCommand(program, config);
|
|
2159
|
+
registerCompareCommand(program, config);
|
|
1880
2160
|
registerFlowCommand(program, config);
|
|
1881
2161
|
}
|
|
1882
2162
|
//#endregion
|
|
@@ -1958,54 +2238,12 @@ async function runQueueOwnerFromEnv(env) {
|
|
|
1958
2238
|
await runSessionQueueOwner(parseQueueOwnerPayload(payload));
|
|
1959
2239
|
}
|
|
1960
2240
|
//#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
|
-
}
|
|
1976
|
-
}
|
|
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;
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
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;
|
|
1997
|
-
}
|
|
1998
|
-
function getAcpxVersion() {
|
|
1999
|
-
if (cachedVersion) return cachedVersion;
|
|
2000
|
-
cachedVersion = resolveAcpxVersion();
|
|
2001
|
-
return cachedVersion;
|
|
2002
|
-
}
|
|
2003
|
-
//#endregion
|
|
2004
2241
|
//#region src/cli-core.ts
|
|
2005
2242
|
const TOP_LEVEL_VERBS = new Set([
|
|
2006
2243
|
"prompt",
|
|
2007
2244
|
"exec",
|
|
2008
2245
|
"cancel",
|
|
2246
|
+
"compare",
|
|
2009
2247
|
"flow",
|
|
2010
2248
|
"set-mode",
|
|
2011
2249
|
"set",
|