acpx 0.12.0 → 0.13.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 (35) hide show
  1. package/README.md +11 -3
  2. package/dist/{cli-CxsS1XQp.js → cli-D52eGvxU.js} +5 -4
  3. package/dist/cli-D52eGvxU.js.map +1 -0
  4. package/dist/cli.d.ts +2 -3
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +84 -25
  7. package/dist/cli.js.map +1 -1
  8. package/dist/{client-DwNyFauq.d.ts → client-BeKvumq9.d.ts} +4 -3
  9. package/dist/client-BeKvumq9.d.ts.map +1 -0
  10. package/dist/{flags-Bjq_XQ4-.js → flags---9OR06b.js} +36 -9
  11. package/dist/flags---9OR06b.js.map +1 -0
  12. package/dist/{flows-Db_LZKu9.js → flows-CYfjwbn2.js} +14 -4
  13. package/dist/flows-CYfjwbn2.js.map +1 -0
  14. package/dist/flows.d.ts +6 -2
  15. package/dist/flows.d.ts.map +1 -1
  16. package/dist/flows.js +1 -1
  17. package/dist/{live-checkpoint-ClPCSdrW.js → live-checkpoint-CBecfnSH.js} +226 -20
  18. package/dist/live-checkpoint-CBecfnSH.js.map +1 -0
  19. package/dist/{output-CjdF5rHk.js → output-CzN8vLdE.js} +150 -18
  20. package/dist/output-CzN8vLdE.js.map +1 -0
  21. package/dist/runtime.d.ts +18 -14
  22. package/dist/runtime.d.ts.map +1 -1
  23. package/dist/runtime.js +34 -11
  24. package/dist/runtime.js.map +1 -1
  25. package/dist/{session-options-jkYbBxGE.d.ts → session-options-CTdZvr68.d.ts} +4 -2
  26. package/dist/session-options-CTdZvr68.d.ts.map +1 -0
  27. package/package.json +27 -27
  28. package/skills/acpx/SKILL.md +10 -7
  29. package/dist/cli-CxsS1XQp.js.map +0 -1
  30. package/dist/client-DwNyFauq.d.ts.map +0 -1
  31. package/dist/flags-Bjq_XQ4-.js.map +0 -1
  32. package/dist/flows-Db_LZKu9.js.map +0 -1
  33. package/dist/live-checkpoint-ClPCSdrW.js.map +0 -1
  34. package/dist/output-CjdF5rHk.js.map +0 -1
  35. package/dist/session-options-jkYbBxGE.d.ts.map +0 -1
package/README.md CHANGED
@@ -36,6 +36,7 @@ One command surface for Pi, OpenClaw ACP, Codex, Claude, and other ACP-compatibl
36
36
  - **Session export/import**: move portable session archives between machines
37
37
  - **Local status checks**: `status` reports running/idle/dead/no-session, pid, uptime, last prompt
38
38
  - **Client methods**: stable `fs/*` and `terminal/*` handlers with permission controls and cwd sandboxing
39
+ - **Capability opt-outs**: let adapters use their native filesystem or terminal tools with `--no-fs` and `--no-terminal`
39
40
  - **Auth handshake**: stable `authenticate` support via env/config credentials
40
41
  - **Structured output**: typed ACP messages (thinking, tool calls, diffs) instead of ANSI scraping
41
42
  - **Any ACP agent**: built-in registry + `--agent` escape hatch for custom servers
@@ -148,7 +149,8 @@ acpx codex --file - "extra context" # explicit stdin + appended args
148
149
  acpx codex --no-wait 'draft test migration plan' # enqueue without waiting if session is busy
149
150
  acpx codex cancel # cooperative cancel of in-flight prompt
150
151
  acpx codex set-mode auto # session/set_mode (adapter-defined mode id)
151
- acpx codex set model 'gpt-5.2[high]' # adapter-advertised model control
152
+ acpx codex set model gpt-5.6-sol # select the advertised base model
153
+ acpx codex set reasoning_effort max # set the advertised reasoning effort
152
154
  acpx exec 'summarize this repo' # default agent shortcut (codex)
153
155
  acpx codex exec 'what does this repo do?' # one-shot, no saved session
154
156
 
@@ -218,6 +220,7 @@ acpx flow run ./my-flow.ts --input-file ./flow-input.json
218
220
  acpx --timeout 1800 flow run ./my-flow.ts
219
221
  acpx --format quiet codex 'final recommendation only'
220
222
  acpx --suppress-reads codex exec 'show tool activity without dumping file bodies'
223
+ acpx --no-fs codex exec 'read files without ACP client filesystem delegation'
221
224
 
222
225
  acpx --timeout 90 codex 'investigate intermittent test timeout'
223
226
  acpx --ttl 30 codex 'keep queue owner alive for quick follow-ups'
@@ -282,7 +285,7 @@ Supported keys:
282
285
  "timeout": null,
283
286
  "format": "text",
284
287
  "agents": {
285
- "my-custom": { "command": "./bin/my-acp-server", "args": ["acp"] }
288
+ "my-custom": { "argv": ["./bin/my-acp-server", "acp"] }
286
289
  },
287
290
  "auth": {
288
291
  "my_auth_method_id": "credential-value"
@@ -291,6 +294,9 @@ Supported keys:
291
294
  ```
292
295
 
293
296
  Use `acpx config show` to inspect the resolved result and `acpx config init` to create the global template.
297
+ Use structured `agents.<name>.argv` for custom launches; it is required on Windows. Legacy
298
+ `command` plus `args` entries migrate when `command` is an unquoted executable with no whitespace,
299
+ while raw command strings remain Unix-only.
294
300
 
295
301
  For ACP `authenticate` handshakes, use either config `auth` entries or explicit
296
302
  `ACPX_AUTH_<METHOD_ID>` environment variables such as `ACPX_AUTH_OPENAI_API_KEY`.
@@ -361,11 +367,13 @@ Built-ins:
361
367
  | `kilocode` | `npx -y @kilocode/cli acp` | [Kilocode](https://kilocode.ai) |
362
368
  | `kimi` | native (`kimi acp`) | [Kimi CLI](https://github.com/MoonshotAI/kimi-cli) |
363
369
  | `kiro` | native (`kiro-cli-chat acp`) | [Kiro CLI](https://kiro.dev) |
364
- | `mux` | `npx -y mux@^0.27.0 acp` | [Mux](https://mux.coder.com) |
370
+ | `mux` | `mux acp` via an ACPX-owned npm range | [Mux](https://mux.coder.com) |
365
371
  | `opencode` | `npx -y opencode-ai acp` | [OpenCode](https://opencode.ai) |
372
+ | `pool` | native (`pool acp`) | [Poolside](https://poolside.ai) |
366
373
  | `qoder` | native (`qodercli --acp`) | [Qoder CLI](https://docs.qoder.com/cli/acp) |
367
374
  | `qwen` | native (`qwen --acp`) | [Qwen Code](https://github.com/QwenLM/qwen-code) |
368
375
  | `trae` | native (`traecli acp serve`) | [Trae CLI](https://docs.trae.cn/cli) |
376
+ | `zeroclaw` | native (`zeroclaw acp`) | [ZeroClaw](https://github.com/zeroclaw-labs/zeroclaw) |
369
377
 
370
378
  `factory-droid` and `factorydroid` also resolve to the built-in `droid` adapter.
371
379
 
@@ -1,6 +1,6 @@
1
- import { R as permissionModeSatisfies } from "./live-checkpoint-ClPCSdrW.js";
2
- import { _ as resolveGlobalFlags, a as hasExplicitPermissionModeFlag, g as resolveAgentInvocation, v as resolveOutputPolicy, x as loadPermissionPolicySpec, y as resolvePermissionMode } from "./flags-Bjq_XQ4-.js";
3
- import { c as validateFlowDefinition, h as isDefinedFlow, o as FlowRunner } from "./flows-Db_LZKu9.js";
1
+ import { B as permissionModeSatisfies } from "./live-checkpoint-CBecfnSH.js";
2
+ import { S as loadPermissionPolicySpec, _ as resolveGlobalFlags, a as hasExplicitPermissionModeFlag, g as resolveAgentInvocation, v as resolveOutputPolicy, y as resolvePermissionMode } from "./flags---9OR06b.js";
3
+ import { c as validateFlowDefinition, h as isDefinedFlow, o as FlowRunner } from "./flows-CYfjwbn2.js";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import path from "node:path";
6
6
  import { InvalidArgumentError } from "commander";
@@ -36,6 +36,7 @@ async function handleFlowRun(flowFile, flags, command, config) {
36
36
  permissionPolicy,
37
37
  authCredentials: config.auth,
38
38
  authPolicy: globalFlags.authPolicy,
39
+ fs: globalFlags.fs,
39
40
  timeoutMs: globalFlags.timeout,
40
41
  ttlMs: globalFlags.ttl,
41
42
  verbose: globalFlags.verbose,
@@ -194,4 +195,4 @@ function printFlowRunResult(result, globalFlags) {
194
195
  //#endregion
195
196
  export { handleFlowRun };
196
197
 
197
- //# sourceMappingURL=cli-CxsS1XQp.js.map
198
+ //# sourceMappingURL=cli-D52eGvxU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-D52eGvxU.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 { loadPermissionPolicySpec } from \"../permission-policy.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 permissionPolicy = await resolveFlowPermissionPolicy(globalFlags);\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 permissionPolicy,\n authCredentials: config.auth,\n authPolicy: globalFlags.authPolicy,\n fs: globalFlags.fs,\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\nasync function resolveFlowPermissionPolicy(globalFlags: GlobalFlags) {\n try {\n return await loadPermissionPolicySpec(globalFlags.permissionPolicy, globalFlags.cwd);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new InvalidArgumentError(`Invalid permission policy: ${message}`);\n }\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 let runtimePath: string;\n\n if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.ts`)) {\n runtimePath = fileURLToPath(new URL(\"../flows.ts\", import.meta.url));\n } else if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.js`)) {\n runtimePath = fileURLToPath(new URL(\"../flows.js\", import.meta.url));\n } else {\n runtimePath = fileURLToPath(new URL(\"./flows.js\", import.meta.url));\n }\n return runtimePath.replaceAll(path.sep, \"/\");\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 === \".cts\") {\n const { register } = (await import(\"tsx/cjs/api\")) as {\n register: (options: { namespace: string }) => {\n require: (\n specifier: string,\n parentURL: string,\n ) => {\n default?: unknown;\n \"module.exports\"?: unknown;\n };\n unregister: () => void;\n };\n };\n const loader = register({ namespace: randomUUID() });\n try {\n return loader.require(flowUrl, import.meta.url);\n } finally {\n loader.unregister();\n }\n }\n\n if (extension === \".mts\") {\n const { register } = (await import(\"tsx/esm/api\")) as {\n register: (options: { namespace: string }) => {\n import: (\n specifier: string,\n parentURL: string,\n ) => Promise<{\n default?: unknown;\n \"module.exports\"?: unknown;\n }>;\n unregister: () => Promise<void>;\n };\n };\n const loader = register({ namespace: randomUUID() });\n try {\n return await loader.import(flowUrl, import.meta.url);\n } finally {\n await loader.unregister();\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,13 +1,12 @@
1
- import { f as SessionRecord } from "./session-options-jkYbBxGE.js";
1
+ import { f as SessionRecord } from "./session-options-CTdZvr68.js";
2
2
  import { Command } from "commander";
3
-
4
3
  //#region src/cli/flags.d.ts
5
4
  declare function parseTtlSeconds(value: string): number;
6
5
  declare function parseAllowedTools(value: string): string[];
7
6
  declare function parseMaxTurns(value: string): number;
8
7
  //#endregion
9
8
  //#region src/cli/output/render.d.ts
10
- type SessionConnectionStatus = "connected" | "needs reconnect";
9
+ type SessionConnectionStatus = "connected" | "starting" | "needs reconnect";
11
10
  declare function formatPromptSessionBannerLine(record: SessionRecord, currentCwd: string, connectionStatus?: SessionConnectionStatus): string;
12
11
  //#endregion
13
12
  export { formatPromptSessionBannerLine, parseAllowedTools, parseMaxTurns, parseTtlSeconds };
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":";;;;iBAgKgB,eAAA,CAAgB,KAAa;AAAA,iBAkD7B,iBAAA,CAAkB,KAAa;AAAA,iBAgB/B,aAAA,CAAc,KAAa;;;KChNtC,uBAAA;AAAA,iBAwLW,6BAAA,CACd,MAAA,EAAQ,aAAA,EACR,UAAA,UACA,gBAAA,GAAkB,uBAA2C"}
1
+ {"version":3,"file":"cli.d.ts","names":[],"sources":["../src/cli/flags.ts","../src/cli/output/render.ts"],"mappings":";;;iBAyKgB,gBAAgB;iBAsDhB,kBAAkB;iBAgBlB,cAAc;;;KC7NzB;iBAkMW,8BACd,QAAQ,eACR,oBACA,mBAAkB"}
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { a as runSessionQueueOwner, c as buildQueueOwnerArgOverride, g as __exportAll, h as isProcessAlive, l as flushPerfMetricsCapture, n as getTextErrorRemediationHints, o as runOnce, p as probeQueueOwnerHealth, t as createOutputFormatter, u as installPerfMetricsCapture } from "./output-CjdF5rHk.js";
3
- import { At as listBuiltInAgents, Et as TimeoutError, G as listSessions, Gt as OUTPUT_FORMATS, H as findSession, It as normalizeOutputError, L as getAcpxVersion, Nt as exitCodeForOutputErrorCode, St as parsePromptSource, Tt as InterruptedError, U as findSessionByDirectoryWalk, V as findGitRepositoryRoot, Vt as EXIT_CODES, X as writeSessionRecord, Xt as AgentSpawnError, Yt as AcpxOperationalError, ct as normalizeRuntimeSessionId, ft as sessionEventActivePath, gt as isAcpJsonRpcMessage, jt as normalizeAgentName$1, kt as DEFAULT_AGENT_NAME, mt as sessionEventSegmentPath, ot as parseSessionRecord, pt as sessionEventLockPath, q as normalizeName, st as serializeSessionRecordForDisk, ut as defaultSessionEventLog, wt as textPrompt, xt as mergePromptSourceWithText, yt as PromptInputValidationError } from "./live-checkpoint-ClPCSdrW.js";
4
- import { _ as resolveGlobalFlags, b as resolveSessionNameFromFlags, c as parseHistoryLimit, d as parseOutputFormat$1, f as parsePruneBeforeDate, g as resolveAgentInvocation, h as parseTtlSeconds, i as addSessionOption, l as parseMaxTurns, m as parseTimeoutSeconds, n as addPromptInputOption, o as parseAllowedTools, p as parseSessionName, r as addSessionNameOption, s as parseDaysOlderThan, t as addGlobalFlags, u as parseNonEmptyValue, v as resolveOutputPolicy, x as loadPermissionPolicySpec, y as resolvePermissionMode } from "./flags-Bjq_XQ4-.js";
2
+ import { a as runSessionQueueOwner, c as buildQueueOwnerArgOverride, g as __exportAll, h as isProcessAlive, l as flushPerfMetricsCapture, n as getTextErrorRemediationHints, o as runOnce, p as probeQueueOwnerHealth, t as createOutputFormatter, u as installPerfMetricsCapture } from "./output-CzN8vLdE.js";
3
+ import { Dt as textPrompt, G as findSessionByDirectoryWalk, Kt as EXIT_CODES, L as renderArgvIdentity, Mt as DEFAULT_AGENT_NAME, Nt as listBuiltInAgents, Ot as InterruptedError, Pt as normalizeAgentName$1, Q as writeSessionRecord, Rt as exitCodeForOutputErrorCode, St as PromptInputValidationError, Tt as parsePromptSource, U as findGitRepositoryRoot, Vt as normalizeOutputError, W as findSession, Xt as OUTPUT_FORMATS, Y as normalizeName, _t as sessionEventSegmentPath, dt as normalizeRuntimeSessionId, en as AcpxOperationalError, gt as sessionEventLockPath, ht as sessionEventActivePath, kt as TimeoutError, lt as parseSessionRecord, pt as defaultSessionEventLog, q as listSessions, tn as AgentSpawnError, ut as serializeSessionRecordForDisk, wt as mergePromptSourceWithText, yt as isAcpJsonRpcMessage, z as getAcpxVersion } from "./live-checkpoint-CBecfnSH.js";
4
+ import { S as loadPermissionPolicySpec, _ as resolveGlobalFlags, b as resolveSessionNameFromFlags, c as parseHistoryLimit, d as parseOutputFormat$1, f as parsePruneBeforeDate, g as resolveAgentInvocation, h as parseTtlSeconds, i as addSessionOption, l as parseMaxTurns, m as parseTimeoutSeconds, n as addPromptInputOption, o as parseAllowedTools, p as parseSessionName, r as addSessionNameOption, s as parseDaysOlderThan, t as addGlobalFlags, u as parseNonEmptyValue, v as resolveOutputPolicy, x as toTimerMilliseconds, y as resolvePermissionMode } from "./flags---9OR06b.js";
5
5
  import { realpathSync } from "node:fs";
6
6
  import { fileURLToPath, pathToFileURL } from "node:url";
7
7
  import path from "node:path";
@@ -387,11 +387,11 @@ let sessionModulePromise;
387
387
  let outputModulePromise;
388
388
  let outputRenderModulePromise;
389
389
  function loadSessionModule() {
390
- sessionModulePromise ??= import("./output-CjdF5rHk.js").then((n) => n.i);
390
+ sessionModulePromise ??= import("./output-CzN8vLdE.js").then((n) => n.i);
391
391
  return sessionModulePromise;
392
392
  }
393
393
  function loadOutputModule() {
394
- outputModulePromise ??= import("./output-CjdF5rHk.js").then((n) => n.r);
394
+ outputModulePromise ??= import("./output-CzN8vLdE.js").then((n) => n.r);
395
395
  return outputModulePromise;
396
396
  }
397
397
  function loadOutputRenderModule() {
@@ -463,6 +463,7 @@ async function resolvePermissionPolicyFromFlags$1(globalFlags) {
463
463
  function buildSessionStartOptions(params) {
464
464
  return {
465
465
  agentCommand: params.agent.agentCommand,
466
+ agentArgv: params.agent.agentArgv,
466
467
  cwd: params.agent.cwd,
467
468
  name: params.flags.name,
468
469
  resumeSessionId: params.flags.resumeSession,
@@ -472,6 +473,7 @@ function buildSessionStartOptions(params) {
472
473
  permissionPolicy: params.permissionPolicy,
473
474
  authCredentials: params.config.auth,
474
475
  authPolicy: params.globalFlags.authPolicy,
476
+ fs: params.globalFlags.fs,
475
477
  terminal: params.globalFlags.terminal,
476
478
  timeoutMs: params.globalFlags.timeout,
477
479
  verbose: params.globalFlags.verbose,
@@ -540,6 +542,7 @@ async function handlePrompt(explicitAgentName, promptParts, flags, command, conf
540
542
  permissionPolicy,
541
543
  authCredentials: config.auth,
542
544
  authPolicy: globalFlags.authPolicy,
545
+ fs: globalFlags.fs,
543
546
  terminal: globalFlags.terminal,
544
547
  outputFormatter,
545
548
  errorEmissionPolicy: { queueErrorAlreadyEmitted: outputPolicy.queueErrorAlreadyEmitted },
@@ -588,6 +591,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
588
591
  const agent = resolveAgentInvocation(explicitAgentName, globalFlags, config);
589
592
  applyPermissionExitCode(await runOnce({
590
593
  agentCommand: agent.agentCommand,
594
+ agentArgv: agent.agentArgv,
591
595
  cwd: agent.cwd,
592
596
  prompt,
593
597
  mcpServers: config.mcpServers,
@@ -596,6 +600,7 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
596
600
  permissionPolicy,
597
601
  authCredentials: config.auth,
598
602
  authPolicy: globalFlags.authPolicy,
603
+ fs: globalFlags.fs,
599
604
  terminal: globalFlags.terminal,
600
605
  outputFormatter,
601
606
  errorEmissionPolicy: { queueErrorAlreadyEmitted: outputPolicy.queueErrorAlreadyEmitted },
@@ -688,6 +693,7 @@ async function handleSetMode(explicitAgentName, modeId, flags, command, config)
688
693
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
689
694
  authCredentials: config.auth,
690
695
  authPolicy: globalFlags.authPolicy,
696
+ fs: globalFlags.fs,
691
697
  terminal: globalFlags.terminal,
692
698
  timeoutMs: globalFlags.timeout,
693
699
  verbose: globalFlags.verbose
@@ -706,6 +712,7 @@ async function handleSetModel(explicitAgentName, modelId, flags, command, config
706
712
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
707
713
  authCredentials: config.auth,
708
714
  authPolicy: globalFlags.authPolicy,
715
+ fs: globalFlags.fs,
709
716
  terminal: globalFlags.terminal,
710
717
  timeoutMs: globalFlags.timeout,
711
718
  verbose: globalFlags.verbose
@@ -730,6 +737,7 @@ async function handleSetConfigOption(explicitAgentName, configId, value, flags,
730
737
  nonInteractivePermissions: globalFlags.nonInteractivePermissions,
731
738
  authCredentials: config.auth,
732
739
  authPolicy: globalFlags.authPolicy,
740
+ fs: globalFlags.fs,
733
741
  terminal: globalFlags.terminal,
734
742
  timeoutMs: globalFlags.timeout,
735
743
  verbose: globalFlags.verbose
@@ -744,6 +752,7 @@ async function tryListAgentSessions(agent, flags, globalFlags, config) {
744
752
  try {
745
753
  return await listAgentSessions({
746
754
  agentCommand: agent.agentCommand,
755
+ agentArgv: agent.agentArgv,
747
756
  cwd: agent.cwd,
748
757
  cursor: flags.cursor,
749
758
  filterCwd: resolveSessionListFilterCwd(flags, agent.cwd),
@@ -753,6 +762,7 @@ async function tryListAgentSessions(agent, flags, globalFlags, config) {
753
762
  permissionPolicy,
754
763
  authCredentials: config.auth,
755
764
  authPolicy: globalFlags.authPolicy,
765
+ fs: globalFlags.fs,
756
766
  terminal: globalFlags.terminal,
757
767
  timeoutMs: globalFlags.timeout,
758
768
  verbose: globalFlags.verbose
@@ -1169,6 +1179,7 @@ async function runAgentForCompare(params) {
1169
1179
  const agent = resolveAgentInvocation(params.agentName, params.globalFlags, params.config);
1170
1180
  const result = await runOnce({
1171
1181
  agentCommand: agent.agentCommand,
1182
+ agentArgv: agent.agentArgv,
1172
1183
  cwd: agent.cwd,
1173
1184
  prompt: params.prompt,
1174
1185
  mcpServers: params.config.mcpServers,
@@ -1177,6 +1188,7 @@ async function runAgentForCompare(params) {
1177
1188
  permissionPolicy: params.permissionPolicy,
1178
1189
  authCredentials: params.config.auth,
1179
1190
  authPolicy: params.globalFlags.authPolicy,
1191
+ fs: params.globalFlags.fs,
1180
1192
  terminal: params.globalFlags.terminal,
1181
1193
  outputFormatter: formatter,
1182
1194
  suppressSdkConsoleErrors: true,
@@ -1413,12 +1425,16 @@ function isObject(value) {
1413
1425
  function parseTtlMs(value, sourcePath) {
1414
1426
  if (value == null) return;
1415
1427
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0) throw new Error(`Invalid config ttl in ${sourcePath}: expected non-negative seconds`);
1416
- return Math.round(value * 1e3);
1428
+ const milliseconds = toTimerMilliseconds(value, true);
1429
+ if (milliseconds === void 0) throw new Error(`Invalid config ttl in ${sourcePath}: exceeds maximum supported timer delay`);
1430
+ return milliseconds;
1417
1431
  }
1418
1432
  function parseTimeoutMs(value, sourcePath) {
1419
1433
  if (value == null) return;
1420
1434
  if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) throw new Error(`Invalid config timeout in ${sourcePath}: expected positive seconds or null`);
1421
- return Math.round(value * 1e3);
1435
+ const milliseconds = toTimerMilliseconds(value, false);
1436
+ if (milliseconds === void 0) throw new Error(`Invalid config timeout in ${sourcePath}: exceeds maximum supported timer delay`);
1437
+ return milliseconds;
1422
1438
  }
1423
1439
  function parseQueueMaxDepth(value, sourcePath) {
1424
1440
  if (value == null) return;
@@ -1454,15 +1470,42 @@ function parseAgents(value, sourcePath) {
1454
1470
  if (value == null) return;
1455
1471
  if (!isObject(value)) throw new Error(`Invalid config agents in ${sourcePath}: expected object`);
1456
1472
  const parsed = {};
1457
- for (const [name, raw] of Object.entries(value)) {
1458
- if (!isObject(raw)) throw new Error(`Invalid config agents.${name} in ${sourcePath}: expected object with command`);
1459
- const command = raw.command;
1460
- if (typeof command !== "string" || command.trim().length === 0) throw new Error(`Invalid config agents.${name}.command in ${sourcePath}: expected non-empty string`);
1461
- const args = parseAgentArgs(raw.args, name, sourcePath);
1462
- parsed[normalizeAgentName$1(name)] = args.length > 0 ? `${command.trim()} ${args.map(quoteCommandArg).join(" ")}` : command.trim();
1463
- }
1473
+ for (const [name, raw] of Object.entries(value)) parsed[normalizeAgentName$1(name)] = parseAgentEntry(raw, name, sourcePath);
1464
1474
  return parsed;
1465
1475
  }
1476
+ function parseAgentEntry(raw, name, sourcePath) {
1477
+ if (!isObject(raw)) throw new Error(`Invalid config agents.${name} in ${sourcePath}: expected object with command`);
1478
+ return Object.prototype.hasOwnProperty.call(raw, "argv") ? parseArgvAgentEntry(raw, name, sourcePath) : parseLegacyAgentEntry(raw, name, sourcePath);
1479
+ }
1480
+ function parseArgvAgentEntry(raw, name, sourcePath) {
1481
+ if (Object.prototype.hasOwnProperty.call(raw, "command") || Object.prototype.hasOwnProperty.call(raw, "args")) throw new Error(`Invalid config agents.${name} in ${sourcePath}: use argv alone, not command or args`);
1482
+ const argv = parseAgentArgv(raw.argv, name, sourcePath);
1483
+ return {
1484
+ command: renderArgv(argv),
1485
+ argv
1486
+ };
1487
+ }
1488
+ function parseLegacyAgentEntry(raw, name, sourcePath) {
1489
+ const command = raw.command;
1490
+ if (typeof command !== "string" || command.trim().length === 0) throw new Error(`Invalid config agents.${name}.command in ${sourcePath}: expected non-empty string`);
1491
+ const trimmedCommand = command.trim();
1492
+ if (!Object.prototype.hasOwnProperty.call(raw, "args")) return { command: trimmedCommand };
1493
+ if (/[\s'"]/u.test(trimmedCommand)) throw new Error(`Invalid config agents.${name}.command in ${sourcePath}: command must be an unquoted executable with no whitespace when args is present; migrate the complete launch to argv`);
1494
+ const args = parseAgentArgs(raw.args, name, sourcePath);
1495
+ return {
1496
+ command: args.length > 0 ? `${trimmedCommand} ${args.map(quoteCommandArg).join(" ")}` : trimmedCommand,
1497
+ argv: [trimmedCommand, ...args]
1498
+ };
1499
+ }
1500
+ function parseAgentArgv(value, agentName, sourcePath) {
1501
+ if (!Array.isArray(value) || value.length === 0) throw new Error(`Invalid config agents.${agentName}.argv in ${sourcePath}: expected non-empty array of strings`);
1502
+ const argv = value.map((arg, index) => {
1503
+ if (typeof arg !== "string") throw new Error(`Invalid config agents.${agentName}.argv[${index}] in ${sourcePath}: expected string`);
1504
+ return arg;
1505
+ });
1506
+ if (argv[0]?.length === 0) throw new Error(`Invalid config agents.${agentName}.argv[0] in ${sourcePath}: expected non-empty executable`);
1507
+ return argv;
1508
+ }
1466
1509
  function parseAgentArgs(value, agentName, sourcePath) {
1467
1510
  if (value == null) return [];
1468
1511
  if (!Array.isArray(value)) throw new Error(`Invalid config agents.${agentName}.args in ${sourcePath}: expected array of strings`);
@@ -1474,6 +1517,9 @@ function parseAgentArgs(value, agentName, sourcePath) {
1474
1517
  function quoteCommandArg(value) {
1475
1518
  return JSON.stringify(value);
1476
1519
  }
1520
+ function renderArgv(argv) {
1521
+ return renderArgvIdentity(argv);
1522
+ }
1477
1523
  function parseAuth(value, sourcePath) {
1478
1524
  if (value == null) return;
1479
1525
  if (!isObject(value)) throw new Error(`Invalid config auth in ${sourcePath}: expected object`);
@@ -1611,13 +1657,13 @@ function resolveDisableExec(projectConfig, projectPath, globalConfig, globalPath
1611
1657
  }
1612
1658
  function toConfigDisplay(config) {
1613
1659
  const agents = {};
1614
- for (const [name, command] of Object.entries(config.agents)) agents[name] = { command };
1660
+ for (const [name, agent] of Object.entries(config.agents)) agents[name] = agent.argv ? { argv: [...agent.argv] } : { command: agent.command };
1615
1661
  return {
1616
1662
  defaultAgent: config.defaultAgent,
1617
1663
  defaultPermissions: config.defaultPermissions,
1618
1664
  nonInteractivePermissions: config.nonInteractivePermissions,
1619
1665
  authPolicy: config.authPolicy,
1620
- ttl: Math.round(config.ttlMs / 1e3),
1666
+ ttl: config.ttlMs / 1e3,
1621
1667
  timeout: config.timeoutMs == null ? null : config.timeoutMs / 1e3,
1622
1668
  queueMaxDepth: config.queueMaxDepth,
1623
1669
  format: config.format,
@@ -1723,6 +1769,7 @@ function registerConfigCommand(program, config) {
1723
1769
  //#region src/cli/output/render.ts
1724
1770
  var render_exports = /* @__PURE__ */ __exportAll({
1725
1771
  agentSessionIdPayload: () => agentSessionIdPayload,
1772
+ classifySessionConnectionStatus: () => classifySessionConnectionStatus,
1726
1773
  formatPromptSessionBannerLine: () => formatPromptSessionBannerLine,
1727
1774
  printAgentSessionsByFormat: () => printAgentSessionsByFormat,
1728
1775
  printClosedSessionByFormat: () => printClosedSessionByFormat,
@@ -1742,8 +1789,12 @@ function formatRoutedFrom(sessionCwd, currentCwd) {
1742
1789
  if (!relative || relative === ".") return;
1743
1790
  return relative.startsWith(".") ? relative : `.${path.sep}${relative}`;
1744
1791
  }
1792
+ function classifySessionConnectionStatus(health) {
1793
+ if (health.healthy) return "connected";
1794
+ return health.hasLease ? "needs reconnect" : "starting";
1795
+ }
1745
1796
  async function resolveSessionConnectionStatus(record) {
1746
- return (await probeQueueOwnerHealth(record.acpxRecordId)).healthy ? "connected" : "needs reconnect";
1797
+ return classifySessionConnectionStatus(await probeQueueOwnerHealth(record.acpxRecordId));
1747
1798
  }
1748
1799
  function printSessionsByFormat(sessions, format) {
1749
1800
  if (format === "json") {
@@ -1848,7 +1899,7 @@ function printQueuedPromptByFormat(result, format) {
1848
1899
  if (format === "quiet") return;
1849
1900
  process.stdout.write(`[queued] ${result.requestId}\n`);
1850
1901
  }
1851
- function formatPromptSessionBannerLine(record, currentCwd, connectionStatus = "needs reconnect") {
1902
+ function formatPromptSessionBannerLine(record, currentCwd, connectionStatus = "starting") {
1852
1903
  const label = formatSessionLabel(record);
1853
1904
  const normalizedSessionCwd = path.resolve(record.cwd);
1854
1905
  const normalizedCurrentCwd = path.resolve(currentCwd);
@@ -2181,7 +2232,7 @@ function registerAgentCommand(program, agentName, config) {
2181
2232
  }
2182
2233
  function registerFlowCommand(program, config) {
2183
2234
  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) {
2184
- const { handleFlowRun } = await import("./cli-CxsS1XQp.js");
2235
+ const { handleFlowRun } = await import("./cli-D52eGvxU.js");
2185
2236
  await handleFlowRun(file, flags, this, config);
2186
2237
  });
2187
2238
  }
@@ -2234,6 +2285,7 @@ function assignQueueOwnerTransportOptions(options, record) {
2234
2285
  function assignQueueOwnerScalarOptions(options, record) {
2235
2286
  if (record.nonInteractivePermissions === "deny" || record.nonInteractivePermissions === "fail") options.nonInteractivePermissions = record.nonInteractivePermissions;
2236
2287
  if (record.authPolicy === "skip" || record.authPolicy === "fail") options.authPolicy = record.authPolicy;
2288
+ assignBooleanOption(options, "fs", record.fs);
2237
2289
  assignBooleanOption(options, "terminal", record.terminal);
2238
2290
  assignBooleanOption(options, "suppressSdkConsoleErrors", record.suppressSdkConsoleErrors);
2239
2291
  assignBooleanOption(options, "verbose", record.verbose);
@@ -2347,6 +2399,7 @@ const TOP_LEVEL_VERSION_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
2347
2399
  "--deny-all",
2348
2400
  "--suppress-reads",
2349
2401
  "--json-strict",
2402
+ "--no-fs",
2350
2403
  "--no-terminal",
2351
2404
  "--verbose"
2352
2405
  ]);
@@ -2653,13 +2706,18 @@ function normalizeLifecycleScriptArgs(rawArgs) {
2653
2706
  return rawArgs;
2654
2707
  }
2655
2708
  //#endregion
2656
- //#region src/cli.ts
2657
- function installBrokenPipeHandler(stream) {
2709
+ //#region src/cli/broken-pipe.ts
2710
+ function handleBrokenPipeError(error, mode, exit = (code) => process.exit(code)) {
2711
+ if (error.code !== "EPIPE") throw error;
2712
+ if (mode === "exit") exit(0);
2713
+ }
2714
+ function installBrokenPipeHandler(stream, mode) {
2658
2715
  stream.on("error", (error) => {
2659
- if (error.code === "EPIPE") process.exit(0);
2660
- throw error;
2716
+ handleBrokenPipeError(error, mode);
2661
2717
  });
2662
2718
  }
2719
+ //#endregion
2720
+ //#region src/cli.ts
2663
2721
  function isCliEntrypoint(argv) {
2664
2722
  const entry = argv[1];
2665
2723
  if (!entry) return false;
@@ -2671,8 +2729,9 @@ function isCliEntrypoint(argv) {
2671
2729
  }
2672
2730
  }
2673
2731
  if (isCliEntrypoint(process.argv)) {
2674
- installBrokenPipeHandler(process.stdout);
2675
- installBrokenPipeHandler(process.stderr);
2732
+ const isQueueOwner = process.argv[2] === "__queue-owner";
2733
+ installBrokenPipeHandler(process.stdout, "exit");
2734
+ installBrokenPipeHandler(process.stderr, isQueueOwner ? "ignore" : "exit");
2676
2735
  const queueOwnerArgOverride = buildQueueOwnerArgOverride(fileURLToPath(import.meta.url));
2677
2736
  if (queueOwnerArgOverride) process.env.ACPX_QUEUE_OWNER_ARGS ??= queueOwnerArgOverride;
2678
2737
  main(process.argv);