acpx 0.6.1 → 0.8.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 +8 -2
- package/dist/{cli-Ddxpnz9X.js → cli-BGYGVo3b.js} +35 -10
- package/dist/cli-BGYGVo3b.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +204 -19
- package/dist/cli.js.map +1 -1
- package/dist/{client-2fTFutRH.d.ts → client-FzXPdgP7.d.ts} +10 -4
- package/dist/client-FzXPdgP7.d.ts.map +1 -0
- package/dist/{flags-yXzUm7Aq.js → flags-D706STfk.js} +46 -6
- package/dist/flags-D706STfk.js.map +1 -0
- package/dist/{flows-CDsfbaA2.js → flows-hcjHmU7P.js} +117 -11
- package/dist/flows-hcjHmU7P.js.map +1 -0
- package/dist/flows.d.ts +19 -3
- package/dist/flows.d.ts.map +1 -1
- package/dist/flows.js +2 -2
- package/dist/{prompt-turn-BY5SwU1F.js → live-checkpoint-B9ctAuqV.js} +1335 -82
- package/dist/live-checkpoint-B9ctAuqV.js.map +1 -0
- package/dist/output-BL9XRWzS.js +3712 -0
- package/dist/output-BL9XRWzS.js.map +1 -0
- package/dist/runtime.d.ts +32 -6
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +169 -32
- package/dist/runtime.js.map +1 -1
- package/dist/{types-CVBeQyi3.d.ts → session-options-BJyG6zEH.d.ts} +56 -3
- package/dist/session-options-BJyG6zEH.d.ts.map +1 -0
- package/package.json +27 -25
- package/skills/acpx/SKILL.md +200 -9
- package/dist/cli-Ddxpnz9X.js.map +0 -1
- package/dist/client-2fTFutRH.d.ts.map +0 -1
- package/dist/flags-yXzUm7Aq.js.map +0 -1
- package/dist/flows-CDsfbaA2.js.map +0 -1
- package/dist/ipc-BruTG5Fb.js +0 -1241
- package/dist/ipc-BruTG5Fb.js.map +0 -1
- package/dist/jsonrpc-DSxh2w5R.js +0 -68
- package/dist/jsonrpc-DSxh2w5R.js.map +0 -1
- package/dist/output-DmHvT8vm.js +0 -807
- package/dist/output-DmHvT8vm.js.map +0 -1
- package/dist/perf-metrics-C2pXfxvR.js +0 -598
- package/dist/perf-metrics-C2pXfxvR.js.map +0 -1
- package/dist/prompt-turn-BY5SwU1F.js.map +0 -1
- package/dist/render-yqwtaOX4.js +0 -172
- package/dist/render-yqwtaOX4.js.map +0 -1
- package/dist/rolldown-runtime-CiIaOW0V.js +0 -13
- package/dist/session-BwgaPK8-.js +0 -1526
- package/dist/session-BwgaPK8-.js.map +0 -1
- package/dist/session-options-pCbHn_n7.d.ts +0 -13
- package/dist/session-options-pCbHn_n7.d.ts.map +0 -1
- package/dist/types-CVBeQyi3.d.ts.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { InitializeResponse, PromptResponse, SessionModelState, SetSessionConfigOptionResponse } from "@agentclientprotocol/sdk";
|
|
1
|
+
import { c as NonInteractivePermissionPolicy, d as PermissionStats, l as PermissionMode, p as PromptInput, r as AcpClientOptions } from "./session-options-BJyG6zEH.js";
|
|
2
|
+
import { InitializeResponse, PromptResponse, SessionConfigOption, SessionModelState, SetSessionConfigOptionResponse } from "@agentclientprotocol/sdk";
|
|
3
3
|
|
|
4
4
|
//#region src/acp/client.d.ts
|
|
5
5
|
type LoadSessionOptions = {
|
|
@@ -10,10 +10,12 @@ type LoadSessionOptions = {
|
|
|
10
10
|
type SessionCreateResult = {
|
|
11
11
|
sessionId: string;
|
|
12
12
|
agentSessionId?: string;
|
|
13
|
+
configOptions?: SessionConfigOption[];
|
|
13
14
|
models?: SessionModelState;
|
|
14
15
|
};
|
|
15
16
|
type SessionLoadResult = {
|
|
16
17
|
agentSessionId?: string;
|
|
18
|
+
configOptions?: SessionConfigOption[];
|
|
17
19
|
models?: SessionModelState;
|
|
18
20
|
};
|
|
19
21
|
type AgentDisconnectReason = "process_exit" | "process_close" | "pipe_close" | "connection_close";
|
|
@@ -47,6 +49,7 @@ declare class AcpClient {
|
|
|
47
49
|
private suppressReplaySessionUpdateMessages;
|
|
48
50
|
private activePrompt?;
|
|
49
51
|
private readonly cancellingSessionIds;
|
|
52
|
+
private readonly permissionAbortControllers;
|
|
50
53
|
private closing;
|
|
51
54
|
private agentStartedAt?;
|
|
52
55
|
private lastAgentExit?;
|
|
@@ -60,11 +63,12 @@ declare class AcpClient {
|
|
|
60
63
|
getAgentLifecycleSnapshot(): AgentLifecycleSnapshot;
|
|
61
64
|
supportsLoadSession(): boolean;
|
|
62
65
|
supportsCloseSession(): boolean;
|
|
63
|
-
setEventHandlers(handlers: Pick<AcpClientOptions, "onAcpMessage" | "onAcpOutputMessage" | "onSessionUpdate" | "onClientOperation">): void;
|
|
66
|
+
setEventHandlers(handlers: Pick<AcpClientOptions, "onAcpMessage" | "onAcpOutputMessage" | "onSessionUpdate" | "onClientOperation" | "onPermissionEscalation">): void;
|
|
64
67
|
clearEventHandlers(): void;
|
|
65
68
|
updateRuntimeOptions(options: {
|
|
66
69
|
permissionMode?: PermissionMode;
|
|
67
70
|
nonInteractivePermissions?: NonInteractivePermissionPolicy;
|
|
71
|
+
permissionPolicy?: AcpClientOptions["permissionPolicy"];
|
|
68
72
|
terminal?: boolean;
|
|
69
73
|
suppressSdkConsoleErrors?: boolean;
|
|
70
74
|
verbose?: boolean;
|
|
@@ -109,6 +113,8 @@ declare class AcpClient {
|
|
|
109
113
|
private handleWaitForTerminalExit;
|
|
110
114
|
private handleKillTerminal;
|
|
111
115
|
private handleReleaseTerminal;
|
|
116
|
+
private cancellationSignalForSession;
|
|
117
|
+
private abortAndDropPermissionSignal;
|
|
112
118
|
private recordPermissionDecision;
|
|
113
119
|
private recordPermissionError;
|
|
114
120
|
private handleSessionUpdate;
|
|
@@ -120,4 +126,4 @@ declare class AcpClient {
|
|
|
120
126
|
}
|
|
121
127
|
//#endregion
|
|
122
128
|
export { AcpClient as t };
|
|
123
|
-
//# sourceMappingURL=client-
|
|
129
|
+
//# sourceMappingURL=client-FzXPdgP7.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-FzXPdgP7.d.ts","names":[],"sources":["../src/acp/client.ts"],"mappings":"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"}
|
|
@@ -1,8 +1,45 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import "./session-BwgaPK8-.js";
|
|
1
|
+
import "./output-BL9XRWzS.js";
|
|
2
|
+
import { It as PERMISSION_POLICY_ACTIONS, Pt as OUTPUT_FORMATS, jt as NON_INTERACTIVE_PERMISSION_POLICIES, kt as AUTH_POLICIES, xt as resolveAgentCommand } from "./live-checkpoint-B9ctAuqV.js";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { InvalidArgumentError } from "commander";
|
|
5
|
+
import fs from "node:fs/promises";
|
|
6
|
+
//#region src/permission-policy.ts
|
|
7
|
+
function asRecord(value) {
|
|
8
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function parseRuleList(value, key, source) {
|
|
12
|
+
if (value == null) return;
|
|
13
|
+
if (!Array.isArray(value)) throw new Error(`${source}: permission policy ${key} must be an array of strings`);
|
|
14
|
+
return value.map((entry) => {
|
|
15
|
+
if (typeof entry !== "string" || entry.trim().length === 0) throw new Error(`${source}: permission policy ${key} must contain only non-empty strings`);
|
|
16
|
+
return entry.trim();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function parsePermissionPolicy(value, source = "permission policy") {
|
|
20
|
+
const record = asRecord(value);
|
|
21
|
+
if (!record) throw new Error(`${source}: permission policy must be a JSON object`);
|
|
22
|
+
const defaultAction = record.defaultAction;
|
|
23
|
+
if (defaultAction != null && (typeof defaultAction !== "string" || !PERMISSION_POLICY_ACTIONS.includes(defaultAction))) throw new Error(`${source}: permission policy defaultAction must be one of ${PERMISSION_POLICY_ACTIONS.join(", ")}`);
|
|
24
|
+
const policy = {};
|
|
25
|
+
const autoApprove = parseRuleList(record.autoApprove, "autoApprove", source);
|
|
26
|
+
const autoDeny = parseRuleList(record.autoDeny, "autoDeny", source);
|
|
27
|
+
const escalate = parseRuleList(record.escalate, "escalate", source);
|
|
28
|
+
if (autoApprove) policy.autoApprove = autoApprove;
|
|
29
|
+
if (autoDeny) policy.autoDeny = autoDeny;
|
|
30
|
+
if (escalate) policy.escalate = escalate;
|
|
31
|
+
if (typeof defaultAction === "string") policy.defaultAction = defaultAction;
|
|
32
|
+
return policy;
|
|
33
|
+
}
|
|
34
|
+
async function loadPermissionPolicySpec(spec, cwd) {
|
|
35
|
+
const trimmed = spec?.trim();
|
|
36
|
+
if (!trimmed) return;
|
|
37
|
+
if (trimmed.startsWith("{")) return parsePermissionPolicy(JSON.parse(trimmed), "--permission-policy");
|
|
38
|
+
const policyPath = path.resolve(cwd, trimmed);
|
|
39
|
+
const raw = await fs.readFile(policyPath, "utf8");
|
|
40
|
+
return parsePermissionPolicy(JSON.parse(raw), policyPath);
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
6
43
|
//#region src/cli/flags.ts
|
|
7
44
|
function hasExplicitPermissionModeFlag(flags) {
|
|
8
45
|
return flags.approveAll === true || flags.approveReads === true || flags.denyAll === true;
|
|
@@ -90,7 +127,7 @@ function resolvePermissionMode(flags, defaultMode) {
|
|
|
90
127
|
return defaultMode;
|
|
91
128
|
}
|
|
92
129
|
function addGlobalFlags(command) {
|
|
93
|
-
return command.option("--agent <command>", "Raw ACP agent command (escape hatch)").option("--cwd <dir>", "Working directory", process.cwd()).option("--auth-policy <policy>", "Authentication policy: skip or fail when auth is required", parseAuthPolicy).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("--non-interactive-permissions <policy>", "When prompting is unavailable: deny or fail", parseNonInteractivePermissionPolicy).option("--format <fmt>", "Output format: text, json, quiet", parseOutputFormat).option("--suppress-reads", "Suppress raw read-file contents in output").option("--model <id>", "Agent model id").option("--allowed-tools <list>", "Allowed tool names as a comma-separated list (use \"\" for no tools)", parseAllowedTools).option("--max-turns <count>", "Maximum turns for the session", parseMaxTurns).option("--system-prompt <text>", "Replace the agent system prompt (claude-agent-acp via ACP _meta.systemPrompt)", (value) => parseNonEmptyValue("System prompt", value)).option("--append-system-prompt <text>", "Append text to the agent system prompt (claude-agent-acp via ACP _meta.systemPrompt.append)", (value) => parseNonEmptyValue("Append system prompt", value)).option("--prompt-retries <count>", "Retry failed prompt turns on transient errors (default: 0)", parsePromptRetries).option("--json-strict", "Strict JSON mode: requires --format json and suppresses non-JSON stderr output").option("--no-terminal", "Do not advertise ACP terminal capability").option("--timeout <seconds>", "Maximum time to wait for agent response", parseTimeoutSeconds).option("--ttl <seconds>", "Queue owner idle TTL before shutdown (0 = keep alive forever) (default: 300)", parseTtlSeconds).option("--verbose", "Enable verbose debug logs");
|
|
130
|
+
return command.option("--agent <command>", "Raw ACP agent command (escape hatch)").option("--cwd <dir>", "Working directory", process.cwd()).option("--auth-policy <policy>", "Authentication policy: skip or fail when auth is required", parseAuthPolicy).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("--non-interactive-permissions <policy>", "When prompting is unavailable: deny or fail", parseNonInteractivePermissionPolicy).option("--permission-policy <json-or-file>", "Permission policy JSON or path (autoApprove, autoDeny, escalate, defaultAction)").option("--policy <json-or-file>", "Alias for --permission-policy").option("--format <fmt>", "Output format: text, json, quiet", parseOutputFormat).option("--suppress-reads", "Suppress raw read-file contents in output").option("--model <id>", "Agent model id").option("--allowed-tools <list>", "Allowed tool names as a comma-separated list (use \"\" for no tools)", parseAllowedTools).option("--max-turns <count>", "Maximum turns for the session", parseMaxTurns).option("--system-prompt <text>", "Replace the agent system prompt (claude-agent-acp via ACP _meta.systemPrompt)", (value) => parseNonEmptyValue("System prompt", value)).option("--append-system-prompt <text>", "Append text to the agent system prompt (claude-agent-acp via ACP _meta.systemPrompt.append)", (value) => parseNonEmptyValue("Append system prompt", value)).option("--prompt-retries <count>", "Retry failed prompt turns on transient errors (default: 0)", parsePromptRetries).option("--json-strict", "Strict JSON mode: requires --format json and suppresses non-JSON stderr output").option("--no-terminal", "Do not advertise ACP terminal capability").option("--timeout <seconds>", "Maximum time to wait for agent response", parseTimeoutSeconds).option("--ttl <seconds>", "Queue owner idle TTL before shutdown (0 = keep alive forever) (default: 300)", parseTtlSeconds).option("--verbose", "Enable verbose debug logs");
|
|
94
131
|
}
|
|
95
132
|
function addSessionOption(command) {
|
|
96
133
|
return command.option("-s, --session <name>", "Use named session instead of cwd default", parseSessionName).option("--no-wait", "Queue prompt and return immediately when another prompt is already running");
|
|
@@ -113,13 +150,16 @@ function resolveGlobalFlags(command, config) {
|
|
|
113
150
|
const format = opts.format ?? config.format ?? "text";
|
|
114
151
|
const jsonStrict = opts.jsonStrict === true;
|
|
115
152
|
const verbose = opts.verbose === true;
|
|
153
|
+
const permissionPolicy = typeof opts.permissionPolicy === "string" ? opts.permissionPolicy : typeof opts.policy === "string" ? opts.policy : void 0;
|
|
116
154
|
if (jsonStrict && format !== "json") throw new InvalidArgumentError("--json-strict requires --format json");
|
|
117
155
|
if (jsonStrict && verbose) throw new InvalidArgumentError("--json-strict cannot be combined with --verbose");
|
|
156
|
+
if (typeof opts.permissionPolicy === "string" && typeof opts.policy === "string" && opts.permissionPolicy !== opts.policy) throw new InvalidArgumentError("Use only one permission policy flag: --permission-policy or --policy");
|
|
118
157
|
return {
|
|
119
158
|
agent: opts.agent,
|
|
120
159
|
cwd: opts.cwd ?? process.cwd(),
|
|
121
160
|
authPolicy: opts.authPolicy ?? config.authPolicy,
|
|
122
161
|
nonInteractivePermissions: opts.nonInteractivePermissions ?? config.nonInteractivePermissions,
|
|
162
|
+
permissionPolicy,
|
|
123
163
|
jsonStrict,
|
|
124
164
|
suppressReads: opts.suppressReads === true,
|
|
125
165
|
terminal: opts.terminal === false ? false : void 0,
|
|
@@ -158,6 +198,6 @@ function resolveAgentInvocation(explicitAgentName, globalFlags, config) {
|
|
|
158
198
|
};
|
|
159
199
|
}
|
|
160
200
|
//#endregion
|
|
161
|
-
export {
|
|
201
|
+
export { resolveOutputPolicy as _, hasExplicitPermissionModeFlag as a, loadPermissionPolicySpec as b, parseHistoryLimit as c, parseOutputFormat as d, parsePruneBeforeDate as f, resolveGlobalFlags as g, resolveAgentInvocation as h, addSessionOption as i, parseMaxTurns as l, parseTtlSeconds as m, addPromptInputOption as n, parseAllowedTools as o, parseSessionName as p, addSessionNameOption as r, parseDaysOlderThan as s, addGlobalFlags as t, parseNonEmptyValue as u, resolvePermissionMode as v, resolveSessionNameFromFlags as y };
|
|
162
202
|
|
|
163
|
-
//# sourceMappingURL=flags-
|
|
203
|
+
//# sourceMappingURL=flags-D706STfk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flags-D706STfk.js","names":["resolveAgentCommandFromRegistry"],"sources":["../src/permission-policy.ts","../src/cli/flags.ts"],"sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n PERMISSION_POLICY_ACTIONS,\n type PermissionPolicy,\n type PermissionPolicyAction,\n} from \"./types.js\";\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as Record<string, unknown>;\n}\n\nfunction parseRuleList(value: unknown, key: string, source: string): string[] | undefined {\n if (value == null) {\n return undefined;\n }\n if (!Array.isArray(value)) {\n throw new Error(`${source}: permission policy ${key} must be an array of strings`);\n }\n\n const parsed = value.map((entry) => {\n if (typeof entry !== \"string\" || entry.trim().length === 0) {\n throw new Error(`${source}: permission policy ${key} must contain only non-empty strings`);\n }\n return entry.trim();\n });\n\n return parsed;\n}\n\nexport function parsePermissionPolicy(\n value: unknown,\n source = \"permission policy\",\n): PermissionPolicy {\n const record = asRecord(value);\n if (!record) {\n throw new Error(`${source}: permission policy must be a JSON object`);\n }\n\n const defaultAction = record.defaultAction;\n if (\n defaultAction != null &&\n (typeof defaultAction !== \"string\" ||\n !PERMISSION_POLICY_ACTIONS.includes(defaultAction as PermissionPolicyAction))\n ) {\n throw new Error(\n `${source}: permission policy defaultAction must be one of ${PERMISSION_POLICY_ACTIONS.join(\", \")}`,\n );\n }\n\n const policy: PermissionPolicy = {};\n const autoApprove = parseRuleList(record.autoApprove, \"autoApprove\", source);\n const autoDeny = parseRuleList(record.autoDeny, \"autoDeny\", source);\n const escalate = parseRuleList(record.escalate, \"escalate\", source);\n\n if (autoApprove) {\n policy.autoApprove = autoApprove;\n }\n if (autoDeny) {\n policy.autoDeny = autoDeny;\n }\n if (escalate) {\n policy.escalate = escalate;\n }\n if (typeof defaultAction === \"string\") {\n policy.defaultAction = defaultAction as PermissionPolicy[\"defaultAction\"];\n }\n\n return policy;\n}\n\nexport async function loadPermissionPolicySpec(\n spec: string | undefined,\n cwd: string,\n): Promise<PermissionPolicy | undefined> {\n const trimmed = spec?.trim();\n if (!trimmed) {\n return undefined;\n }\n\n if (trimmed.startsWith(\"{\")) {\n return parsePermissionPolicy(JSON.parse(trimmed), \"--permission-policy\");\n }\n\n const policyPath = path.resolve(cwd, trimmed);\n const raw = await fs.readFile(policyPath, \"utf8\");\n return parsePermissionPolicy(JSON.parse(raw), policyPath);\n}\n","import path from \"node:path\";\nimport { InvalidArgumentError } from \"commander\";\nimport type { Command } from \"commander\";\nimport {\n DEFAULT_AGENT_NAME,\n resolveAgentCommand as resolveAgentCommandFromRegistry,\n} from \"../agent-registry.js\";\nimport type { SystemPromptOption } from \"../runtime/engine/session-options.js\";\nimport { DEFAULT_QUEUE_OWNER_TTL_MS } from \"../session/session.js\";\nimport {\n AUTH_POLICIES,\n NON_INTERACTIVE_PERMISSION_POLICIES,\n OUTPUT_FORMATS,\n type AuthPolicy,\n type NonInteractivePermissionPolicy,\n type OutputFormat,\n type OutputPolicy,\n type PermissionMode,\n} from \"../types.js\";\nimport type { ResolvedAcpxConfig } from \"./config.js\";\n\nexport type PermissionFlags = {\n approveAll?: boolean;\n approveReads?: boolean;\n denyAll?: boolean;\n};\n\nexport function hasExplicitPermissionModeFlag(flags: PermissionFlags): boolean {\n return flags.approveAll === true || flags.approveReads === true || flags.denyAll === true;\n}\n\nexport type GlobalFlags = PermissionFlags & {\n agent?: string;\n cwd: string;\n authPolicy?: AuthPolicy;\n nonInteractivePermissions: NonInteractivePermissionPolicy;\n jsonStrict?: boolean;\n suppressReads?: boolean;\n terminal?: boolean;\n timeout?: number;\n ttl: number;\n verbose?: boolean;\n format: OutputFormat;\n model?: string;\n allowedTools?: string[];\n maxTurns?: number;\n systemPrompt?: SystemPromptOption;\n promptRetries?: number;\n permissionPolicy?: string;\n};\n\nexport type PromptFlags = {\n session?: string;\n wait?: boolean;\n file?: string;\n};\n\nexport type ExecFlags = {\n file?: string;\n};\n\nexport type SessionsNewFlags = {\n name?: string;\n resumeSession?: string;\n};\n\nexport type SessionsHistoryFlags = {\n limit: number;\n};\n\nexport type StatusFlags = {\n session?: string;\n};\n\nexport type SessionsPruneFlags = {\n dryRun?: boolean;\n before?: Date;\n olderThan?: number;\n includeHistory?: boolean;\n};\n\nexport function parseOutputFormat(value: string): OutputFormat {\n if (!OUTPUT_FORMATS.includes(value as OutputFormat)) {\n throw new InvalidArgumentError(\n `Invalid format \"${value}\". Expected one of: ${OUTPUT_FORMATS.join(\", \")}`,\n );\n }\n return value as OutputFormat;\n}\n\nexport function parseAuthPolicy(value: string): AuthPolicy {\n if (!AUTH_POLICIES.includes(value as AuthPolicy)) {\n throw new InvalidArgumentError(\n `Invalid auth policy \"${value}\". Expected one of: ${AUTH_POLICIES.join(\", \")}`,\n );\n }\n return value as AuthPolicy;\n}\n\nexport function parseNonInteractivePermissionPolicy(value: string): NonInteractivePermissionPolicy {\n if (!NON_INTERACTIVE_PERMISSION_POLICIES.includes(value as NonInteractivePermissionPolicy)) {\n throw new InvalidArgumentError(\n `Invalid non-interactive permission policy \"${value}\". Expected one of: ${NON_INTERACTIVE_PERMISSION_POLICIES.join(\", \")}`,\n );\n }\n return value as NonInteractivePermissionPolicy;\n}\n\nexport function parseTimeoutSeconds(value: string): number {\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(\"Timeout must be a positive number of seconds\");\n }\n return Math.round(parsed * 1000);\n}\n\nexport function parseTtlSeconds(value: string): number {\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new InvalidArgumentError(\"TTL must be a non-negative number of seconds\");\n }\n return Math.round(parsed * 1000);\n}\n\nexport function parseSessionName(value: string): string {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n throw new InvalidArgumentError(\"Session name must not be empty\");\n }\n return trimmed;\n}\n\nexport function parseNonEmptyValue(label: string, value: string): string {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n throw new InvalidArgumentError(`${label} must not be empty`);\n }\n return trimmed;\n}\n\nexport function parseHistoryLimit(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(\"Limit must be a positive integer\");\n }\n return parsed;\n}\n\nexport function parseDaysOlderThan(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(\"--older-than must be a positive integer number of days\");\n }\n return parsed;\n}\n\nexport function parsePruneBeforeDate(value: string): Date {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n throw new InvalidArgumentError(\n `--before must be a valid date (e.g. 2026-01-01 or 2026-01-01T00:00:00Z)`,\n );\n }\n return date;\n}\n\nexport function parseAllowedTools(value: string): string[] {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n return [];\n }\n\n const items = trimmed.split(\",\").map((item) => item.trim());\n if (items.some((item) => item.length === 0)) {\n throw new InvalidArgumentError(\n \"Allowed tools must be a comma-separated list without empty entries\",\n );\n }\n\n return items;\n}\n\nexport function parseMaxTurns(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(\"Max turns must be a positive integer\");\n }\n return parsed;\n}\n\nexport function resolveSystemPromptFlag(opts: {\n systemPrompt?: unknown;\n appendSystemPrompt?: unknown;\n}): SystemPromptOption | undefined {\n const replace =\n typeof opts.systemPrompt === \"string\" && opts.systemPrompt.length > 0\n ? opts.systemPrompt\n : undefined;\n const append =\n typeof opts.appendSystemPrompt === \"string\" && opts.appendSystemPrompt.length > 0\n ? opts.appendSystemPrompt\n : undefined;\n\n if (replace !== undefined && append !== undefined) {\n throw new InvalidArgumentError(\"Use only one of --system-prompt or --append-system-prompt\");\n }\n if (replace !== undefined) {\n return replace;\n }\n if (append !== undefined) {\n return { append };\n }\n return undefined;\n}\n\nexport function parsePromptRetries(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new InvalidArgumentError(\"Prompt retries must be a non-negative integer\");\n }\n return parsed;\n}\n\nexport function resolvePermissionMode(\n flags: PermissionFlags,\n defaultMode: PermissionMode,\n): PermissionMode {\n const selected = [flags.approveAll, flags.approveReads, flags.denyAll].filter(Boolean).length;\n\n if (selected > 1) {\n throw new InvalidArgumentError(\n \"Use only one permission mode: --approve-all, --approve-reads, or --deny-all\",\n );\n }\n\n if (flags.approveAll) {\n return \"approve-all\";\n }\n if (flags.approveReads) {\n return \"approve-reads\";\n }\n if (flags.denyAll) {\n return \"deny-all\";\n }\n\n return defaultMode;\n}\n\nexport function addGlobalFlags(command: Command): Command {\n return command\n .option(\"--agent <command>\", \"Raw ACP agent command (escape hatch)\")\n .option(\"--cwd <dir>\", \"Working directory\", process.cwd())\n .option(\n \"--auth-policy <policy>\",\n \"Authentication policy: skip or fail when auth is required\",\n parseAuthPolicy,\n )\n .option(\"--approve-all\", \"Auto-approve all permission requests\")\n .option(\"--approve-reads\", \"Auto-approve read/search requests and prompt for writes\")\n .option(\"--deny-all\", \"Deny all permission requests\")\n .option(\n \"--non-interactive-permissions <policy>\",\n \"When prompting is unavailable: deny or fail\",\n parseNonInteractivePermissionPolicy,\n )\n .option(\n \"--permission-policy <json-or-file>\",\n \"Permission policy JSON or path (autoApprove, autoDeny, escalate, defaultAction)\",\n )\n .option(\"--policy <json-or-file>\", \"Alias for --permission-policy\")\n .option(\"--format <fmt>\", \"Output format: text, json, quiet\", parseOutputFormat)\n .option(\"--suppress-reads\", \"Suppress raw read-file contents in output\")\n .option(\"--model <id>\", \"Agent model id\")\n .option(\n \"--allowed-tools <list>\",\n 'Allowed tool names as a comma-separated list (use \"\" for no tools)',\n parseAllowedTools,\n )\n .option(\"--max-turns <count>\", \"Maximum turns for the session\", parseMaxTurns)\n .option(\n \"--system-prompt <text>\",\n \"Replace the agent system prompt (claude-agent-acp via ACP _meta.systemPrompt)\",\n (value: string) => parseNonEmptyValue(\"System prompt\", value),\n )\n .option(\n \"--append-system-prompt <text>\",\n \"Append text to the agent system prompt (claude-agent-acp via ACP _meta.systemPrompt.append)\",\n (value: string) => parseNonEmptyValue(\"Append system prompt\", value),\n )\n .option(\n \"--prompt-retries <count>\",\n \"Retry failed prompt turns on transient errors (default: 0)\",\n parsePromptRetries,\n )\n .option(\n \"--json-strict\",\n \"Strict JSON mode: requires --format json and suppresses non-JSON stderr output\",\n )\n .option(\"--no-terminal\", \"Do not advertise ACP terminal capability\")\n .option(\"--timeout <seconds>\", \"Maximum time to wait for agent response\", parseTimeoutSeconds)\n .option(\n \"--ttl <seconds>\",\n \"Queue owner idle TTL before shutdown (0 = keep alive forever) (default: 300)\",\n parseTtlSeconds,\n )\n .option(\"--verbose\", \"Enable verbose debug logs\");\n}\n\nexport function addSessionOption(command: Command): Command {\n return command\n .option(\"-s, --session <name>\", \"Use named session instead of cwd default\", parseSessionName)\n .option(\n \"--no-wait\",\n \"Queue prompt and return immediately when another prompt is already running\",\n );\n}\n\nexport function addSessionNameOption(command: Command): Command {\n return command.option(\n \"-s, --session <name>\",\n \"Use named session instead of cwd default\",\n parseSessionName,\n );\n}\n\nexport function resolveSessionNameFromFlags(\n flags: StatusFlags,\n command: Command,\n): string | undefined {\n if (flags.session) {\n return flags.session;\n }\n\n // Commander parses options on the parent command when flags appear before the\n // subcommand (e.g. `acpx codex -s foo cancel`). Use optsWithGlobals() so\n // subcommands can still access those values.\n const allOpts = (command as unknown as { optsWithGlobals?: () => unknown }).optsWithGlobals?.();\n if (allOpts && typeof (allOpts as { session?: unknown }).session === \"string\") {\n return parseSessionName((allOpts as { session: string }).session);\n }\n\n const parentOpts = command.parent?.opts?.();\n if (parentOpts && typeof (parentOpts as { session?: unknown }).session === \"string\") {\n return parseSessionName((parentOpts as { session: string }).session);\n }\n\n return undefined;\n}\n\nexport function addPromptInputOption(command: Command): Command {\n return command.option(\"-f, --file <path>\", \"Read prompt text from file path (use - for stdin)\");\n}\n\nexport function resolveGlobalFlags(command: Command, config: ResolvedAcpxConfig): GlobalFlags {\n const opts = command.optsWithGlobals();\n const format = opts.format ?? config.format ?? \"text\";\n const jsonStrict = opts.jsonStrict === true;\n const verbose = opts.verbose === true;\n const permissionPolicy =\n typeof opts.permissionPolicy === \"string\"\n ? opts.permissionPolicy\n : typeof opts.policy === \"string\"\n ? opts.policy\n : undefined;\n\n if (jsonStrict && format !== \"json\") {\n throw new InvalidArgumentError(\"--json-strict requires --format json\");\n }\n\n if (jsonStrict && verbose) {\n throw new InvalidArgumentError(\"--json-strict cannot be combined with --verbose\");\n }\n\n if (\n typeof opts.permissionPolicy === \"string\" &&\n typeof opts.policy === \"string\" &&\n opts.permissionPolicy !== opts.policy\n ) {\n throw new InvalidArgumentError(\n \"Use only one permission policy flag: --permission-policy or --policy\",\n );\n }\n\n return {\n agent: opts.agent,\n cwd: opts.cwd ?? process.cwd(),\n authPolicy: opts.authPolicy ?? config.authPolicy,\n nonInteractivePermissions: opts.nonInteractivePermissions ?? config.nonInteractivePermissions,\n permissionPolicy,\n jsonStrict,\n suppressReads: opts.suppressReads === true,\n terminal: opts.terminal === false ? false : undefined,\n timeout: opts.timeout ?? config.timeoutMs,\n ttl: opts.ttl ?? config.ttlMs ?? DEFAULT_QUEUE_OWNER_TTL_MS,\n verbose,\n format,\n model: typeof opts.model === \"string\" ? parseNonEmptyValue(\"Model\", opts.model) : undefined,\n allowedTools: Array.isArray(opts.allowedTools) ? opts.allowedTools : undefined,\n maxTurns: typeof opts.maxTurns === \"number\" ? opts.maxTurns : undefined,\n systemPrompt: resolveSystemPromptFlag(opts),\n promptRetries: typeof opts.promptRetries === \"number\" ? opts.promptRetries : undefined,\n approveAll: opts.approveAll ? true : undefined,\n approveReads: opts.approveReads ? true : undefined,\n denyAll: opts.denyAll ? true : undefined,\n };\n}\n\nexport function resolveOutputPolicy(format: OutputFormat, jsonStrict: boolean): OutputPolicy {\n return {\n format,\n jsonStrict,\n suppressReads: false,\n suppressNonJsonStderr: jsonStrict,\n queueErrorAlreadyEmitted: format !== \"quiet\",\n suppressSdkConsoleErrors: jsonStrict,\n };\n}\n\nexport function resolveAgentInvocation(\n explicitAgentName: string | undefined,\n globalFlags: GlobalFlags,\n config: ResolvedAcpxConfig,\n): {\n agentName: string;\n agentCommand: string;\n cwd: string;\n} {\n const override = globalFlags.agent?.trim();\n if (override && explicitAgentName) {\n throw new InvalidArgumentError(\"Do not combine positional agent with --agent override\");\n }\n\n const agentName = explicitAgentName ?? config.defaultAgent ?? DEFAULT_AGENT_NAME;\n const agentCommand =\n override && override.length > 0\n ? override\n : resolveAgentCommandFromRegistry(agentName, config.agents);\n\n return {\n agentName,\n agentCommand,\n cwd: path.resolve(globalFlags.cwd),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { c as createSessionWithClient, i as sendSessionDirect, l as cancelSessionPrompt, r as runOnce } from "./session-BwgaPK8-.js";
|
|
4
|
-
import { t as createOutputFormatter } from "./output-DmHvT8vm.js";
|
|
1
|
+
import { d as createSessionWithClient, f as cancelSessionPrompt, o as runOnce, s as sendSessionDirect, t as createOutputFormatter } from "./output-BL9XRWzS.js";
|
|
2
|
+
import { Ft as PERMISSION_MODES, H as resolveSessionRecord, K as defaultSessionEventLog, Lt as SESSION_RECORD_SCHEMA, _t as withTimeout, b as recordPromptSubmission, ft as promptToDisplayText, g as cloneSessionAcpxState, gt as withInterrupt, ht as TimeoutError, mt as InterruptedError, pt as textPrompt, v as createSessionConversation, x as recordSessionUpdate, y as recordClientOperation } from "./live-checkpoint-B9ctAuqV.js";
|
|
5
3
|
import path from "node:path";
|
|
6
4
|
import fs from "node:fs/promises";
|
|
7
5
|
import os from "node:os";
|
|
@@ -465,7 +463,7 @@ function normalizeFlowRunTitle(value) {
|
|
|
465
463
|
return trimmed ? trimmed : void 0;
|
|
466
464
|
}
|
|
467
465
|
function createRunId(flowName) {
|
|
468
|
-
return `${isoNow$1().replaceAll(":", "").replaceAll(".", "")}-${flowName
|
|
466
|
+
return `${isoNow$1().replaceAll(":", "").replaceAll(".", "")}-${slugifyAsciiIdPart(flowName)}-${randomUUID().slice(0, 8)}`;
|
|
469
467
|
}
|
|
470
468
|
function createSessionBindingKey(agentCommand, cwd, handle) {
|
|
471
469
|
return `${agentCommand}::${cwd}::${handle}`;
|
|
@@ -474,7 +472,31 @@ function createSessionName(flowName, handle, cwd, runId) {
|
|
|
474
472
|
return `${flowName}-${handle}-${stableShortHash(cwd)}-${runId.slice(-8)}`;
|
|
475
473
|
}
|
|
476
474
|
function createSessionBundleId(handle, key) {
|
|
477
|
-
return `${handle
|
|
475
|
+
return `${slugifyAsciiIdPart(handle) || "session"}-${stableShortHash(key)}`;
|
|
476
|
+
}
|
|
477
|
+
function slugifyAsciiIdPart(value) {
|
|
478
|
+
let slug = "";
|
|
479
|
+
let lastWasSeparator = false;
|
|
480
|
+
for (const char of value) {
|
|
481
|
+
const safeChar = toLowerAsciiAlphaNumeric(char);
|
|
482
|
+
if (safeChar) {
|
|
483
|
+
slug += safeChar;
|
|
484
|
+
lastWasSeparator = false;
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
if (slug.length > 0 && !lastWasSeparator) {
|
|
488
|
+
slug += "-";
|
|
489
|
+
lastWasSeparator = true;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return lastWasSeparator ? slug.slice(0, -1) : slug;
|
|
493
|
+
}
|
|
494
|
+
function toLowerAsciiAlphaNumeric(char) {
|
|
495
|
+
const code = char.charCodeAt(0);
|
|
496
|
+
if (code >= 48 && code <= 57) return char;
|
|
497
|
+
if (code >= 65 && code <= 90) return String.fromCharCode(code + 32);
|
|
498
|
+
if (code >= 97 && code <= 122) return char;
|
|
499
|
+
return null;
|
|
478
500
|
}
|
|
479
501
|
function createIsolatedSessionBinding(flowName, runId, attemptId, profile, agent) {
|
|
480
502
|
const key = `isolated::${attemptId}`;
|
|
@@ -965,6 +987,7 @@ var FlowRunner = class {
|
|
|
965
987
|
permissionMode;
|
|
966
988
|
mcpServers;
|
|
967
989
|
nonInteractivePermissions;
|
|
990
|
+
permissionPolicy;
|
|
968
991
|
authCredentials;
|
|
969
992
|
authPolicy;
|
|
970
993
|
timeoutMs;
|
|
@@ -981,6 +1004,7 @@ var FlowRunner = class {
|
|
|
981
1004
|
this.permissionMode = options.permissionMode;
|
|
982
1005
|
this.mcpServers = options.mcpServers;
|
|
983
1006
|
this.nonInteractivePermissions = options.nonInteractivePermissions;
|
|
1007
|
+
this.permissionPolicy = options.permissionPolicy;
|
|
984
1008
|
this.authCredentials = options.authCredentials;
|
|
985
1009
|
this.authPolicy = options.authPolicy;
|
|
986
1010
|
this.timeoutMs = options.timeoutMs;
|
|
@@ -1497,6 +1521,7 @@ var FlowRunner = class {
|
|
|
1497
1521
|
mcpServers: this.mcpServers,
|
|
1498
1522
|
permissionMode: this.permissionMode,
|
|
1499
1523
|
nonInteractivePermissions: this.nonInteractivePermissions,
|
|
1524
|
+
permissionPolicy: this.permissionPolicy,
|
|
1500
1525
|
authCredentials: this.authCredentials,
|
|
1501
1526
|
authPolicy: this.authPolicy,
|
|
1502
1527
|
timeoutMs,
|
|
@@ -1545,6 +1570,7 @@ var FlowRunner = class {
|
|
|
1545
1570
|
mcpServers: this.mcpServers,
|
|
1546
1571
|
permissionMode: this.permissionMode,
|
|
1547
1572
|
nonInteractivePermissions: this.nonInteractivePermissions,
|
|
1573
|
+
permissionPolicy: this.permissionPolicy,
|
|
1548
1574
|
authCredentials: this.authCredentials,
|
|
1549
1575
|
authPolicy: this.authPolicy,
|
|
1550
1576
|
outputFormatter: capture.formatter,
|
|
@@ -1608,6 +1634,7 @@ var FlowRunner = class {
|
|
|
1608
1634
|
mcpServers: this.mcpServers,
|
|
1609
1635
|
permissionMode: this.permissionMode,
|
|
1610
1636
|
nonInteractivePermissions: this.nonInteractivePermissions,
|
|
1637
|
+
permissionPolicy: this.permissionPolicy,
|
|
1611
1638
|
authCredentials: this.authCredentials,
|
|
1612
1639
|
authPolicy: this.authPolicy,
|
|
1613
1640
|
outputFormatter: capture.formatter,
|
|
@@ -1677,9 +1704,9 @@ function parseJsonObject(text, options = {}) {
|
|
|
1677
1704
|
const direct = tryParse(trimmed);
|
|
1678
1705
|
if (direct.ok) return direct.value;
|
|
1679
1706
|
if (mode === "fenced" || mode === "compat") {
|
|
1680
|
-
const
|
|
1681
|
-
if (
|
|
1682
|
-
const fenced = tryParse(
|
|
1707
|
+
const fencedText = extractFencedJsonText(trimmed);
|
|
1708
|
+
if (fencedText !== null) {
|
|
1709
|
+
const fenced = tryParse(fencedText);
|
|
1683
1710
|
if (fenced.ok) return fenced.value;
|
|
1684
1711
|
}
|
|
1685
1712
|
}
|
|
@@ -1705,6 +1732,19 @@ function tryParse(text) {
|
|
|
1705
1732
|
return { ok: false };
|
|
1706
1733
|
}
|
|
1707
1734
|
}
|
|
1735
|
+
function extractFencedJsonText(text) {
|
|
1736
|
+
const openingFenceIndex = text.indexOf("```");
|
|
1737
|
+
if (openingFenceIndex === -1) return null;
|
|
1738
|
+
let contentStart = openingFenceIndex + 3;
|
|
1739
|
+
if (text.slice(contentStart, contentStart + 4).toLowerCase() === "json" && isFenceWhitespace(text[contentStart + 4])) contentStart += 4;
|
|
1740
|
+
while (isFenceWhitespace(text[contentStart])) contentStart += 1;
|
|
1741
|
+
const closingFenceIndex = text.indexOf("```", contentStart);
|
|
1742
|
+
if (closingFenceIndex === -1) return null;
|
|
1743
|
+
return text.slice(contentStart, closingFenceIndex).trim();
|
|
1744
|
+
}
|
|
1745
|
+
function isFenceWhitespace(char) {
|
|
1746
|
+
return char === " " || char === "\n" || char === "\r" || char === " ";
|
|
1747
|
+
}
|
|
1708
1748
|
function extractBalancedJsonCandidates(text) {
|
|
1709
1749
|
const candidates = [];
|
|
1710
1750
|
for (let index = 0; index < text.length; index += 1) {
|
|
@@ -1743,6 +1783,72 @@ function scanBalanced(text, startIndex) {
|
|
|
1743
1783
|
return null;
|
|
1744
1784
|
}
|
|
1745
1785
|
//#endregion
|
|
1746
|
-
|
|
1786
|
+
//#region src/flows/decision.ts
|
|
1787
|
+
const DEFAULT_FIELD = "route";
|
|
1788
|
+
const SIMPLE_FIELD_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
1789
|
+
function decision(definition) {
|
|
1790
|
+
const { question, choices, field: fieldOverride, ...acpOptions } = definition;
|
|
1791
|
+
const field = normalizeField(fieldOverride);
|
|
1792
|
+
assertValidChoices(choices);
|
|
1793
|
+
const allowed = new Set(choices);
|
|
1794
|
+
return acp({
|
|
1795
|
+
...acpOptions,
|
|
1796
|
+
async prompt(context) {
|
|
1797
|
+
return formatDecisionPrompt(typeof question === "function" ? await question(context) : question, choices, field);
|
|
1798
|
+
},
|
|
1799
|
+
parse(text) {
|
|
1800
|
+
const raw = extractJsonObject(text);
|
|
1801
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) throw new Error(`Decision response must be a JSON object, got ${typeof raw}`);
|
|
1802
|
+
const value = raw[field];
|
|
1803
|
+
if (typeof value !== "string" || !allowed.has(value)) {
|
|
1804
|
+
const allowedLabels = choices.map((choice) => JSON.stringify(choice)).join(", ");
|
|
1805
|
+
throw new Error(`Decision returned invalid ${field}=${JSON.stringify(value)}; expected one of ${allowedLabels}`);
|
|
1806
|
+
}
|
|
1807
|
+
return raw;
|
|
1808
|
+
}
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1811
|
+
function decisionEdge(args) {
|
|
1812
|
+
const field = normalizeField(args.field);
|
|
1813
|
+
assertValidChoices(args.choices);
|
|
1814
|
+
for (const choice of args.choices) if (!Object.hasOwn(args.cases, choice)) throw new Error(`Decision edge is missing case for choice ${JSON.stringify(choice)}`);
|
|
1815
|
+
return {
|
|
1816
|
+
from: args.from,
|
|
1817
|
+
switch: {
|
|
1818
|
+
on: `$.${field}`,
|
|
1819
|
+
cases: args.cases
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
function assertValidChoices(choices) {
|
|
1824
|
+
if (choices.length === 0) throw new Error("Decision choices must include at least one value");
|
|
1825
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1826
|
+
for (const choice of choices) {
|
|
1827
|
+
if (typeof choice !== "string" || choice.length === 0) throw new Error("Decision choices must be non-empty strings");
|
|
1828
|
+
if (seen.has(choice)) throw new Error(`Decision choices must be unique; duplicate ${JSON.stringify(choice)}`);
|
|
1829
|
+
seen.add(choice);
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
function normalizeField(fieldOverride) {
|
|
1833
|
+
const field = fieldOverride ?? DEFAULT_FIELD;
|
|
1834
|
+
if (!SIMPLE_FIELD_PATTERN.test(field)) throw new Error(`Decision field must be a simple JSON key matching ${SIMPLE_FIELD_PATTERN.source}`);
|
|
1835
|
+
return field;
|
|
1836
|
+
}
|
|
1837
|
+
function formatDecisionPrompt(question, choices, field) {
|
|
1838
|
+
const allowed = choices.map((choice) => JSON.stringify(choice)).join(" | ");
|
|
1839
|
+
return [
|
|
1840
|
+
question,
|
|
1841
|
+
"",
|
|
1842
|
+
"Return exactly one JSON object with this shape:",
|
|
1843
|
+
"{",
|
|
1844
|
+
` ${JSON.stringify(field)}: ${allowed},`,
|
|
1845
|
+
" \"reason\": \"short justification\"",
|
|
1846
|
+
"}",
|
|
1847
|
+
"",
|
|
1848
|
+
"Do not include any other text outside the JSON object."
|
|
1849
|
+
].join("\n");
|
|
1850
|
+
}
|
|
1851
|
+
//#endregion
|
|
1852
|
+
export { parseStrictJsonObject as a, validateFlowDefinition as c, checkpoint as d, compute as f, isDefinedFlow as h, parseJsonObject as i, acp as l, shell as m, decisionEdge as n, FlowRunner as o, defineFlow as p, extractJsonObject as r, flowRunsBaseDir as s, decision as t, action as u };
|
|
1747
1853
|
|
|
1748
|
-
//# sourceMappingURL=flows-
|
|
1854
|
+
//# sourceMappingURL=flows-hcjHmU7P.js.map
|