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