acpx 0.5.3 → 0.6.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.
Files changed (47) hide show
  1. package/README.md +12 -4
  2. package/dist/{cli-ChWsO-bb.js → cli-rGyZlX2p.js} +4 -4
  3. package/dist/{cli-ChWsO-bb.js.map → cli-rGyZlX2p.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 +100 -24
  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-DG-3Vfgg.js} +25 -6
  11. package/dist/flags-DG-3Vfgg.js.map +1 -0
  12. package/dist/{flows-_KmnuUXd.js → flows-gbxyIf6o.js} +13 -6
  13. package/dist/flows-gbxyIf6o.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-CkAW8Qvc.js} +51 -9
  18. package/dist/ipc-CkAW8Qvc.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-DvT_gvUh.js} +12 -2
  22. package/dist/perf-metrics-DvT_gvUh.js.map +1 -0
  23. package/dist/{prompt-turn-CXMtXBl-.js → prompt-turn-BOoZaDEq.js} +221 -38
  24. package/dist/prompt-turn-BOoZaDEq.js.map +1 -0
  25. package/dist/{render-Br-kVPK_.js → render-CyodRDtK.js} +35 -3
  26. package/dist/{render-Br-kVPK_.js.map → render-CyodRDtK.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-DcIse8N0.js} +66 -15
  32. package/dist/session-DcIse8N0.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 +20 -20
  38. package/skills/acpx/SKILL.md +7 -2
  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 { S as permissionModeSatisfies } from "./prompt-turn-BOoZaDEq.js";
2
+ import { _ as resolvePermissionMode, a as hasExplicitPermissionModeFlag, g as resolveOutputPolicy, h as resolveGlobalFlags, m as resolveAgentInvocation } from "./flags-DG-3Vfgg.js";
3
+ import { i as FlowRunner, o as validateFlowDefinition, p as isDefinedFlow } from "./flows-gbxyIf6o.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-rGyZlX2p.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-rGyZlX2p.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 { 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-DvT_gvUh.js";
3
+ import { D as findSessionByDirectoryWalk, E as findSession, J as DEFAULT_AGENT_NAME, T as findGitRepositoryRoot, W as InterruptedError, X as normalizeAgentName, Y as listBuiltInAgents } from "./prompt-turn-BOoZaDEq.js";
4
+ import { a as buildQueueOwnerArgOverride, n as runSessionQueueOwner, o as flushPerfMetricsCapture, s as installPerfMetricsCapture } from "./session-DcIse8N0.js";
5
+ import { s as probeQueueOwnerHealth } from "./ipc-CkAW8Qvc.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-DG-3Vfgg.js";
7
+ import { i as emitJsonResult, n as formatPromptSessionBannerLine, t as agentSessionIdPayload } from "./render-CyodRDtK.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-DcIse8N0.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-CyodRDtK.js").then((n) => n.r);
81
81
  return outputRenderModulePromise;
82
82
  }
83
83
  async function readPromptInputFromStdin() {
@@ -154,6 +154,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
154
154
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
155
155
  authCredentials: config.auth,
156
156
  authPolicy: globalFlags.authPolicy,
157
+ terminal: globalFlags.terminal,
157
158
  outputFormatter,
158
159
  errorEmissionPolicy: { queueErrorAlreadyEmitted: outputPolicy.queueErrorAlreadyEmitted },
159
160
  suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,
@@ -162,7 +163,13 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
162
163
  maxQueueDepth: config.queueMaxDepth,
163
164
  promptRetries: globalFlags.promptRetries,
164
165
  verbose: globalFlags.verbose,
165
- waitForCompletion: flags.wait !== false
166
+ waitForCompletion: flags.wait !== false,
167
+ sessionOptions: {
168
+ model: globalFlags.model,
169
+ allowedTools: globalFlags.allowedTools,
170
+ maxTurns: globalFlags.maxTurns,
171
+ systemPrompt: globalFlags.systemPrompt
172
+ }
166
173
  });
167
174
  if ("queued" in result) {
168
175
  printQueuedPromptByFormat(result, outputPolicy.format);
@@ -201,6 +208,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
201
208
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
202
209
  authCredentials: config.auth,
203
210
  authPolicy: globalFlags.authPolicy,
211
+ terminal: globalFlags.terminal,
204
212
  outputFormatter,
205
213
  suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,
206
214
  timeoutMs: globalFlags.timeout,
@@ -209,7 +217,8 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
209
217
  sessionOptions: {
210
218
  model: globalFlags.model,
211
219
  allowedTools: globalFlags.allowedTools,
212
- maxTurns: globalFlags.maxTurns
220
+ maxTurns: globalFlags.maxTurns,
221
+ systemPrompt: globalFlags.systemPrompt
213
222
  }
214
223
  }));
215
224
  }
@@ -290,6 +299,7 @@ async function handleSetMode(explicitAgentName, modeId, flags, command, config)
290
299
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
291
300
  authCredentials: config.auth,
292
301
  authPolicy: globalFlags.authPolicy,
302
+ terminal: globalFlags.terminal,
293
303
  timeoutMs: globalFlags.timeout,
294
304
  verbose: globalFlags.verbose
295
305
  });
@@ -307,6 +317,7 @@ async function handleSetModel(explicitAgentName, modelId, flags, command, config
307
317
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
308
318
  authCredentials: config.auth,
309
319
  authPolicy: globalFlags.authPolicy,
320
+ terminal: globalFlags.terminal,
310
321
  timeoutMs: globalFlags.timeout,
311
322
  verbose: globalFlags.verbose
312
323
  });
@@ -330,6 +341,7 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
330
341
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
331
342
  authCredentials: config.auth,
332
343
  authPolicy: globalFlags.authPolicy,
344
+ terminal: globalFlags.terminal,
333
345
  timeoutMs: globalFlags.timeout,
334
346
  verbose: globalFlags.verbose
335
347
  });
@@ -378,12 +390,14 @@ async function handleSessionsNew(explicitAgentName, flags, command, config) {
378
390
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
379
391
  authCredentials: config.auth,
380
392
  authPolicy: globalFlags.authPolicy,
393
+ terminal: globalFlags.terminal,
381
394
  timeoutMs: globalFlags.timeout,
382
395
  verbose: globalFlags.verbose,
383
396
  sessionOptions: {
384
397
  model: globalFlags.model,
385
398
  allowedTools: globalFlags.allowedTools,
386
- maxTurns: globalFlags.maxTurns
399
+ maxTurns: globalFlags.maxTurns,
400
+ systemPrompt: globalFlags.systemPrompt
387
401
  }
388
402
  });
389
403
  printCreatedSessionBanner(created, agent.agentName, globalFlags.format, globalFlags.jsonStrict);
@@ -408,12 +422,14 @@ async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
408
422
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
409
423
  authCredentials: config.auth,
410
424
  authPolicy: globalFlags.authPolicy,
425
+ terminal: globalFlags.terminal,
411
426
  timeoutMs: globalFlags.timeout,
412
427
  verbose: globalFlags.verbose,
413
428
  sessionOptions: {
414
429
  model: globalFlags.model,
415
430
  allowedTools: globalFlags.allowedTools,
416
- maxTurns: globalFlags.maxTurns
431
+ maxTurns: globalFlags.maxTurns,
432
+ systemPrompt: globalFlags.systemPrompt
417
433
  }
418
434
  });
419
435
  if (result.created) printCreatedSessionBanner(result.record, agent.agentName, globalFlags.format, globalFlags.jsonStrict);
@@ -534,6 +550,19 @@ async function handleSessionsHistory(explicitAgentName, sessionName, flags, comm
534
550
  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
551
  printSessionHistoryByFormat(record, flags.limit, globalFlags.format);
536
552
  }
553
+ async function handleSessionsPrune(explicitAgentName, flags, command, config) {
554
+ const globalFlags = resolveGlobalFlags(command, config);
555
+ const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
556
+ const [{ pruneSessions }, { printPruneResultByFormat }] = await Promise.all([loadSessionModule(), loadOutputRenderModule()]);
557
+ const olderThanMs = flags.olderThan != null ? flags.olderThan * 24 * 60 * 60 * 1e3 : void 0;
558
+ printPruneResultByFormat(await pruneSessions({
559
+ agentCommand: agent.agentCommand,
560
+ before: flags.before,
561
+ olderThanMs,
562
+ includeHistory: flags.includeHistory,
563
+ dryRun: flags.dryRun
564
+ }), globalFlags.format);
565
+ }
537
566
  //#endregion
538
567
  //#region src/mcp-servers.ts
539
568
  function asRecord$1(value) {
@@ -715,10 +744,22 @@ function parseAgents(value, sourcePath) {
715
744
  if (!isObject(raw)) throw new Error(`Invalid config agents.${name} in ${sourcePath}: expected object with command`);
716
745
  const command = raw.command;
717
746
  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();
747
+ const args = parseAgentArgs(raw.args, name, sourcePath);
748
+ parsed[normalizeAgentName(name)] = args.length > 0 ? `${command.trim()} ${args.map(quoteCommandArg).join(" ")}` : command.trim();
719
749
  }
720
750
  return parsed;
721
751
  }
752
+ function parseAgentArgs(value, agentName, sourcePath) {
753
+ if (value == null) return [];
754
+ if (!Array.isArray(value)) throw new Error(`Invalid config agents.${agentName}.args in ${sourcePath}: expected array of strings`);
755
+ return value.map((arg, index) => {
756
+ if (typeof arg !== "string") throw new Error(`Invalid config agents.${agentName}.args[${index}] in ${sourcePath}: expected string`);
757
+ return arg;
758
+ });
759
+ }
760
+ function quoteCommandArg(value) {
761
+ return JSON.stringify(value);
762
+ }
722
763
  function parseAuth(value, sourcePath) {
723
764
  if (value == null) return;
724
765
  if (!isObject(value)) throw new Error(`Invalid config auth in ${sourcePath}: expected object`);
@@ -922,6 +963,20 @@ function formatUptime(startedAt) {
922
963
  const remSeconds = seconds % 60;
923
964
  return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${remSeconds.toString().padStart(2, "0")}`;
924
965
  }
966
+ function resolveStatusState(record, health) {
967
+ if (health.healthy) return "running";
968
+ if (health.hasLease) return "dead";
969
+ if (record.lastAgentExitSignal || (record.lastAgentExitCode ?? 0) !== 0) return "dead";
970
+ return "idle";
971
+ }
972
+ function statusSummary(state) {
973
+ switch (state) {
974
+ case "running": return "queue owner healthy";
975
+ case "idle": return "session idle; queue owner will start on next prompt";
976
+ case "dead": return "queue owner unavailable";
977
+ }
978
+ return "queue owner unavailable";
979
+ }
925
980
  async function handleStatus(explicitAgentName, flags, command, config) {
926
981
  const globalFlags = resolveGlobalFlags(command, config);
927
982
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
@@ -951,12 +1006,14 @@ async function handleStatus(explicitAgentName, flags, command, config) {
951
1006
  return;
952
1007
  }
953
1008
  const health = await probeQueueOwnerHealth(record.acpxRecordId);
954
- const running = health.healthy;
1009
+ const statusState = resolveStatusState(record, health);
1010
+ const running = statusState === "running";
1011
+ const dead = statusState === "dead";
955
1012
  const payload = {
956
1013
  sessionId: record.acpxRecordId,
957
1014
  agentCommand: record.agentCommand,
958
1015
  pid: health.pid ?? record.pid ?? null,
959
- status: running ? "running" : "dead",
1016
+ status: statusState,
960
1017
  model: record.acpx?.current_model_id ?? null,
961
1018
  mode: record.acpx?.current_mode_id ?? null,
962
1019
  availableModels: record.acpx?.available_models ?? null,
@@ -968,16 +1025,16 @@ async function handleStatus(explicitAgentName, flags, command, config) {
968
1025
  };
969
1026
  if (emitJsonResult(globalFlags.format, {
970
1027
  action: "status_snapshot",
971
- status: running ? "alive" : "dead",
1028
+ status: running ? "alive" : statusState,
972
1029
  pid: payload.pid ?? void 0,
973
- summary: running ? "queue owner healthy" : "queue owner unavailable",
1030
+ summary: statusSummary(statusState),
974
1031
  model: payload.model ?? void 0,
975
1032
  mode: payload.mode ?? void 0,
976
1033
  availableModels: payload.availableModels ?? void 0,
977
1034
  uptime: payload.uptime ?? void 0,
978
1035
  lastPromptTime: payload.lastPromptTime ?? void 0,
979
- exitCode: payload.exitCode ?? void 0,
980
- signal: payload.signal ?? void 0,
1036
+ exitCode: dead ? payload.exitCode ?? void 0 : void 0,
1037
+ signal: dead ? payload.signal ?? void 0 : void 0,
981
1038
  acpxRecordId: record.acpxRecordId,
982
1039
  acpxSessionId: record.acpSessionId,
983
1040
  agentSessionId: record.agentSessionId
@@ -995,7 +1052,7 @@ async function handleStatus(explicitAgentName, flags, command, config) {
995
1052
  process.stdout.write(`mode: ${payload.mode ?? "-"}\n`);
996
1053
  process.stdout.write(`uptime: ${payload.uptime ?? "-"}\n`);
997
1054
  process.stdout.write(`lastPromptTime: ${payload.lastPromptTime ?? "-"}\n`);
998
- if (payload.status === "dead") {
1055
+ if (dead) {
999
1056
  process.stdout.write(`exitCode: ${payload.exitCode ?? "-"}\n`);
1000
1057
  process.stdout.write(`signal: ${payload.signal ?? "-"}\n`);
1001
1058
  }
@@ -1035,6 +1092,9 @@ function registerSessionsCommand(parent, explicitAgentName, config) {
1035
1092
  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
1093
  await handleSessionsHistory(explicitAgentName, name, { limit: flags.tail ?? 0 }, this, config);
1037
1094
  });
1095
+ 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) {
1096
+ await handleSessionsPrune(explicitAgentName, flags, this, config);
1097
+ });
1038
1098
  }
1039
1099
  function registerSharedAgentSubcommands(parent, explicitAgentName, config, descriptions) {
1040
1100
  const promptCommand = parent.command("prompt").description(descriptions.prompt).argument("[prompt...]", "Prompt text").showHelpAfterError();
@@ -1084,7 +1144,7 @@ function registerAgentCommand(program, agentName, config) {
1084
1144
  }
1085
1145
  function registerFlowCommand(program, config) {
1086
1146
  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");
1147
+ const { handleFlowRun } = await import("./cli-rGyZlX2p.js");
1088
1148
  await handleFlowRun(file, flags, this, config);
1089
1149
  });
1090
1150
  }
@@ -1124,11 +1184,24 @@ function parseQueueOwnerPayload(raw) {
1124
1184
  options.authCredentials = Object.fromEntries(entries);
1125
1185
  }
1126
1186
  if (record.authPolicy === "skip" || record.authPolicy === "fail") options.authPolicy = record.authPolicy;
1187
+ if (typeof record.terminal === "boolean") options.terminal = record.terminal;
1127
1188
  if (typeof record.suppressSdkConsoleErrors === "boolean") options.suppressSdkConsoleErrors = record.suppressSdkConsoleErrors;
1128
1189
  if (typeof record.verbose === "boolean") options.verbose = record.verbose;
1129
1190
  if (typeof record.ttlMs === "number" && Number.isFinite(record.ttlMs)) options.ttlMs = record.ttlMs;
1130
1191
  if (typeof record.maxQueueDepth === "number" && Number.isFinite(record.maxQueueDepth)) options.maxQueueDepth = Math.max(1, Math.round(record.maxQueueDepth));
1131
1192
  if (typeof record.promptRetries === "number" && Number.isFinite(record.promptRetries)) options.promptRetries = Math.max(0, Math.round(record.promptRetries));
1193
+ const sessionOpts = asRecord(record.sessionOptions);
1194
+ if (sessionOpts) {
1195
+ options.sessionOptions = {};
1196
+ if (typeof sessionOpts.model === "string" && sessionOpts.model.trim().length > 0) options.sessionOptions.model = sessionOpts.model;
1197
+ if (Array.isArray(sessionOpts.allowedTools)) options.sessionOptions.allowedTools = sessionOpts.allowedTools.filter((tool) => typeof tool === "string");
1198
+ if (typeof sessionOpts.maxTurns === "number" && Number.isFinite(sessionOpts.maxTurns)) options.sessionOptions.maxTurns = Math.max(1, Math.round(sessionOpts.maxTurns));
1199
+ if (typeof sessionOpts.systemPrompt === "string") options.sessionOptions.systemPrompt = sessionOpts.systemPrompt;
1200
+ else {
1201
+ const systemPrompt = asRecord(sessionOpts.systemPrompt);
1202
+ if (typeof systemPrompt?.append === "string") options.sessionOptions.systemPrompt = { append: systemPrompt.append };
1203
+ }
1204
+ }
1132
1205
  return options;
1133
1206
  }
1134
1207
  async function runQueueOwnerFromEnv(env) {
@@ -1287,7 +1360,10 @@ async function emitRequestedError(error, normalized, outputPolicy) {
1287
1360
  await emitJsonErrorEvent(normalized);
1288
1361
  return;
1289
1362
  }
1290
- if (!outputPolicy.suppressNonJsonStderr) process.stderr.write(`${normalized.message}\n`);
1363
+ if (!outputPolicy.suppressNonJsonStderr) {
1364
+ process.stderr.write(`${normalized.message}\n`);
1365
+ if (outputPolicy.format === "text") for (const hint of getTextErrorRemediationHints(normalized)) process.stderr.write(`${hint}\n`);
1366
+ }
1291
1367
  }
1292
1368
  async function runWithOutputPolicy(_outputPolicy, run) {
1293
1369
  return await run();