acpx 0.5.3 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +12 -4
  2. package/dist/{cli-ChWsO-bb.js → cli-Ddxpnz9X.js} +4 -4
  3. package/dist/{cli-ChWsO-bb.js.map → cli-Ddxpnz9X.js.map} +1 -1
  4. package/dist/cli.d.ts +1 -1
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +147 -75
  7. package/dist/cli.js.map +1 -1
  8. package/dist/{client-D-4_aZf2.d.ts → client-2fTFutRH.d.ts} +4 -2
  9. package/dist/client-2fTFutRH.d.ts.map +1 -0
  10. package/dist/{flags-ceSqz2T6.js → flags-yXzUm7Aq.js} +25 -6
  11. package/dist/flags-yXzUm7Aq.js.map +1 -0
  12. package/dist/{flows-_KmnuUXd.js → flows-CDsfbaA2.js} +13 -6
  13. package/dist/flows-CDsfbaA2.js.map +1 -0
  14. package/dist/flows.d.ts +2 -8
  15. package/dist/flows.d.ts.map +1 -1
  16. package/dist/flows.js +1 -1
  17. package/dist/{ipc-BM335WFg.js → ipc-BruTG5Fb.js} +50 -19
  18. package/dist/ipc-BruTG5Fb.js.map +1 -0
  19. package/dist/{output-C4QhjpM6.js → output-DmHvT8vm.js} +141 -12
  20. package/dist/output-DmHvT8vm.js.map +1 -0
  21. package/dist/{perf-metrics-D0um6IR6.js → perf-metrics-C2pXfxvR.js} +12 -2
  22. package/dist/perf-metrics-C2pXfxvR.js.map +1 -0
  23. package/dist/{prompt-turn-CXMtXBl-.js → prompt-turn-BY5SwU1F.js} +256 -80
  24. package/dist/prompt-turn-BY5SwU1F.js.map +1 -0
  25. package/dist/{render-Br-kVPK_.js → render-yqwtaOX4.js} +35 -3
  26. package/dist/{render-Br-kVPK_.js.map → render-yqwtaOX4.js.map} +1 -1
  27. package/dist/runtime.d.ts +84 -10
  28. package/dist/runtime.d.ts.map +1 -1
  29. package/dist/runtime.js +425 -190
  30. package/dist/runtime.js.map +1 -1
  31. package/dist/{session-BtwAKtJ3.js → session-BwgaPK8-.js} +119 -81
  32. package/dist/session-BwgaPK8-.js.map +1 -0
  33. package/dist/session-options-pCbHn_n7.d.ts +13 -0
  34. package/dist/session-options-pCbHn_n7.d.ts.map +1 -0
  35. package/dist/{types-yxf-gcOE.d.ts → types-CVBeQyi3.d.ts} +9 -1
  36. package/dist/types-CVBeQyi3.d.ts.map +1 -0
  37. package/package.json +21 -21
  38. package/skills/acpx/SKILL.md +9 -4
  39. package/dist/client-D-4_aZf2.d.ts.map +0 -1
  40. package/dist/flags-ceSqz2T6.js.map +0 -1
  41. package/dist/flows-_KmnuUXd.js.map +0 -1
  42. package/dist/ipc-BM335WFg.js.map +0 -1
  43. package/dist/output-C4QhjpM6.js.map +0 -1
  44. package/dist/perf-metrics-D0um6IR6.js.map +0 -1
  45. package/dist/prompt-turn-CXMtXBl-.js.map +0 -1
  46. package/dist/session-BtwAKtJ3.js.map +0 -1
  47. package/dist/types-yxf-gcOE.d.ts.map +0 -1
package/README.md CHANGED
@@ -33,7 +33,7 @@ One command surface for Pi, OpenClaw ACP, Codex, Claude, and other ACP-compatibl
33
33
  - **Prompt from file/stdin**: `--file <path>` or piped stdin for prompt content
34
34
  - **Config files**: global + project JSON config with `acpx config show|init`
35
35
  - **Session inspect/history**: `sessions show` and `sessions history --limit <n>`
36
- - **Local status checks**: `status` reports running/dead/no-session, pid, uptime, last prompt
36
+ - **Local status checks**: `status` reports running/idle/dead/no-session, pid, uptime, last prompt
37
37
  - **Client methods**: stable `fs/*` and `terminal/*` handlers with permission controls and cwd sandboxing
38
38
  - **Auth handshake**: stable `authenticate` support via env/config credentials
39
39
  - **Structured output**: typed ACP messages (thinking, tool calls, diffs) instead of ANSI scraping
@@ -271,7 +271,7 @@ Supported keys:
271
271
  "timeout": null,
272
272
  "format": "text",
273
273
  "agents": {
274
- "my-custom": { "command": "./bin/my-acp-server" }
274
+ "my-custom": { "command": "./bin/my-acp-server", "args": ["acp"] }
275
275
  },
276
276
  "auth": {
277
277
  "my_auth_method_id": "credential-value"
@@ -281,6 +281,11 @@ Supported keys:
281
281
 
282
282
  Use `acpx config show` to inspect the resolved result and `acpx config init` to create the global template.
283
283
 
284
+ For ACP `authenticate` handshakes, use either config `auth` entries or explicit
285
+ `ACPX_AUTH_<METHOD_ID>` environment variables such as `ACPX_AUTH_OPENAI_API_KEY`.
286
+ Ambient provider env vars such as `OPENAI_API_KEY` are still passed through to
287
+ child agents, but they do not trigger ACP auth-method selection on their own.
288
+
284
289
  ## Output formats
285
290
 
286
291
  ```bash
@@ -319,8 +324,11 @@ JSON events include a stable envelope for correlation:
319
324
  }
320
325
  ```
321
326
 
322
- Session-control JSON payloads (`sessions new|ensure`, `status`) may also include
323
- `runtimeSessionId` when the adapter exposes a provider-native session ID.
327
+ Session-control JSON payloads (`sessions new|ensure`, `status`) always include
328
+ `acpxRecordId` and `acpxSessionId`. They include `agentSessionId` only when the
329
+ adapter exposes a provider-native session ID. The text/quiet session id is the
330
+ local acpx record id; do not assume it can be passed to the native provider CLI
331
+ unless `agentSessionId` is present.
324
332
 
325
333
  ## Built-in agents and custom servers
326
334
 
@@ -1,6 +1,6 @@
1
- import { b as permissionModeSatisfies } from "./prompt-turn-CXMtXBl-.js";
2
- import { a as hasExplicitPermissionModeFlag, f as resolveAgentInvocation, h as resolvePermissionMode, m as resolveOutputPolicy, p as resolveGlobalFlags } from "./flags-ceSqz2T6.js";
3
- import { i as FlowRunner, o as validateFlowDefinition, p as isDefinedFlow } from "./flows-_KmnuUXd.js";
1
+ import { C as permissionModeSatisfies } from "./prompt-turn-BY5SwU1F.js";
2
+ import { _ as resolvePermissionMode, a as hasExplicitPermissionModeFlag, g as resolveOutputPolicy, h as resolveGlobalFlags, m as resolveAgentInvocation } from "./flags-yXzUm7Aq.js";
3
+ import { i as FlowRunner, o as validateFlowDefinition, p as isDefinedFlow } from "./flows-CDsfbaA2.js";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import path from "node:path";
6
6
  import { InvalidArgumentError } from "commander";
@@ -169,4 +169,4 @@ function printFlowRunResult(result, globalFlags) {
169
169
  //#endregion
170
170
  export { handleFlowRun };
171
171
 
172
- //# sourceMappingURL=cli-ChWsO-bb.js.map
172
+ //# sourceMappingURL=cli-Ddxpnz9X.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli-ChWsO-bb.js","names":[],"sources":["../src/flows/cli.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { InvalidArgumentError, type Command } from \"commander\";\nimport type { ResolvedAcpxConfig } from \"../cli/config.js\";\nimport {\n hasExplicitPermissionModeFlag,\n resolveAgentInvocation,\n resolveGlobalFlags,\n resolveOutputPolicy,\n resolvePermissionMode,\n type GlobalFlags,\n} from \"../cli/flags.js\";\nimport { type FlowDefinition, FlowRunner } from \"../flows.js\";\nimport { permissionModeSatisfies } from \"../permissions.js\";\nimport type { PermissionMode } from \"../types.js\";\nimport { isDefinedFlow } from \"./authoring.js\";\nimport { validateFlowDefinition } from \"./graph.js\";\n\ntype FlowRunFlags = {\n inputJson?: string;\n inputFile?: string;\n defaultAgent?: string;\n};\n\nconst FLOW_RUNTIME_SPECIFIER = \"acpx/flows\";\nconst TEXT_MODULE_EXTENSIONS = new Set([\".js\", \".mjs\", \".cjs\", \".ts\", \".tsx\", \".mts\", \".cts\"]);\n\nexport async function handleFlowRun(\n flowFile: string,\n flags: FlowRunFlags,\n command: Command,\n config: ResolvedAcpxConfig,\n): Promise<void> {\n const globalFlags = resolveGlobalFlags(command, config);\n const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);\n const outputPolicy = resolveOutputPolicy(globalFlags.format, globalFlags.jsonStrict === true);\n const input = await readFlowInput(flags);\n const flowPath = path.resolve(flowFile);\n const flow = await loadFlowModule(flowPath);\n assertFlowPermissionRequirements(flow, permissionMode, globalFlags);\n\n const runner = new FlowRunner({\n resolveAgent: (profile?: string) => {\n return resolveAgentInvocation(profile ?? flags.defaultAgent, globalFlags, config);\n },\n permissionMode,\n mcpServers: config.mcpServers,\n nonInteractivePermissions: globalFlags.nonInteractivePermissions,\n authCredentials: config.auth,\n authPolicy: globalFlags.authPolicy,\n timeoutMs: globalFlags.timeout,\n ttlMs: globalFlags.ttl,\n verbose: globalFlags.verbose,\n suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,\n sessionOptions: {\n model: globalFlags.model,\n allowedTools: globalFlags.allowedTools,\n maxTurns: globalFlags.maxTurns,\n },\n });\n\n const result = await runner.run(flow, input, {\n flowPath,\n });\n\n printFlowRunResult(result, globalFlags);\n}\n\nfunction assertFlowPermissionRequirements(\n flow: FlowDefinition,\n permissionMode: PermissionMode,\n globalFlags: GlobalFlags,\n): void {\n const permissions = flow.permissions;\n if (!permissions) {\n return;\n }\n\n if (permissions.requireExplicitGrant && !hasExplicitPermissionModeFlag(globalFlags)) {\n throw new InvalidArgumentError(\n buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, true),\n );\n }\n\n if (!permissionModeSatisfies(permissionMode, permissions.requiredMode)) {\n throw new InvalidArgumentError(\n buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, false),\n );\n }\n}\n\nfunction buildFlowPermissionFailureMessage(\n flow: FlowDefinition,\n requiredMode: PermissionMode,\n reason?: string,\n explicit = false,\n): string {\n return [\n explicit\n ? `Flow \"${flow.name}\" requires an explicit ${requiredMode} grant.`\n : `Flow \"${flow.name}\" requires permission mode ${requiredMode}.`,\n `Rerun with --${requiredMode}.`,\n ...(reason ? [`Reason: ${reason}`] : []),\n ].join(\" \");\n}\n\nasync function readFlowInput(flags: FlowRunFlags): Promise<unknown> {\n if (flags.inputJson && flags.inputFile) {\n throw new InvalidArgumentError(\"Use only one of --input-json or --input-file\");\n }\n\n if (flags.inputJson) {\n return parseJsonInput(flags.inputJson, \"--input-json\");\n }\n\n if (flags.inputFile) {\n const inputPath = path.resolve(flags.inputFile);\n const payload = await fs.readFile(inputPath, \"utf8\");\n return parseJsonInput(payload, \"--input-file\");\n }\n\n return {};\n}\n\nasync function loadFlowModule(flowPath: string): Promise<FlowDefinition> {\n const extension = path.extname(flowPath).toLowerCase();\n const prepared = await prepareFlowModuleImport(flowPath, extension);\n try {\n const module = await loadFlowRuntimeModule(prepared.flowUrl, extension);\n\n const candidate = findFlowDefinition(module);\n if (!candidate) {\n throw new Error(\n `Flow module must export default defineFlow({...}) from \"acpx/flows\": ${flowPath}`,\n );\n }\n validateFlowDefinition(candidate);\n return candidate;\n } finally {\n await prepared.cleanup?.();\n }\n}\n\nasync function prepareFlowModuleImport(\n flowPath: string,\n extension: string,\n): Promise<{\n flowUrl: string;\n cleanup?: () => Promise<void>;\n}> {\n const flowUrl = pathToFileURL(flowPath).href;\n if (!TEXT_MODULE_EXTENSIONS.has(extension)) {\n return { flowUrl };\n }\n\n const source = await fs.readFile(flowPath, \"utf8\");\n if (!source.includes(FLOW_RUNTIME_SPECIFIER)) {\n return { flowUrl };\n }\n\n const runtimeSpecifier = resolveFlowRuntimeImportSpecifier();\n const rewritten = source.replaceAll(\n /([\"'])acpx\\/flows\\1/g,\n (_match, quote: string) => `${quote}${runtimeSpecifier}${quote}`,\n );\n if (rewritten === source) {\n return { flowUrl };\n }\n\n const tempPath = path.join(path.dirname(flowPath), `.acpx-flow-load-${randomUUID()}${extension}`);\n await fs.writeFile(tempPath, rewritten, \"utf8\");\n return {\n flowUrl: pathToFileURL(tempPath).href,\n cleanup: async () => {\n await fs.rm(tempPath, { force: true });\n },\n };\n}\n\nfunction resolveFlowRuntimeImportSpecifier(): string {\n const selfPath = fileURLToPath(import.meta.url);\n\n if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.ts`)) {\n return new URL(\"../flows.ts\", import.meta.url).href;\n }\n if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.js`)) {\n return new URL(\"../flows.js\", import.meta.url).href;\n }\n return new URL(\"./flows.js\", import.meta.url).href;\n}\n\nasync function loadFlowRuntimeModule(\n flowUrl: string,\n extension: string,\n): Promise<{\n default?: unknown;\n \"module.exports\"?: unknown;\n}> {\n if (extension === \".ts\" || extension === \".tsx\" || extension === \".mts\" || extension === \".cts\") {\n const { tsImport } = (await import(\"tsx/esm/api\")) as {\n tsImport: (\n specifier: string,\n parentURL: string,\n ) => Promise<{\n default?: unknown;\n \"module.exports\"?: unknown;\n }>;\n };\n return (await tsImport(flowUrl, import.meta.url)) as {\n default?: unknown;\n \"module.exports\"?: unknown;\n };\n }\n\n return (await import(flowUrl)) as {\n default?: unknown;\n \"module.exports\"?: unknown;\n };\n}\n\nfunction findFlowDefinition(module: {\n default?: unknown;\n \"module.exports\"?: unknown;\n}): FlowDefinition | null {\n const candidates = [\n module.default,\n module[\"module.exports\"],\n getNestedDefault(module.default),\n getNestedDefault(module[\"module.exports\"]),\n ];\n\n for (const candidate of candidates) {\n if (isDefinedFlow(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction getNestedDefault(value: unknown): unknown {\n if (!value || typeof value !== \"object\" || !(\"default\" in value)) {\n return null;\n }\n return (value as { default?: unknown }).default ?? null;\n}\n\nfunction parseJsonInput(raw: string, label: string): unknown {\n try {\n return JSON.parse(raw);\n } catch (error) {\n throw new InvalidArgumentError(\n `${label} must contain valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nfunction printFlowRunResult(\n result: Awaited<ReturnType<FlowRunner[\"run\"]>>,\n globalFlags: GlobalFlags,\n): void {\n const payload = {\n action: \"flow_run_result\",\n runId: result.state.runId,\n flowName: result.state.flowName,\n runTitle: result.state.runTitle,\n flowPath: result.state.flowPath,\n status: result.state.status,\n currentNode: result.state.currentNode,\n currentNodeType: result.state.currentNodeType,\n currentNodeStartedAt: result.state.currentNodeStartedAt,\n lastHeartbeatAt: result.state.lastHeartbeatAt,\n statusDetail: result.state.statusDetail,\n waitingOn: result.state.waitingOn,\n runDir: result.runDir,\n outputs: result.state.outputs,\n sessionBindings: result.state.sessionBindings,\n };\n\n if (globalFlags.format === \"json\") {\n process.stdout.write(`${JSON.stringify(payload)}\\n`);\n return;\n }\n\n if (globalFlags.format === \"quiet\") {\n process.stdout.write(`${result.state.runId}\\n`);\n return;\n }\n\n process.stdout.write(`runId: ${payload.runId}\\n`);\n process.stdout.write(`flow: ${payload.flowName}\\n`);\n if (payload.runTitle) {\n process.stdout.write(`title: ${payload.runTitle}\\n`);\n }\n process.stdout.write(`status: ${payload.status}\\n`);\n process.stdout.write(`runDir: ${payload.runDir}\\n`);\n if (payload.currentNode) {\n process.stdout.write(`currentNode: ${payload.currentNode}\\n`);\n }\n if (payload.statusDetail) {\n process.stdout.write(`statusDetail: ${payload.statusDetail}\\n`);\n }\n if (payload.waitingOn) {\n process.stdout.write(`waitingOn: ${payload.waitingOn}\\n`);\n }\n process.stdout.write(`${JSON.stringify(payload.outputs, null, 2)}\\n`);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli-Ddxpnz9X.js","names":[],"sources":["../src/flows/cli.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { InvalidArgumentError, type Command } from \"commander\";\nimport type { ResolvedAcpxConfig } from \"../cli/config.js\";\nimport {\n hasExplicitPermissionModeFlag,\n resolveAgentInvocation,\n resolveGlobalFlags,\n resolveOutputPolicy,\n resolvePermissionMode,\n type GlobalFlags,\n} from \"../cli/flags.js\";\nimport { type FlowDefinition, FlowRunner } from \"../flows.js\";\nimport { permissionModeSatisfies } from \"../permissions.js\";\nimport type { PermissionMode } from \"../types.js\";\nimport { isDefinedFlow } from \"./authoring.js\";\nimport { validateFlowDefinition } from \"./graph.js\";\n\ntype FlowRunFlags = {\n inputJson?: string;\n inputFile?: string;\n defaultAgent?: string;\n};\n\nconst FLOW_RUNTIME_SPECIFIER = \"acpx/flows\";\nconst TEXT_MODULE_EXTENSIONS = new Set([\".js\", \".mjs\", \".cjs\", \".ts\", \".tsx\", \".mts\", \".cts\"]);\n\nexport async function handleFlowRun(\n flowFile: string,\n flags: FlowRunFlags,\n command: Command,\n config: ResolvedAcpxConfig,\n): Promise<void> {\n const globalFlags = resolveGlobalFlags(command, config);\n const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);\n const outputPolicy = resolveOutputPolicy(globalFlags.format, globalFlags.jsonStrict === true);\n const input = await readFlowInput(flags);\n const flowPath = path.resolve(flowFile);\n const flow = await loadFlowModule(flowPath);\n assertFlowPermissionRequirements(flow, permissionMode, globalFlags);\n\n const runner = new FlowRunner({\n resolveAgent: (profile?: string) => {\n return resolveAgentInvocation(profile ?? flags.defaultAgent, globalFlags, config);\n },\n permissionMode,\n mcpServers: config.mcpServers,\n nonInteractivePermissions: globalFlags.nonInteractivePermissions,\n authCredentials: config.auth,\n authPolicy: globalFlags.authPolicy,\n timeoutMs: globalFlags.timeout,\n ttlMs: globalFlags.ttl,\n verbose: globalFlags.verbose,\n suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,\n sessionOptions: {\n model: globalFlags.model,\n allowedTools: globalFlags.allowedTools,\n maxTurns: globalFlags.maxTurns,\n },\n });\n\n const result = await runner.run(flow, input, {\n flowPath,\n });\n\n printFlowRunResult(result, globalFlags);\n}\n\nfunction assertFlowPermissionRequirements(\n flow: FlowDefinition,\n permissionMode: PermissionMode,\n globalFlags: GlobalFlags,\n): void {\n const permissions = flow.permissions;\n if (!permissions) {\n return;\n }\n\n if (permissions.requireExplicitGrant && !hasExplicitPermissionModeFlag(globalFlags)) {\n throw new InvalidArgumentError(\n buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, true),\n );\n }\n\n if (!permissionModeSatisfies(permissionMode, permissions.requiredMode)) {\n throw new InvalidArgumentError(\n buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, false),\n );\n }\n}\n\nfunction buildFlowPermissionFailureMessage(\n flow: FlowDefinition,\n requiredMode: PermissionMode,\n reason?: string,\n explicit = false,\n): string {\n return [\n explicit\n ? `Flow \"${flow.name}\" requires an explicit ${requiredMode} grant.`\n : `Flow \"${flow.name}\" requires permission mode ${requiredMode}.`,\n `Rerun with --${requiredMode}.`,\n ...(reason ? [`Reason: ${reason}`] : []),\n ].join(\" \");\n}\n\nasync function readFlowInput(flags: FlowRunFlags): Promise<unknown> {\n if (flags.inputJson && flags.inputFile) {\n throw new InvalidArgumentError(\"Use only one of --input-json or --input-file\");\n }\n\n if (flags.inputJson) {\n return parseJsonInput(flags.inputJson, \"--input-json\");\n }\n\n if (flags.inputFile) {\n const inputPath = path.resolve(flags.inputFile);\n const payload = await fs.readFile(inputPath, \"utf8\");\n return parseJsonInput(payload, \"--input-file\");\n }\n\n return {};\n}\n\nasync function loadFlowModule(flowPath: string): Promise<FlowDefinition> {\n const extension = path.extname(flowPath).toLowerCase();\n const prepared = await prepareFlowModuleImport(flowPath, extension);\n try {\n const module = await loadFlowRuntimeModule(prepared.flowUrl, extension);\n\n const candidate = findFlowDefinition(module);\n if (!candidate) {\n throw new Error(\n `Flow module must export default defineFlow({...}) from \"acpx/flows\": ${flowPath}`,\n );\n }\n validateFlowDefinition(candidate);\n return candidate;\n } finally {\n await prepared.cleanup?.();\n }\n}\n\nasync function prepareFlowModuleImport(\n flowPath: string,\n extension: string,\n): Promise<{\n flowUrl: string;\n cleanup?: () => Promise<void>;\n}> {\n const flowUrl = pathToFileURL(flowPath).href;\n if (!TEXT_MODULE_EXTENSIONS.has(extension)) {\n return { flowUrl };\n }\n\n const source = await fs.readFile(flowPath, \"utf8\");\n if (!source.includes(FLOW_RUNTIME_SPECIFIER)) {\n return { flowUrl };\n }\n\n const runtimeSpecifier = resolveFlowRuntimeImportSpecifier();\n const rewritten = source.replaceAll(\n /([\"'])acpx\\/flows\\1/g,\n (_match, quote: string) => `${quote}${runtimeSpecifier}${quote}`,\n );\n if (rewritten === source) {\n return { flowUrl };\n }\n\n const tempPath = path.join(path.dirname(flowPath), `.acpx-flow-load-${randomUUID()}${extension}`);\n await fs.writeFile(tempPath, rewritten, \"utf8\");\n return {\n flowUrl: pathToFileURL(tempPath).href,\n cleanup: async () => {\n await fs.rm(tempPath, { force: true });\n },\n };\n}\n\nfunction resolveFlowRuntimeImportSpecifier(): string {\n const selfPath = fileURLToPath(import.meta.url);\n\n if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.ts`)) {\n return new URL(\"../flows.ts\", import.meta.url).href;\n }\n if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.js`)) {\n return new URL(\"../flows.js\", import.meta.url).href;\n }\n return new URL(\"./flows.js\", import.meta.url).href;\n}\n\nasync function loadFlowRuntimeModule(\n flowUrl: string,\n extension: string,\n): Promise<{\n default?: unknown;\n \"module.exports\"?: unknown;\n}> {\n if (extension === \".ts\" || extension === \".tsx\" || extension === \".mts\" || extension === \".cts\") {\n const { tsImport } = (await import(\"tsx/esm/api\")) as {\n tsImport: (\n specifier: string,\n parentURL: string,\n ) => Promise<{\n default?: unknown;\n \"module.exports\"?: unknown;\n }>;\n };\n return (await tsImport(flowUrl, import.meta.url)) as {\n default?: unknown;\n \"module.exports\"?: unknown;\n };\n }\n\n return (await import(flowUrl)) as {\n default?: unknown;\n \"module.exports\"?: unknown;\n };\n}\n\nfunction findFlowDefinition(module: {\n default?: unknown;\n \"module.exports\"?: unknown;\n}): FlowDefinition | null {\n const candidates = [\n module.default,\n module[\"module.exports\"],\n getNestedDefault(module.default),\n getNestedDefault(module[\"module.exports\"]),\n ];\n\n for (const candidate of candidates) {\n if (isDefinedFlow(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction getNestedDefault(value: unknown): unknown {\n if (!value || typeof value !== \"object\" || !(\"default\" in value)) {\n return null;\n }\n return (value as { default?: unknown }).default ?? null;\n}\n\nfunction parseJsonInput(raw: string, label: string): unknown {\n try {\n return JSON.parse(raw);\n } catch (error) {\n throw new InvalidArgumentError(\n `${label} must contain valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nfunction printFlowRunResult(\n result: Awaited<ReturnType<FlowRunner[\"run\"]>>,\n globalFlags: GlobalFlags,\n): void {\n const payload = {\n action: \"flow_run_result\",\n runId: result.state.runId,\n flowName: result.state.flowName,\n runTitle: result.state.runTitle,\n flowPath: result.state.flowPath,\n status: result.state.status,\n currentNode: result.state.currentNode,\n currentNodeType: result.state.currentNodeType,\n currentNodeStartedAt: result.state.currentNodeStartedAt,\n lastHeartbeatAt: result.state.lastHeartbeatAt,\n statusDetail: result.state.statusDetail,\n waitingOn: result.state.waitingOn,\n runDir: result.runDir,\n outputs: result.state.outputs,\n sessionBindings: result.state.sessionBindings,\n };\n\n if (globalFlags.format === \"json\") {\n process.stdout.write(`${JSON.stringify(payload)}\\n`);\n return;\n }\n\n if (globalFlags.format === \"quiet\") {\n process.stdout.write(`${result.state.runId}\\n`);\n return;\n }\n\n process.stdout.write(`runId: ${payload.runId}\\n`);\n process.stdout.write(`flow: ${payload.flowName}\\n`);\n if (payload.runTitle) {\n process.stdout.write(`title: ${payload.runTitle}\\n`);\n }\n process.stdout.write(`status: ${payload.status}\\n`);\n process.stdout.write(`runDir: ${payload.runDir}\\n`);\n if (payload.currentNode) {\n process.stdout.write(`currentNode: ${payload.currentNode}\\n`);\n }\n if (payload.statusDetail) {\n process.stdout.write(`statusDetail: ${payload.statusDetail}\\n`);\n }\n if (payload.waitingOn) {\n process.stdout.write(`waitingOn: ${payload.waitingOn}\\n`);\n }\n process.stdout.write(`${JSON.stringify(payload.outputs, null, 2)}\\n`);\n}\n"],"mappings":"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"}
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { s as SessionRecord } from "./types-yxf-gcOE.js";
1
+ import { s as SessionRecord } from "./types-CVBeQyi3.js";
2
2
  import { Command } from "commander";
3
3
 
4
4
  //#region src/cli/flags.d.ts
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","names":[],"sources":["../src/cli/flags.ts","../src/cli/output/render.ts"],"mappings":";;;;iBAyGgB,eAAA,CAAgB,KAAA;AAAA,iBAgChB,iBAAA,CAAkB,KAAA;AAAA,iBAgBlB,aAAA,CAAc,KAAA;;;KCvIzB,uBAAA;AAAA,iBA0IW,6BAAA,CACd,MAAA,EAAQ,aAAA,EACR,UAAA,UACA,gBAAA,GAAkB,uBAAA"}
1
+ {"version":3,"file":"cli.d.ts","names":[],"sources":["../src/cli/flags.ts","../src/cli/output/render.ts"],"mappings":";;;;iBAmHgB,eAAA,CAAgB,KAAA;AAAA,iBAkDhB,iBAAA,CAAkB,KAAA;AAAA,iBAgBlB,aAAA,CAAc,KAAA;;;KCnKzB,uBAAA;AAAA,iBA0IW,6BAAA,CACd,MAAA,EAAQ,aAAA,EACR,UAAA,UACA,gBAAA,GAAkB,uBAAA"}
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { T as EXIT_CODES, _ as exitCodeForOutputErrorCode, d as PromptInputValidationError, g as textPrompt, k as OUTPUT_FORMATS, m as parsePromptSource, p as mergePromptSourceWithText, x as normalizeOutputError } from "./perf-metrics-D0um6IR6.js";
3
- import { C as findGitRepositoryRoot, G as DEFAULT_AGENT_NAME, K as listBuiltInAgents, T as findSessionByDirectoryWalk, V as InterruptedError, q as normalizeAgentName, w as findSession } from "./prompt-turn-CXMtXBl-.js";
4
- import { a as buildQueueOwnerArgOverride, n as runSessionQueueOwner, o as flushPerfMetricsCapture, s as installPerfMetricsCapture } from "./session-BtwAKtJ3.js";
5
- import { s as probeQueueOwnerHealth } from "./ipc-BM335WFg.js";
6
- import { c as parseMaxTurns, d as parseTtlSeconds, f as resolveAgentInvocation, g as resolveSessionNameFromFlags, h as resolvePermissionMode, i as addSessionOption, l as parseNonEmptyValue, m as resolveOutputPolicy, n as addPromptInputOption, o as parseAllowedTools, p as resolveGlobalFlags, r as addSessionNameOption, s as parseHistoryLimit, t as addGlobalFlags, u as parseSessionName } from "./flags-ceSqz2T6.js";
7
- import { i as emitJsonResult, n as formatPromptSessionBannerLine, t as agentSessionIdPayload } from "./render-Br-kVPK_.js";
8
- import { t as createOutputFormatter } from "./output-C4QhjpM6.js";
2
+ import { A as OUTPUT_FORMATS, E as EXIT_CODES, _ as exitCodeForOutputErrorCode, d as PromptInputValidationError, g as textPrompt, m as parsePromptSource, p as mergePromptSourceWithText, x as normalizeOutputError } from "./perf-metrics-C2pXfxvR.js";
3
+ import { D as findSession, E as findGitRepositoryRoot, G as InterruptedError, O as findSessionByDirectoryWalk, X as listBuiltInAgents, Y as DEFAULT_AGENT_NAME, Z as normalizeAgentName } from "./prompt-turn-BY5SwU1F.js";
4
+ import { a as buildQueueOwnerArgOverride, n as runSessionQueueOwner, o as flushPerfMetricsCapture, s as installPerfMetricsCapture } from "./session-BwgaPK8-.js";
5
+ import { s as probeQueueOwnerHealth } from "./ipc-BruTG5Fb.js";
6
+ import { _ as resolvePermissionMode, c as parseHistoryLimit, d as parsePruneBeforeDate, f as parseSessionName, g as resolveOutputPolicy, h as resolveGlobalFlags, i as addSessionOption, l as parseMaxTurns, m as resolveAgentInvocation, n as addPromptInputOption, o as parseAllowedTools, p as parseTtlSeconds, r as addSessionNameOption, s as parseDaysOlderThan, t as addGlobalFlags, u as parseNonEmptyValue, v as resolveSessionNameFromFlags } from "./flags-yXzUm7Aq.js";
7
+ import { i as emitJsonResult, n as formatPromptSessionBannerLine, t as agentSessionIdPayload } from "./render-yqwtaOX4.js";
8
+ import { n as getTextErrorRemediationHints, t as createOutputFormatter } from "./output-DmHvT8vm.js";
9
9
  import { readFileSync, realpathSync } from "node:fs";
10
10
  import { fileURLToPath, pathToFileURL } from "node:url";
11
11
  import path from "node:path";
@@ -69,15 +69,15 @@ let sessionModulePromise;
69
69
  let outputModulePromise;
70
70
  let outputRenderModulePromise;
71
71
  function loadSessionModule() {
72
- sessionModulePromise ??= import("./session-BtwAKtJ3.js").then((n) => n.t);
72
+ sessionModulePromise ??= import("./session-BwgaPK8-.js").then((n) => n.t);
73
73
  return sessionModulePromise;
74
74
  }
75
75
  function loadOutputModule() {
76
- outputModulePromise ??= import("./output-C4QhjpM6.js").then((n) => n.n);
76
+ outputModulePromise ??= import("./output-DmHvT8vm.js").then((n) => n.r);
77
77
  return outputModulePromise;
78
78
  }
79
79
  function loadOutputRenderModule() {
80
- outputRenderModulePromise ??= import("./render-Br-kVPK_.js").then((n) => n.r);
80
+ outputRenderModulePromise ??= import("./render-yqwtaOX4.js").then((n) => n.r);
81
81
  return outputRenderModulePromise;
82
82
  }
83
83
  async function readPromptInputFromStdin() {
@@ -118,6 +118,44 @@ function resolveRequestedOutputPolicy(globalFlags) {
118
118
  suppressReads: globalFlags.suppressReads === true
119
119
  };
120
120
  }
121
+ function sessionOptionsFromGlobalFlags(globalFlags) {
122
+ return {
123
+ model: globalFlags.model,
124
+ allowedTools: globalFlags.allowedTools,
125
+ maxTurns: globalFlags.maxTurns,
126
+ systemPrompt: globalFlags.systemPrompt
127
+ };
128
+ }
129
+ function buildSessionStartOptions(params) {
130
+ return {
131
+ agentCommand: params.agent.agentCommand,
132
+ cwd: params.agent.cwd,
133
+ name: params.flags.name,
134
+ resumeSessionId: params.flags.resumeSession,
135
+ mcpServers: params.config.mcpServers,
136
+ permissionMode: params.permissionMode,
137
+ nonInteractivePermissions: params.globalFlags.nonInteractivePermissions,
138
+ authCredentials: params.config.auth,
139
+ authPolicy: params.globalFlags.authPolicy,
140
+ terminal: params.globalFlags.terminal,
141
+ timeoutMs: params.globalFlags.timeout,
142
+ verbose: params.globalFlags.verbose,
143
+ sessionOptions: sessionOptionsFromGlobalFlags(params.globalFlags)
144
+ };
145
+ }
146
+ function missingScopedSessionMessage(agent, sessionName) {
147
+ return sessionName ? `No named session "${sessionName}" for cwd ${agent.cwd} and agent ${agent.agentName}` : `No cwd session for ${agent.cwd} and agent ${agent.agentName}`;
148
+ }
149
+ async function findScopedSessionOrThrow(agent, sessionName) {
150
+ const record = await findSession({
151
+ agentCommand: agent.agentCommand,
152
+ cwd: agent.cwd,
153
+ name: sessionName,
154
+ includeClosed: true
155
+ });
156
+ if (!record) throw new Error(missingScopedSessionMessage(agent, sessionName));
157
+ return record;
158
+ }
121
159
  async function findRoutedSessionOrThrow(agentCommand, agentName, cwd, sessionName) {
122
160
  const walkBoundary = findGitRepositoryRoot(cwd) ?? cwd;
123
161
  const record = await findSessionByDirectoryWalk({
@@ -154,6 +192,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
154
192
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
155
193
  authCredentials: config.auth,
156
194
  authPolicy: globalFlags.authPolicy,
195
+ terminal: globalFlags.terminal,
157
196
  outputFormatter,
158
197
  errorEmissionPolicy: { queueErrorAlreadyEmitted: outputPolicy.queueErrorAlreadyEmitted },
159
198
  suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,
@@ -162,7 +201,13 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
162
201
  maxQueueDepth: config.queueMaxDepth,
163
202
  promptRetries: globalFlags.promptRetries,
164
203
  verbose: globalFlags.verbose,
165
- waitForCompletion: flags.wait !== false
204
+ waitForCompletion: flags.wait !== false,
205
+ sessionOptions: {
206
+ model: globalFlags.model,
207
+ allowedTools: globalFlags.allowedTools,
208
+ maxTurns: globalFlags.maxTurns,
209
+ systemPrompt: globalFlags.systemPrompt
210
+ }
166
211
  });
167
212
  if ("queued" in result) {
168
213
  printQueuedPromptByFormat(result, outputPolicy.format);
@@ -201,6 +246,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
201
246
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
202
247
  authCredentials: config.auth,
203
248
  authPolicy: globalFlags.authPolicy,
249
+ terminal: globalFlags.terminal,
204
250
  outputFormatter,
205
251
  suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,
206
252
  timeoutMs: globalFlags.timeout,
@@ -209,7 +255,8 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
209
255
  sessionOptions: {
210
256
  model: globalFlags.model,
211
257
  allowedTools: globalFlags.allowedTools,
212
- maxTurns: globalFlags.maxTurns
258
+ maxTurns: globalFlags.maxTurns,
259
+ systemPrompt: globalFlags.systemPrompt
213
260
  }
214
261
  }));
215
262
  }
@@ -290,6 +337,7 @@ async function handleSetMode(explicitAgentName, modeId, flags, command, config)
290
337
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
291
338
  authCredentials: config.auth,
292
339
  authPolicy: globalFlags.authPolicy,
340
+ terminal: globalFlags.terminal,
293
341
  timeoutMs: globalFlags.timeout,
294
342
  verbose: globalFlags.verbose
295
343
  });
@@ -307,6 +355,7 @@ async function handleSetModel(explicitAgentName, modelId, flags, command, config
307
355
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
308
356
  authCredentials: config.auth,
309
357
  authPolicy: globalFlags.authPolicy,
358
+ terminal: globalFlags.terminal,
310
359
  timeoutMs: globalFlags.timeout,
311
360
  verbose: globalFlags.verbose
312
361
  });
@@ -330,6 +379,7 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
330
379
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
331
380
  authCredentials: config.auth,
332
381
  authPolicy: globalFlags.authPolicy,
382
+ terminal: globalFlags.terminal,
333
383
  timeoutMs: globalFlags.timeout,
334
384
  verbose: globalFlags.verbose
335
385
  });
@@ -351,7 +401,7 @@ async function handleSessionsClose(explicitAgentName, sessionName, command, conf
351
401
  cwd: agent.cwd,
352
402
  name: sessionName
353
403
  });
354
- if (!record) throw new Error(sessionName ? `No named session "${sessionName}" for cwd ${agent.cwd} and agent ${agent.agentName}` : `No cwd session for ${agent.cwd} and agent ${agent.agentName}`);
404
+ if (!record) throw new Error(missingScopedSessionMessage(agent, sessionName));
355
405
  printClosedSessionByFormat(await closeSession(record.acpxRecordId), globalFlags.format);
356
406
  }
357
407
  async function handleSessionsNew(explicitAgentName, flags, command, config) {
@@ -368,24 +418,13 @@ async function handleSessionsNew(explicitAgentName, flags, command, config) {
368
418
  await closeSession(replaced.acpxRecordId);
369
419
  if (globalFlags.verbose) process.stderr.write(`[acpx] soft-closed prior session: ${replaced.acpxRecordId}\n`);
370
420
  }
371
- const created = await createSession({
372
- agentCommand: agent.agentCommand,
373
- cwd: agent.cwd,
374
- name: flags.name,
375
- resumeSessionId: flags.resumeSession,
376
- mcpServers: config.mcpServers,
377
- permissionMode,
378
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
379
- authCredentials: config.auth,
380
- authPolicy: globalFlags.authPolicy,
381
- timeoutMs: globalFlags.timeout,
382
- verbose: globalFlags.verbose,
383
- sessionOptions: {
384
- model: globalFlags.model,
385
- allowedTools: globalFlags.allowedTools,
386
- maxTurns: globalFlags.maxTurns
387
- }
388
- });
421
+ const created = await createSession(buildSessionStartOptions({
422
+ agent,
423
+ flags,
424
+ globalFlags,
425
+ config,
426
+ permissionMode
427
+ }));
389
428
  printCreatedSessionBanner(created, agent.agentName, globalFlags.format, globalFlags.jsonStrict);
390
429
  if (globalFlags.verbose) {
391
430
  const scope = flags.name ? `named session "${flags.name}"` : "cwd session";
@@ -398,24 +437,13 @@ async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
398
437
  const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
399
438
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
400
439
  const [{ ensureSession }, { printCreatedSessionBanner, printEnsuredSessionByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
401
- const result = await ensureSession({
402
- agentCommand: agent.agentCommand,
403
- cwd: agent.cwd,
404
- name: flags.name,
405
- resumeSessionId: flags.resumeSession,
406
- mcpServers: config.mcpServers,
407
- permissionMode,
408
- nonInteractivePermissions: globalFlags.nonInteractivePermissions,
409
- authCredentials: config.auth,
410
- authPolicy: globalFlags.authPolicy,
411
- timeoutMs: globalFlags.timeout,
412
- verbose: globalFlags.verbose,
413
- sessionOptions: {
414
- model: globalFlags.model,
415
- allowedTools: globalFlags.allowedTools,
416
- maxTurns: globalFlags.maxTurns
417
- }
418
- });
440
+ const result = await ensureSession(buildSessionStartOptions({
441
+ agent,
442
+ flags,
443
+ globalFlags,
444
+ config,
445
+ permissionMode
446
+ }));
419
447
  if (result.created) printCreatedSessionBanner(result.record, agent.agentName, globalFlags.format, globalFlags.jsonStrict);
420
448
  printEnsuredSessionByFormat(result.record, result.created, globalFlags.format);
421
449
  }
@@ -512,27 +540,24 @@ function printSessionHistoryByFormat(record, limit, format) {
512
540
  }
513
541
  async function handleSessionsShow(explicitAgentName, sessionName, command, config) {
514
542
  const globalFlags = resolveGlobalFlags(command, config);
515
- const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
516
- const record = await findSession({
517
- agentCommand: agent.agentCommand,
518
- cwd: agent.cwd,
519
- name: sessionName,
520
- includeClosed: true
521
- });
522
- if (!record) throw new Error(sessionName ? `No named session "${sessionName}" for cwd ${agent.cwd} and agent ${agent.agentName}` : `No cwd session for ${agent.cwd} and agent ${agent.agentName}`);
523
- printSessionDetailsByFormat(record, globalFlags.format);
543
+ printSessionDetailsByFormat(await findScopedSessionOrThrow(resolveAgentInvocation(explicitAgentName, globalFlags, config), sessionName), globalFlags.format);
524
544
  }
525
545
  async function handleSessionsHistory(explicitAgentName, sessionName, flags, command, config) {
546
+ const globalFlags = resolveGlobalFlags(command, config);
547
+ printSessionHistoryByFormat(await findScopedSessionOrThrow(resolveAgentInvocation(explicitAgentName, globalFlags, config), sessionName), flags.limit, globalFlags.format);
548
+ }
549
+ async function handleSessionsPrune(explicitAgentName, flags, command, config) {
526
550
  const globalFlags = resolveGlobalFlags(command, config);
527
551
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
528
- const record = await findSession({
552
+ const [{ pruneSessions }, { printPruneResultByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
553
+ const olderThanMs = flags.olderThan != null ? flags.olderThan * 24 * 60 * 60 * 1e3 : void 0;
554
+ printPruneResultByFormat(await pruneSessions({
529
555
  agentCommand: agent.agentCommand,
530
- cwd: agent.cwd,
531
- name: sessionName,
532
- includeClosed: true
533
- });
534
- if (!record) throw new Error(sessionName ? `No named session "${sessionName}" for cwd ${agent.cwd} and agent ${agent.agentName}` : `No cwd session for ${agent.cwd} and agent ${agent.agentName}`);
535
- printSessionHistoryByFormat(record, flags.limit, globalFlags.format);
556
+ before: flags.before,
557
+ olderThanMs,
558
+ includeHistory: flags.includeHistory,
559
+ dryRun: flags.dryRun
560
+ }), globalFlags.format);
536
561
  }
537
562
  //#endregion
538
563
  //#region src/mcp-servers.ts
@@ -715,10 +740,22 @@ function parseAgents(value, sourcePath) {
715
740
  if (!isObject(raw)) throw new Error(`Invalid config agents.${name} in ${sourcePath}: expected object with command`);
716
741
  const command = raw.command;
717
742
  if (typeof command !== "string" || command.trim().length === 0) throw new Error(`Invalid config agents.${name}.command in ${sourcePath}: expected non-empty string`);
718
- parsed[normalizeAgentName(name)] = command.trim();
743
+ const args = parseAgentArgs(raw.args, name, sourcePath);
744
+ parsed[normalizeAgentName(name)] = args.length > 0 ? `${command.trim()} ${args.map(quoteCommandArg).join(" ")}` : command.trim();
719
745
  }
720
746
  return parsed;
721
747
  }
748
+ function parseAgentArgs(value, agentName, sourcePath) {
749
+ if (value == null) return [];
750
+ if (!Array.isArray(value)) throw new Error(`Invalid config agents.${agentName}.args in ${sourcePath}: expected array of strings`);
751
+ return value.map((arg, index) => {
752
+ if (typeof arg !== "string") throw new Error(`Invalid config agents.${agentName}.args[${index}] in ${sourcePath}: expected string`);
753
+ return arg;
754
+ });
755
+ }
756
+ function quoteCommandArg(value) {
757
+ return JSON.stringify(value);
758
+ }
722
759
  function parseAuth(value, sourcePath) {
723
760
  if (value == null) return;
724
761
  if (!isObject(value)) throw new Error(`Invalid config auth in ${sourcePath}: expected object`);
@@ -922,6 +959,20 @@ function formatUptime(startedAt) {
922
959
  const remSeconds = seconds % 60;
923
960
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${remSeconds.toString().padStart(2, "0")}`;
924
961
  }
962
+ function resolveStatusState(record, health) {
963
+ if (health.healthy) return "running";
964
+ if (health.hasLease) return "dead";
965
+ if (record.lastAgentExitSignal || (record.lastAgentExitCode ?? 0) !== 0) return "dead";
966
+ return "idle";
967
+ }
968
+ function statusSummary(state) {
969
+ switch (state) {
970
+ case "running": return "queue owner healthy";
971
+ case "idle": return "session idle; queue owner will start on next prompt";
972
+ case "dead": return "queue owner unavailable";
973
+ }
974
+ return "queue owner unavailable";
975
+ }
925
976
  async function handleStatus(explicitAgentName, flags, command, config) {
926
977
  const globalFlags = resolveGlobalFlags(command, config);
927
978
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
@@ -951,12 +1002,14 @@ async function handleStatus(explicitAgentName, flags, command, config) {
951
1002
  return;
952
1003
  }
953
1004
  const health = await probeQueueOwnerHealth(record.acpxRecordId);
954
- const running = health.healthy;
1005
+ const statusState = resolveStatusState(record, health);
1006
+ const running = statusState === "running";
1007
+ const dead = statusState === "dead";
955
1008
  const payload = {
956
1009
  sessionId: record.acpxRecordId,
957
1010
  agentCommand: record.agentCommand,
958
1011
  pid: health.pid ?? record.pid ?? null,
959
- status: running ? "running" : "dead",
1012
+ status: statusState,
960
1013
  model: record.acpx?.current_model_id ?? null,
961
1014
  mode: record.acpx?.current_mode_id ?? null,
962
1015
  availableModels: record.acpx?.available_models ?? null,
@@ -968,16 +1021,16 @@ async function handleStatus(explicitAgentName, flags, command, config) {
968
1021
  };
969
1022
  if (emitJsonResult(globalFlags.format, {
970
1023
  action: "status_snapshot",
971
- status: running ? "alive" : "dead",
1024
+ status: running ? "alive" : statusState,
972
1025
  pid: payload.pid ?? void 0,
973
- summary: running ? "queue owner healthy" : "queue owner unavailable",
1026
+ summary: statusSummary(statusState),
974
1027
  model: payload.model ?? void 0,
975
1028
  mode: payload.mode ?? void 0,
976
1029
  availableModels: payload.availableModels ?? void 0,
977
1030
  uptime: payload.uptime ?? void 0,
978
1031
  lastPromptTime: payload.lastPromptTime ?? void 0,
979
- exitCode: payload.exitCode ?? void 0,
980
- signal: payload.signal ?? void 0,
1032
+ exitCode: dead ? payload.exitCode ?? void 0 : void 0,
1033
+ signal: dead ? payload.signal ?? void 0 : void 0,
981
1034
  acpxRecordId: record.acpxRecordId,
982
1035
  acpxSessionId: record.acpSessionId,
983
1036
  agentSessionId: record.agentSessionId
@@ -995,7 +1048,7 @@ async function handleStatus(explicitAgentName, flags, command, config) {
995
1048
  process.stdout.write(`mode: ${payload.mode ?? "-"}\n`);
996
1049
  process.stdout.write(`uptime: ${payload.uptime ?? "-"}\n`);
997
1050
  process.stdout.write(`lastPromptTime: ${payload.lastPromptTime ?? "-"}\n`);
998
- if (payload.status === "dead") {
1051
+ if (dead) {
999
1052
  process.stdout.write(`exitCode: ${payload.exitCode ?? "-"}\n`);
1000
1053
  process.stdout.write(`signal: ${payload.signal ?? "-"}\n`);
1001
1054
  }
@@ -1035,6 +1088,9 @@ function registerSessionsCommand(parent, explicitAgentName, config) {
1035
1088
  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) {
1036
1089
  await handleSessionsHistory(explicitAgentName, name, { limit: flags.tail ?? 0 }, this, config);
1037
1090
  });
1091
+ sessionsCommand.command("prune").description("Delete closed sessions and free disk space").option("--dry-run", "Preview what would be pruned without deleting anything").option("--before <date>", "Prune sessions closed before this date", parsePruneBeforeDate).option("--older-than <days>", "Prune sessions closed more than N days ago", parseDaysOlderThan).option("--include-history", "Also delete event stream files (.stream.ndjson)").action(async function(flags) {
1092
+ await handleSessionsPrune(explicitAgentName, flags, this, config);
1093
+ });
1038
1094
  }
1039
1095
  function registerSharedAgentSubcommands(parent, explicitAgentName, config, descriptions) {
1040
1096
  const promptCommand = parent.command("prompt").description(descriptions.prompt).argument("[prompt...]", "Prompt text").showHelpAfterError();
@@ -1084,7 +1140,7 @@ function registerAgentCommand(program, agentName, config) {
1084
1140
  }
1085
1141
  function registerFlowCommand(program, config) {
1086
1142
  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) {
1087
- const { handleFlowRun } = await import("./cli-ChWsO-bb.js");
1143
+ const { handleFlowRun } = await import("./cli-Ddxpnz9X.js");
1088
1144
  await handleFlowRun(file, flags, this, config);
1089
1145
  });
1090
1146
  }
@@ -1124,11 +1180,24 @@ function parseQueueOwnerPayload(raw) {
1124
1180
  options.authCredentials = Object.fromEntries(entries);
1125
1181
  }
1126
1182
  if (record.authPolicy === "skip" || record.authPolicy === "fail") options.authPolicy = record.authPolicy;
1183
+ if (typeof record.terminal === "boolean") options.terminal = record.terminal;
1127
1184
  if (typeof record.suppressSdkConsoleErrors === "boolean") options.suppressSdkConsoleErrors = record.suppressSdkConsoleErrors;
1128
1185
  if (typeof record.verbose === "boolean") options.verbose = record.verbose;
1129
1186
  if (typeof record.ttlMs === "number" && Number.isFinite(record.ttlMs)) options.ttlMs = record.ttlMs;
1130
1187
  if (typeof record.maxQueueDepth === "number" && Number.isFinite(record.maxQueueDepth)) options.maxQueueDepth = Math.max(1, Math.round(record.maxQueueDepth));
1131
1188
  if (typeof record.promptRetries === "number" && Number.isFinite(record.promptRetries)) options.promptRetries = Math.max(0, Math.round(record.promptRetries));
1189
+ const sessionOpts = asRecord(record.sessionOptions);
1190
+ if (sessionOpts) {
1191
+ options.sessionOptions = {};
1192
+ if (typeof sessionOpts.model === "string" && sessionOpts.model.trim().length > 0) options.sessionOptions.model = sessionOpts.model;
1193
+ if (Array.isArray(sessionOpts.allowedTools)) options.sessionOptions.allowedTools = sessionOpts.allowedTools.filter((tool) => typeof tool === "string");
1194
+ if (typeof sessionOpts.maxTurns === "number" && Number.isFinite(sessionOpts.maxTurns)) options.sessionOptions.maxTurns = Math.max(1, Math.round(sessionOpts.maxTurns));
1195
+ if (typeof sessionOpts.systemPrompt === "string") options.sessionOptions.systemPrompt = sessionOpts.systemPrompt;
1196
+ else {
1197
+ const systemPrompt = asRecord(sessionOpts.systemPrompt);
1198
+ if (typeof systemPrompt?.append === "string") options.sessionOptions.systemPrompt = { append: systemPrompt.append };
1199
+ }
1200
+ }
1132
1201
  return options;
1133
1202
  }
1134
1203
  async function runQueueOwnerFromEnv(env) {
@@ -1287,7 +1356,10 @@ async function emitRequestedError(error, normalized, outputPolicy) {
1287
1356
  await emitJsonErrorEvent(normalized);
1288
1357
  return;
1289
1358
  }
1290
- if (!outputPolicy.suppressNonJsonStderr) process.stderr.write(`${normalized.message}\n`);
1359
+ if (!outputPolicy.suppressNonJsonStderr) {
1360
+ process.stderr.write(`${normalized.message}\n`);
1361
+ if (outputPolicy.format === "text") for (const hint of getTextErrorRemediationHints(normalized)) process.stderr.write(`${hint}\n`);
1362
+ }
1291
1363
  }
1292
1364
  async function runWithOutputPolicy(_outputPolicy, run) {
1293
1365
  return await run();