acpx 0.3.1 → 0.4.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 (34) hide show
  1. package/README.md +65 -16
  2. package/dist/{acp-jsonrpc-BNHXq7qK.js → acp-jsonrpc-C7pPk9Tw.js} +1 -1
  3. package/dist/{acp-jsonrpc-BNHXq7qK.js.map → acp-jsonrpc-C7pPk9Tw.js.map} +1 -1
  4. package/dist/cli-5s-E-Y99.js +176 -0
  5. package/dist/cli-5s-E-Y99.js.map +1 -0
  6. package/dist/cli.d.ts +1 -118
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +235 -336
  9. package/dist/cli.js.map +1 -1
  10. package/dist/flags-BkWInxAq.js +194 -0
  11. package/dist/flags-BkWInxAq.js.map +1 -0
  12. package/dist/flows-DnIYoHI1.js +1551 -0
  13. package/dist/flows-DnIYoHI1.js.map +1 -0
  14. package/dist/flows.d.ts +292 -0
  15. package/dist/flows.d.ts.map +1 -0
  16. package/dist/flows.js +2 -0
  17. package/dist/{output-BmkPP7qE.js → output-C58ukIo3.js} +137 -14
  18. package/dist/output-C58ukIo3.js.map +1 -0
  19. package/dist/{output-render-DEAaMxg8.js → output-render-C7w9NZ2H.js} +10 -10
  20. package/dist/output-render-C7w9NZ2H.js.map +1 -0
  21. package/dist/{queue-ipc-EQLpBMKv.js → queue-ipc-CgWf63GN.js} +258 -95
  22. package/dist/queue-ipc-CgWf63GN.js.map +1 -0
  23. package/dist/{session-C2Q8ktsN.js → session-BtpTC2pM.js} +687 -138
  24. package/dist/session-BtpTC2pM.js.map +1 -0
  25. package/dist/types-CeRKmEQ1.d.ts +137 -0
  26. package/dist/types-CeRKmEQ1.d.ts.map +1 -0
  27. package/package.json +35 -16
  28. package/skills/acpx/SKILL.md +22 -5
  29. package/dist/output-BmkPP7qE.js.map +0 -1
  30. package/dist/output-render-DEAaMxg8.js.map +0 -1
  31. package/dist/queue-ipc-EQLpBMKv.js.map +0 -1
  32. package/dist/runtime-session-id-C544sPPL.js +0 -31
  33. package/dist/runtime-session-id-C544sPPL.js.map +0 -1
  34. package/dist/session-C2Q8ktsN.js.map +0 -1
package/README.md CHANGED
@@ -39,6 +39,9 @@ One command surface for Pi, OpenClaw ACP, Codex, Claude, and other ACP-compatibl
39
39
  - **Structured output**: typed ACP messages (thinking, tool calls, diffs) instead of ANSI scraping
40
40
  - **Any ACP agent**: built-in registry + `--agent` escape hatch for custom servers
41
41
  - **One-shot mode**: `exec` for stateless fire-and-forget tasks
42
+ - **Experimental flows**: `flow run <file>` for TypeScript workflow modules over multiple prompts
43
+ - **Runtime-owned flow actions**: shell-backed action steps can prepare workspaces and other deterministic mechanics outside the agent turn
44
+ - **Flow workspace isolation**: `acp` nodes can target an explicit per-step cwd, so flows can keep agent work inside disposable worktrees
42
45
 
43
46
  ```bash
44
47
  $ acpx codex sessions new
@@ -204,13 +207,49 @@ acpx --cwd ~/repos/backend codex 'review recent auth changes'
204
207
  acpx --format text codex 'summarize your findings'
205
208
  acpx --format json codex exec 'review changed files'
206
209
  acpx --format json --json-strict codex exec 'machine-safe JSON only'
210
+ acpx flow run ./my-flow.ts --input-file ./flow-input.json
211
+ acpx --timeout 1800 flow run ./my-flow.ts
207
212
  acpx --format quiet codex 'final recommendation only'
213
+ acpx --suppress-reads codex exec 'show tool activity without dumping file bodies'
208
214
 
209
215
  acpx --timeout 90 codex 'investigate intermittent test timeout'
210
216
  acpx --ttl 30 codex 'keep queue owner alive for quick follow-ups'
211
217
  acpx --verbose codex 'debug why adapter startup is failing'
212
218
  ```
213
219
 
220
+ ## Flows
221
+
222
+ `acpx flow run <file>` executes a TypeScript flow module through the `acpx/flows`
223
+ runtime and persists run state under `~/.acpx/flows/runs/`.
224
+
225
+ Flows are for multi-step ACP work where one prompt is not enough:
226
+
227
+ - `acp` steps keep model-shaped work in ACP
228
+ - `action` steps handle deterministic mechanics like shell commands or GitHub calls
229
+ - `compute` steps do local routing or shaping
230
+ - `checkpoint` steps pause for something outside the runtime
231
+
232
+ The source tree includes flow examples under [examples/flows/README.md](examples/flows/README.md):
233
+
234
+ - small examples such as `echo`, `branch`, `shell`, `workdir`, and `two-turn`
235
+ - a larger PR-triage example under [examples/flows/pr-triage/README.md](examples/flows/pr-triage/README.md)
236
+ - a replay viewer under [examples/flows/replay-viewer/README.md](examples/flows/replay-viewer/README.md) for inspecting saved run bundles in the browser
237
+
238
+ Example runs:
239
+
240
+ ```bash
241
+ acpx flow run ./my-flow.ts --input-file ./flow-input.json
242
+
243
+ acpx flow run examples/flows/branch.flow.ts \
244
+ --input-json '{"task":"FIX: add a regression test for the reconnect bug"}'
245
+
246
+ acpx flow run examples/flows/pr-triage/pr-triage.flow.ts \
247
+ --input-json '{"repo":"openclaw/acpx","prNumber":150}'
248
+ ```
249
+
250
+ The PR-triage example is only an example workflow. It can comment on or close
251
+ real GitHub PRs if you run it against a live repository.
252
+
214
253
  ## Configuration files
215
254
 
216
255
  `acpx` reads config in this order (later wins):
@@ -257,8 +296,16 @@ acpx --format json --json-strict codex exec 'review this PR'
257
296
 
258
297
  # quiet: final assistant text only
259
298
  acpx --format quiet codex 'give me a 3-line summary'
299
+
300
+ # suppress read payloads while keeping the selected output format
301
+ acpx --suppress-reads codex exec 'inspect the repo and report tool usage'
260
302
  ```
261
303
 
304
+ - `text`: human-readable stream with assistant text and tool updates
305
+ - `json`: raw ACP NDJSON stream for automation
306
+ - `quiet`: final assistant text only
307
+ - `--suppress-reads`: replace raw read-file contents with `[read output suppressed]` in `text` and `json` output
308
+
262
309
  JSON events include a stable envelope for correlation:
263
310
 
264
311
  ```json
@@ -279,22 +326,24 @@ Session-control JSON payloads (`sessions new|ensure`, `status`) may also include
279
326
 
280
327
  Built-ins:
281
328
 
282
- | Agent | Adapter | Wraps |
283
- | ---------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
284
- | `pi` | [pi-acp](https://github.com/svkozak/pi-acp) | [Pi Coding Agent](https://github.com/mariozechner/pi) |
285
- | `openclaw` | native (`openclaw acp`) | [OpenClaw ACP bridge](https://github.com/openclaw/openclaw) |
286
- | `codex` | [codex-acp](https://github.com/zed-industries/codex-acp) | [Codex CLI](https://codex.openai.com) |
287
- | `claude` | [claude-agent-acp](https://github.com/zed-industries/claude-agent-acp) | [Claude Code](https://claude.ai/code) |
288
- | `gemini` | native (`gemini --acp`) | [Gemini CLI](https://github.com/google/gemini-cli) |
289
- | `cursor` | native (`cursor-agent acp`) | [Cursor CLI](https://cursor.com/docs/cli/acp) |
290
- | `copilot` | native (`copilot --acp --stdio`) | [GitHub Copilot CLI](https://docs.github.com/copilot/how-tos/copilot-chat/use-copilot-chat-in-the-command-line) |
291
- | `droid` | native (`droid exec --output-format acp`) | [Factory Droid](https://www.factory.ai) |
292
- | `iflow` | native (`iflow --experimental-acp`) | [iFlow CLI](https://github.com/iflow-ai/iflow-cli) |
293
- | `kilocode` | `npx -y @kilocode/cli acp` | [Kilocode](https://kilocode.ai) |
294
- | `kimi` | native (`kimi acp`) | [Kimi CLI](https://github.com/MoonshotAI/kimi-cli) |
295
- | `kiro` | native (`kiro-cli acp`) | [Kiro CLI](https://kiro.dev) |
296
- | `opencode` | `npx -y opencode-ai acp` | [OpenCode](https://opencode.ai) |
297
- | `qwen` | native (`qwen --acp`) | [Qwen Code](https://github.com/QwenLM/qwen-code) |
329
+ | Agent | Adapter | Wraps |
330
+ | ---------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
331
+ | `pi` | [pi-acp](https://github.com/svkozak/pi-acp) | [Pi Coding Agent](https://github.com/mariozechner/pi) |
332
+ | `openclaw` | native (`openclaw acp`) | [OpenClaw ACP bridge](https://github.com/openclaw/openclaw) |
333
+ | `codex` | [codex-acp](https://github.com/zed-industries/codex-acp) | [Codex CLI](https://codex.openai.com) |
334
+ | `claude` | [claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp) | [Claude Code](https://claude.ai/code) |
335
+ | `gemini` | native (`gemini --acp`) | [Gemini CLI](https://github.com/google/gemini-cli) |
336
+ | `cursor` | native (`cursor-agent acp`) | [Cursor CLI](https://cursor.com/docs/cli/acp) |
337
+ | `copilot` | native (`copilot --acp --stdio`) | [GitHub Copilot CLI](https://docs.github.com/copilot/how-tos/copilot-chat/use-copilot-chat-in-the-command-line) |
338
+ | `droid` | native (`droid exec --output-format acp`) | [Factory Droid](https://www.factory.ai) |
339
+ | `iflow` | native (`iflow --experimental-acp`) | [iFlow CLI](https://github.com/iflow-ai/iflow-cli) |
340
+ | `kilocode` | `npx -y @kilocode/cli acp` | [Kilocode](https://kilocode.ai) |
341
+ | `kimi` | native (`kimi acp`) | [Kimi CLI](https://github.com/MoonshotAI/kimi-cli) |
342
+ | `kiro` | native (`kiro-cli-chat acp`) | [Kiro CLI](https://kiro.dev) |
343
+ | `opencode` | `npx -y opencode-ai acp` | [OpenCode](https://opencode.ai) |
344
+ | `qoder` | native (`qodercli --acp`) | [Qoder CLI](https://docs.qoder.com/cli/acp) |
345
+ | `qwen` | native (`qwen --acp`) | [Qwen Code](https://github.com/QwenLM/qwen-code) |
346
+ | `trae` | native (`traecli acp serve`) | [Trae CLI](https://docs.trae.cn/cli) |
298
347
 
299
348
  `factory-droid` and `factorydroid` also resolve to the built-in `droid` adapter.
300
349
 
@@ -52,4 +52,4 @@ function parseJsonRpcErrorMessage(message) {
52
52
  //#endregion
53
53
  export { parsePromptStopReason as i, isSessionUpdateNotification as n, parseJsonRpcErrorMessage as r, isAcpJsonRpcMessage as t };
54
54
 
55
- //# sourceMappingURL=acp-jsonrpc-BNHXq7qK.js.map
55
+ //# sourceMappingURL=acp-jsonrpc-C7pPk9Tw.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"acp-jsonrpc-BNHXq7qK.js","names":[],"sources":["../src/acp-jsonrpc.ts"],"sourcesContent":["import type { AnyMessage } from \"@agentclientprotocol/sdk\";\n\ntype JsonRpcId = string | number | null;\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n return value as Record<string, unknown>;\n}\n\nfunction hasValidId(value: unknown): value is JsonRpcId {\n return (\n value === null ||\n typeof value === \"string\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n );\n}\n\nfunction isErrorObject(value: unknown): value is { code: number; message: string } {\n const record = asRecord(value);\n return (\n !!record &&\n typeof record.code === \"number\" &&\n Number.isFinite(record.code) &&\n typeof record.message === \"string\"\n );\n}\n\nfunction hasResultOrError(value: Record<string, unknown>): boolean {\n const hasResult = Object.hasOwn(value, \"result\");\n const hasError = Object.hasOwn(value, \"error\");\n if (hasResult && hasError) {\n return false;\n }\n if (!hasResult && !hasError) {\n return false;\n }\n if (hasError && !isErrorObject(value.error)) {\n return false;\n }\n return true;\n}\n\nexport function isAcpJsonRpcMessage(value: unknown): value is AnyMessage {\n const record = asRecord(value);\n if (!record || record.jsonrpc !== \"2.0\") {\n return false;\n }\n\n const hasMethod = typeof record.method === \"string\" && record.method.length > 0;\n const hasId = Object.hasOwn(record, \"id\");\n\n if (hasMethod && !hasId) {\n // Notification\n return true;\n }\n\n if (hasMethod && hasId) {\n // Request\n return hasValidId(record.id);\n }\n\n if (!hasMethod && hasId) {\n // Response\n if (!hasValidId(record.id)) {\n return false;\n }\n return hasResultOrError(record);\n }\n\n return false;\n}\n\nexport function isJsonRpcNotification(message: AnyMessage): boolean {\n return (\n Object.hasOwn(message, \"method\") &&\n typeof (message as { method?: unknown }).method === \"string\" &&\n !Object.hasOwn(message, \"id\")\n );\n}\n\nexport function isSessionUpdateNotification(message: AnyMessage): boolean {\n return (\n isJsonRpcNotification(message) && (message as { method?: unknown }).method === \"session/update\"\n );\n}\n\nexport function parsePromptStopReason(message: AnyMessage): string | undefined {\n if (!Object.hasOwn(message, \"id\") || !Object.hasOwn(message, \"result\")) {\n return undefined;\n }\n const record = asRecord((message as { result?: unknown }).result);\n if (!record) {\n return undefined;\n }\n return typeof record.stopReason === \"string\" ? record.stopReason : undefined;\n}\n\nexport function parseJsonRpcErrorMessage(message: AnyMessage): string | undefined {\n if (!Object.hasOwn(message, \"error\")) {\n return undefined;\n }\n const errorRecord = asRecord((message as { error?: unknown }).error);\n if (!errorRecord || typeof errorRecord.message !== \"string\") {\n return undefined;\n }\n return errorRecord.message;\n}\n"],"mappings":";AAIA,SAAS,SAAS,OAAgD;AAChE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;AAET,QAAO;;AAGT,SAAS,WAAW,OAAoC;AACtD,QACE,UAAU,QACV,OAAO,UAAU,YAChB,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM;;AAIxD,SAAS,cAAc,OAA4D;CACjF,MAAM,SAAS,SAAS,MAAM;AAC9B,QACE,CAAC,CAAC,UACF,OAAO,OAAO,SAAS,YACvB,OAAO,SAAS,OAAO,KAAK,IAC5B,OAAO,OAAO,YAAY;;AAI9B,SAAS,iBAAiB,OAAyC;CACjE,MAAM,YAAY,OAAO,OAAO,OAAO,SAAS;CAChD,MAAM,WAAW,OAAO,OAAO,OAAO,QAAQ;AAC9C,KAAI,aAAa,SACf,QAAO;AAET,KAAI,CAAC,aAAa,CAAC,SACjB,QAAO;AAET,KAAI,YAAY,CAAC,cAAc,MAAM,MAAM,CACzC,QAAO;AAET,QAAO;;AAGT,SAAgB,oBAAoB,OAAqC;CACvE,MAAM,SAAS,SAAS,MAAM;AAC9B,KAAI,CAAC,UAAU,OAAO,YAAY,MAChC,QAAO;CAGT,MAAM,YAAY,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,SAAS;CAC9E,MAAM,QAAQ,OAAO,OAAO,QAAQ,KAAK;AAEzC,KAAI,aAAa,CAAC,MAEhB,QAAO;AAGT,KAAI,aAAa,MAEf,QAAO,WAAW,OAAO,GAAG;AAG9B,KAAI,CAAC,aAAa,OAAO;AAEvB,MAAI,CAAC,WAAW,OAAO,GAAG,CACxB,QAAO;AAET,SAAO,iBAAiB,OAAO;;AAGjC,QAAO;;AAGT,SAAgB,sBAAsB,SAA8B;AAClE,QACE,OAAO,OAAO,SAAS,SAAS,IAChC,OAAQ,QAAiC,WAAW,YACpD,CAAC,OAAO,OAAO,SAAS,KAAK;;AAIjC,SAAgB,4BAA4B,SAA8B;AACxE,QACE,sBAAsB,QAAQ,IAAK,QAAiC,WAAW;;AAInF,SAAgB,sBAAsB,SAAyC;AAC7E,KAAI,CAAC,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC,OAAO,OAAO,SAAS,SAAS,CACpE;CAEF,MAAM,SAAS,SAAU,QAAiC,OAAO;AACjE,KAAI,CAAC,OACH;AAEF,QAAO,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa,KAAA;;AAGrE,SAAgB,yBAAyB,SAAyC;AAChF,KAAI,CAAC,OAAO,OAAO,SAAS,QAAQ,CAClC;CAEF,MAAM,cAAc,SAAU,QAAgC,MAAM;AACpE,KAAI,CAAC,eAAe,OAAO,YAAY,YAAY,SACjD;AAEF,QAAO,YAAY"}
1
+ {"version":3,"file":"acp-jsonrpc-C7pPk9Tw.js","names":[],"sources":["../src/acp-jsonrpc.ts"],"sourcesContent":["import type { AnyMessage } from \"@agentclientprotocol/sdk\";\n\ntype JsonRpcId = string | number | null;\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n return value as Record<string, unknown>;\n}\n\nfunction hasValidId(value: unknown): value is JsonRpcId {\n return (\n value === null ||\n typeof value === \"string\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n );\n}\n\nfunction isErrorObject(value: unknown): value is { code: number; message: string } {\n const record = asRecord(value);\n return (\n !!record &&\n typeof record.code === \"number\" &&\n Number.isFinite(record.code) &&\n typeof record.message === \"string\"\n );\n}\n\nfunction hasResultOrError(value: Record<string, unknown>): boolean {\n const hasResult = Object.hasOwn(value, \"result\");\n const hasError = Object.hasOwn(value, \"error\");\n if (hasResult && hasError) {\n return false;\n }\n if (!hasResult && !hasError) {\n return false;\n }\n if (hasError && !isErrorObject(value.error)) {\n return false;\n }\n return true;\n}\n\nexport function isAcpJsonRpcMessage(value: unknown): value is AnyMessage {\n const record = asRecord(value);\n if (!record || record.jsonrpc !== \"2.0\") {\n return false;\n }\n\n const hasMethod = typeof record.method === \"string\" && record.method.length > 0;\n const hasId = Object.hasOwn(record, \"id\");\n\n if (hasMethod && !hasId) {\n // Notification\n return true;\n }\n\n if (hasMethod && hasId) {\n // Request\n return hasValidId(record.id);\n }\n\n if (!hasMethod && hasId) {\n // Response\n if (!hasValidId(record.id)) {\n return false;\n }\n return hasResultOrError(record);\n }\n\n return false;\n}\n\nexport function isJsonRpcNotification(message: AnyMessage): boolean {\n return (\n Object.hasOwn(message, \"method\") &&\n typeof (message as { method?: unknown }).method === \"string\" &&\n !Object.hasOwn(message, \"id\")\n );\n}\n\nexport function isSessionUpdateNotification(message: AnyMessage): boolean {\n return (\n isJsonRpcNotification(message) && (message as { method?: unknown }).method === \"session/update\"\n );\n}\n\nexport function parsePromptStopReason(message: AnyMessage): string | undefined {\n if (!Object.hasOwn(message, \"id\") || !Object.hasOwn(message, \"result\")) {\n return undefined;\n }\n const record = asRecord((message as { result?: unknown }).result);\n if (!record) {\n return undefined;\n }\n return typeof record.stopReason === \"string\" ? record.stopReason : undefined;\n}\n\nexport function parseJsonRpcErrorMessage(message: AnyMessage): string | undefined {\n if (!Object.hasOwn(message, \"error\")) {\n return undefined;\n }\n const errorRecord = asRecord((message as { error?: unknown }).error);\n if (!errorRecord || typeof errorRecord.message !== \"string\") {\n return undefined;\n }\n return errorRecord.message;\n}\n"],"mappings":";AAIA,SAAS,SAAS,OAAgD;AAChE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;AAET,QAAO;;AAGT,SAAS,WAAW,OAAoC;AACtD,QACE,UAAU,QACV,OAAO,UAAU,YAChB,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM;;AAIxD,SAAS,cAAc,OAA4D;CACjF,MAAM,SAAS,SAAS,MAAM;AAC9B,QACE,CAAC,CAAC,UACF,OAAO,OAAO,SAAS,YACvB,OAAO,SAAS,OAAO,KAAK,IAC5B,OAAO,OAAO,YAAY;;AAI9B,SAAS,iBAAiB,OAAyC;CACjE,MAAM,YAAY,OAAO,OAAO,OAAO,SAAS;CAChD,MAAM,WAAW,OAAO,OAAO,OAAO,QAAQ;AAC9C,KAAI,aAAa,SACf,QAAO;AAET,KAAI,CAAC,aAAa,CAAC,SACjB,QAAO;AAET,KAAI,YAAY,CAAC,cAAc,MAAM,MAAM,CACzC,QAAO;AAET,QAAO;;AAGT,SAAgB,oBAAoB,OAAqC;CACvE,MAAM,SAAS,SAAS,MAAM;AAC9B,KAAI,CAAC,UAAU,OAAO,YAAY,MAChC,QAAO;CAGT,MAAM,YAAY,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,SAAS;CAC9E,MAAM,QAAQ,OAAO,OAAO,QAAQ,KAAK;AAEzC,KAAI,aAAa,CAAC,MAEhB,QAAO;AAGT,KAAI,aAAa,MAEf,QAAO,WAAW,OAAO,GAAG;AAG9B,KAAI,CAAC,aAAa,OAAO;AAEvB,MAAI,CAAC,WAAW,OAAO,GAAG,CACxB,QAAO;AAET,SAAO,iBAAiB,OAAO;;AAGjC,QAAO;;AAGT,SAAgB,sBAAsB,SAA8B;AAClE,QACE,OAAO,OAAO,SAAS,SAAS,IAChC,OAAQ,QAAiC,WAAW,YACpD,CAAC,OAAO,OAAO,SAAS,KAAK;;AAIjC,SAAgB,4BAA4B,SAA8B;AACxE,QACE,sBAAsB,QAAQ,IAAK,QAAiC,WAAW;;AAInF,SAAgB,sBAAsB,SAAyC;AAC7E,KAAI,CAAC,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC,OAAO,OAAO,SAAS,SAAS,CACpE;CAEF,MAAM,SAAS,SAAU,QAAiC,OAAO;AACjE,KAAI,CAAC,OACH;AAEF,QAAO,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa,KAAA;;AAGrE,SAAgB,yBAAyB,SAAyC;AAChF,KAAI,CAAC,OAAO,OAAO,SAAS,QAAQ,CAClC;CAEF,MAAM,cAAc,SAAU,QAAgC,MAAM;AACpE,KAAI,CAAC,eAAe,OAAO,YAAY,YAAY,SACjD;AAEF,QAAO,YAAY"}
@@ -0,0 +1,176 @@
1
+ import { a as hasExplicitPermissionModeFlag, f as resolveAgentInvocation, h as resolvePermissionMode, m as resolveOutputPolicy, p as resolveGlobalFlags } from "./flags-BkWInxAq.js";
2
+ import { E as permissionModeSatisfies } from "./session-BtpTC2pM.js";
3
+ import { i as FlowRunner } from "./flows-DnIYoHI1.js";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { InvalidArgumentError } from "commander";
8
+ import { randomUUID } from "node:crypto";
9
+ //#region src/flows/cli.ts
10
+ const FLOW_RUNTIME_SPECIFIER = "acpx/flows";
11
+ const TEXT_MODULE_EXTENSIONS = new Set([
12
+ ".js",
13
+ ".mjs",
14
+ ".cjs",
15
+ ".ts",
16
+ ".tsx",
17
+ ".mts",
18
+ ".cts"
19
+ ]);
20
+ async function handleFlowRun(flowFile, flags, command, config) {
21
+ const globalFlags = resolveGlobalFlags(command, config);
22
+ const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);
23
+ const outputPolicy = resolveOutputPolicy(globalFlags.format, globalFlags.jsonStrict === true);
24
+ const input = await readFlowInput(flags);
25
+ const flowPath = path.resolve(flowFile);
26
+ const flow = await loadFlowModule(flowPath);
27
+ assertFlowPermissionRequirements(flow, permissionMode, globalFlags);
28
+ printFlowRunResult(await new FlowRunner({
29
+ resolveAgent: (profile) => {
30
+ return resolveAgentInvocation(profile ?? flags.defaultAgent, globalFlags, config);
31
+ },
32
+ permissionMode,
33
+ mcpServers: config.mcpServers,
34
+ nonInteractivePermissions: globalFlags.nonInteractivePermissions,
35
+ authCredentials: config.auth,
36
+ authPolicy: globalFlags.authPolicy,
37
+ timeoutMs: globalFlags.timeout,
38
+ ttlMs: globalFlags.ttl,
39
+ verbose: globalFlags.verbose,
40
+ suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,
41
+ sessionOptions: {
42
+ model: globalFlags.model,
43
+ allowedTools: globalFlags.allowedTools,
44
+ maxTurns: globalFlags.maxTurns
45
+ }
46
+ }).run(flow, input, { flowPath }), globalFlags);
47
+ }
48
+ function assertFlowPermissionRequirements(flow, permissionMode, globalFlags) {
49
+ const permissions = flow.permissions;
50
+ if (!permissions) return;
51
+ if (permissions.requireExplicitGrant && !hasExplicitPermissionModeFlag(globalFlags)) throw new InvalidArgumentError(buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, true));
52
+ if (!permissionModeSatisfies(permissionMode, permissions.requiredMode)) throw new InvalidArgumentError(buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, false));
53
+ }
54
+ function buildFlowPermissionFailureMessage(flow, requiredMode, reason, explicit = false) {
55
+ return [
56
+ explicit ? `Flow "${flow.name}" requires an explicit ${requiredMode} grant.` : `Flow "${flow.name}" requires permission mode ${requiredMode}.`,
57
+ `Rerun with --${requiredMode}.`,
58
+ ...reason ? [`Reason: ${reason}`] : []
59
+ ].join(" ");
60
+ }
61
+ async function readFlowInput(flags) {
62
+ if (flags.inputJson && flags.inputFile) throw new InvalidArgumentError("Use only one of --input-json or --input-file");
63
+ if (flags.inputJson) return parseJsonInput(flags.inputJson, "--input-json");
64
+ if (flags.inputFile) {
65
+ const inputPath = path.resolve(flags.inputFile);
66
+ return parseJsonInput(await fs.readFile(inputPath, "utf8"), "--input-file");
67
+ }
68
+ return {};
69
+ }
70
+ async function loadFlowModule(flowPath) {
71
+ const extension = path.extname(flowPath).toLowerCase();
72
+ const prepared = await prepareFlowModuleImport(flowPath, extension);
73
+ try {
74
+ const candidate = findFlowDefinition(await loadFlowRuntimeModule(prepared.flowUrl, extension));
75
+ if (!candidate) throw new Error(`Flow module must export a flow object: ${flowPath}`);
76
+ return candidate;
77
+ } finally {
78
+ await prepared.cleanup?.();
79
+ }
80
+ }
81
+ async function prepareFlowModuleImport(flowPath, extension) {
82
+ const flowUrl = pathToFileURL(flowPath).href;
83
+ if (!TEXT_MODULE_EXTENSIONS.has(extension)) return { flowUrl };
84
+ const source = await fs.readFile(flowPath, "utf8");
85
+ if (!source.includes(FLOW_RUNTIME_SPECIFIER)) return { flowUrl };
86
+ const runtimeSpecifier = resolveFlowRuntimeImportSpecifier();
87
+ const rewritten = source.replaceAll(/(["'])acpx\/flows\1/g, (_match, quote) => `${quote}${runtimeSpecifier}${quote}`);
88
+ if (rewritten === source) return { flowUrl };
89
+ const tempPath = path.join(path.dirname(flowPath), `.acpx-flow-load-${randomUUID()}${extension}`);
90
+ await fs.writeFile(tempPath, rewritten, "utf8");
91
+ return {
92
+ flowUrl: pathToFileURL(tempPath).href,
93
+ cleanup: async () => {
94
+ await fs.rm(tempPath, { force: true });
95
+ }
96
+ };
97
+ }
98
+ function resolveFlowRuntimeImportSpecifier() {
99
+ const selfPath = fileURLToPath(import.meta.url);
100
+ if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.ts`)) return new URL("../flows.ts", import.meta.url).href;
101
+ if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.js`)) return new URL("../flows.js", import.meta.url).href;
102
+ return new URL("./flows.js", import.meta.url).href;
103
+ }
104
+ async function loadFlowRuntimeModule(flowUrl, extension) {
105
+ if (extension === ".ts" || extension === ".tsx" || extension === ".mts" || extension === ".cts") {
106
+ const { tsImport } = await import("tsx/esm/api");
107
+ return await tsImport(flowUrl, import.meta.url);
108
+ }
109
+ return await import(flowUrl);
110
+ }
111
+ function findFlowDefinition(module) {
112
+ const candidates = [
113
+ module.default,
114
+ module["module.exports"],
115
+ getNestedDefault(module.default),
116
+ getNestedDefault(module["module.exports"])
117
+ ];
118
+ for (const candidate of candidates) if (isFlowDefinition(candidate)) return candidate;
119
+ return null;
120
+ }
121
+ function getNestedDefault(value) {
122
+ if (!value || typeof value !== "object" || !("default" in value)) return null;
123
+ return value.default ?? null;
124
+ }
125
+ function isFlowDefinition(value) {
126
+ if (!value || typeof value !== "object") return false;
127
+ const candidate = value;
128
+ return typeof candidate.name === "string" && typeof candidate.startAt === "string" && candidate.nodes !== void 0 && typeof candidate.nodes === "object" && Array.isArray(candidate.edges);
129
+ }
130
+ function parseJsonInput(raw, label) {
131
+ try {
132
+ return JSON.parse(raw);
133
+ } catch (error) {
134
+ throw new InvalidArgumentError(`${label} must contain valid JSON: ${error instanceof Error ? error.message : String(error)}`);
135
+ }
136
+ }
137
+ function printFlowRunResult(result, globalFlags) {
138
+ const payload = {
139
+ action: "flow_run_result",
140
+ runId: result.state.runId,
141
+ flowName: result.state.flowName,
142
+ runTitle: result.state.runTitle,
143
+ flowPath: result.state.flowPath,
144
+ status: result.state.status,
145
+ currentNode: result.state.currentNode,
146
+ currentNodeType: result.state.currentNodeType,
147
+ currentNodeStartedAt: result.state.currentNodeStartedAt,
148
+ lastHeartbeatAt: result.state.lastHeartbeatAt,
149
+ statusDetail: result.state.statusDetail,
150
+ waitingOn: result.state.waitingOn,
151
+ runDir: result.runDir,
152
+ outputs: result.state.outputs,
153
+ sessionBindings: result.state.sessionBindings
154
+ };
155
+ if (globalFlags.format === "json") {
156
+ process.stdout.write(`${JSON.stringify(payload)}\n`);
157
+ return;
158
+ }
159
+ if (globalFlags.format === "quiet") {
160
+ process.stdout.write(`${result.state.runId}\n`);
161
+ return;
162
+ }
163
+ process.stdout.write(`runId: ${payload.runId}\n`);
164
+ process.stdout.write(`flow: ${payload.flowName}\n`);
165
+ if (payload.runTitle) process.stdout.write(`title: ${payload.runTitle}\n`);
166
+ process.stdout.write(`status: ${payload.status}\n`);
167
+ process.stdout.write(`runDir: ${payload.runDir}\n`);
168
+ if (payload.currentNode) process.stdout.write(`currentNode: ${payload.currentNode}\n`);
169
+ if (payload.statusDetail) process.stdout.write(`statusDetail: ${payload.statusDetail}\n`);
170
+ if (payload.waitingOn) process.stdout.write(`waitingOn: ${payload.waitingOn}\n`);
171
+ process.stdout.write(`${JSON.stringify(payload.outputs, null, 2)}\n`);
172
+ }
173
+ //#endregion
174
+ export { handleFlowRun };
175
+
176
+ //# sourceMappingURL=cli-5s-E-Y99.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-5s-E-Y99.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 {\n hasExplicitPermissionModeFlag,\n resolveAgentInvocation,\n resolveGlobalFlags,\n resolveOutputPolicy,\n resolvePermissionMode,\n type GlobalFlags,\n} from \"../cli/flags.js\";\nimport type { ResolvedAcpxConfig } from \"../config.js\";\nimport { type FlowDefinition, FlowRunner } from \"../flows.js\";\nimport { permissionModeSatisfies } from \"../permissions.js\";\nimport type { PermissionMode } from \"../types.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(`Flow module must export a flow object: ${flowPath}`);\n }\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 (isFlowDefinition(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 isFlowDefinition(value: unknown): value is FlowDefinition {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Partial<FlowDefinition>;\n return (\n typeof candidate.name === \"string\" &&\n typeof candidate.startAt === \"string\" &&\n candidate.nodes !== undefined &&\n typeof candidate.nodes === \"object\" &&\n Array.isArray(candidate.edges)\n );\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,123 +1,6 @@
1
+ import { a as SessionRecord } from "./types-CeRKmEQ1.js";
1
2
  import { Command } from "commander";
2
- import { AgentCapabilities, SessionConfigOption } from "@agentclientprotocol/sdk";
3
3
 
4
- //#region src/types.d.ts
5
- type SessionEventLog = {
6
- active_path: string;
7
- segment_count: number;
8
- max_segment_bytes: number;
9
- max_segments: number;
10
- last_write_at?: string;
11
- last_write_error?: string | null;
12
- };
13
- declare const SESSION_RECORD_SCHEMA: "acpx.session.v1";
14
- type SessionMessageImage = {
15
- source: string;
16
- size?: {
17
- width: number;
18
- height: number;
19
- } | null;
20
- };
21
- type SessionUserContent = {
22
- Text: string;
23
- } | {
24
- Mention: {
25
- uri: string;
26
- content: string;
27
- };
28
- } | {
29
- Image: SessionMessageImage;
30
- };
31
- type SessionToolUse = {
32
- id: string;
33
- name: string;
34
- raw_input: string;
35
- input: unknown;
36
- is_input_complete: boolean;
37
- thought_signature?: string | null;
38
- };
39
- type SessionToolResultContent = {
40
- Text: string;
41
- } | {
42
- Image: SessionMessageImage;
43
- };
44
- type SessionToolResult = {
45
- tool_use_id: string;
46
- tool_name: string;
47
- is_error: boolean;
48
- content: SessionToolResultContent;
49
- output?: unknown;
50
- };
51
- type SessionAgentContent = {
52
- Text: string;
53
- } | {
54
- Thinking: {
55
- text: string;
56
- signature?: string | null;
57
- };
58
- } | {
59
- RedactedThinking: string;
60
- } | {
61
- ToolUse: SessionToolUse;
62
- };
63
- type SessionUserMessage = {
64
- id: string;
65
- content: SessionUserContent[];
66
- };
67
- type SessionAgentMessage = {
68
- content: SessionAgentContent[];
69
- tool_results: Record<string, SessionToolResult>;
70
- reasoning_details?: unknown;
71
- };
72
- type SessionMessage = {
73
- User: SessionUserMessage;
74
- } | {
75
- Agent: SessionAgentMessage;
76
- } | "Resume";
77
- type SessionTokenUsage = {
78
- input_tokens?: number;
79
- output_tokens?: number;
80
- cache_creation_input_tokens?: number;
81
- cache_read_input_tokens?: number;
82
- };
83
- type SessionAcpxState = {
84
- current_mode_id?: string;
85
- desired_mode_id?: string;
86
- available_commands?: string[];
87
- config_options?: SessionConfigOption[];
88
- };
89
- type SessionRecord = {
90
- schema: typeof SESSION_RECORD_SCHEMA;
91
- acpxRecordId: string;
92
- acpSessionId: string;
93
- agentSessionId?: string;
94
- agentCommand: string;
95
- cwd: string;
96
- name?: string;
97
- createdAt: string;
98
- lastUsedAt: string;
99
- lastSeq: number;
100
- lastRequestId?: string;
101
- eventLog: SessionEventLog;
102
- closed?: boolean;
103
- closedAt?: string;
104
- pid?: number;
105
- agentStartedAt?: string;
106
- lastPromptAt?: string;
107
- lastAgentExitCode?: number | null;
108
- lastAgentExitSignal?: NodeJS.Signals | null;
109
- lastAgentExitAt?: string;
110
- lastAgentDisconnectReason?: string;
111
- protocolVersion?: number;
112
- agentCapabilities?: AgentCapabilities;
113
- title?: string | null;
114
- messages: SessionMessage[];
115
- updated_at: string;
116
- cumulative_token_usage: SessionTokenUsage;
117
- request_token_usage: Record<string, SessionTokenUsage>;
118
- acpx?: SessionAcpxState;
119
- };
120
- //#endregion
121
4
  //#region src/cli/flags.d.ts
122
5
  declare function parseTtlSeconds(value: string): number;
123
6
  declare function parseAllowedTools(value: string): string[];
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","names":[],"sources":["../src/types.ts","../src/cli/flags.ts","../src/cli/output-render.ts"],"mappings":";;;;KAyGY,eAAA;EACV,WAAA;EACA,aAAA;EACA,iBAAA;EACA,YAAA;EACA,aAAA;EACA,gBAAA;AAAA;AAAA,cAmEW,qBAAA;AAAA,KACD,mBAAA;EACV,MAAA;EACA,IAAA;IACE,KAAA;IACA,MAAA;EAAA;AAAA;AAAA,KAIQ,kBAAA;EAEN,IAAA;AAAA;EAGA,OAAA;IACE,GAAA;IACA,OAAA;EAAA;AAAA;EAIF,KAAA,EAAO,mBAAA;AAAA;AAAA,KAGD,cAAA;EACV,EAAA;EACA,IAAA;EACA,SAAA;EACA,KAAA;EACA,iBAAA;EACA,iBAAA;AAAA;AAAA,KAGU,wBAAA;EAEN,IAAA;AAAA;EAGA,KAAA,EAAO,mBAAA;AAAA;AAAA,KAGD,iBAAA;EACV,WAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA,EAAS,wBAAA;EACT,MAAA;AAAA;AAAA,KAGU,mBAAA;EAEN,IAAA;AAAA;EAGA,QAAA;IACE,IAAA;IACA,SAAA;EAAA;AAAA;EAIF,gBAAA;AAAA;EAGA,OAAA,EAAS,cAAA;AAAA;AAAA,KAGH,kBAAA;EACV,EAAA;EACA,OAAA,EAAS,kBAAA;AAAA;AAAA,KAGC,mBAAA;EACV,OAAA,EAAS,mBAAA;EACT,YAAA,EAAc,MAAA,SAAe,iBAAA;EAC7B,iBAAA;AAAA;AAAA,KAGU,cAAA;EAEN,IAAA,EAAM,kBAAA;AAAA;EAGN,KAAA,EAAO,mBAAA;AAAA;AAAA,KAID,iBAAA;EACV,YAAA;EACA,aAAA;EACA,2BAAA;EACA,uBAAA;AAAA;AAAA,KAWU,gBAAA;EACV,eAAA;EACA,eAAA;EACA,kBAAA;EACA,cAAA,GAAiB,mBAAA;AAAA;AAAA,KAGP,aAAA;EACV,MAAA,SAAe,qBAAA;EACf,YAAA;EACA,YAAA;EACA,cAAA;EACA,YAAA;EACA,GAAA;EACA,IAAA;EACA,SAAA;EACA,UAAA;EACA,OAAA;EACA,aAAA;EACA,QAAA,EAAU,eAAA;EACV,MAAA;EACA,QAAA;EACA,GAAA;EACA,cAAA;EACA,YAAA;EACA,iBAAA;EACA,mBAAA,GAAsB,MAAA,CAAO,OAAA;EAC7B,eAAA;EACA,yBAAA;EACA,eAAA;EACA,iBAAA,GAAoB,iBAAA;EACpB,KAAA;EACA,QAAA,EAAU,cAAA;EACV,UAAA;EACA,sBAAA,EAAwB,iBAAA;EACxB,mBAAA,EAAqB,MAAA,SAAe,iBAAA;EACpC,IAAA,GAAO,gBAAA;AAAA;;;iBCvNO,eAAA,CAAgB,KAAA;AAAA,iBAgChB,iBAAA,CAAkB,KAAA;AAAA,iBAgBlB,aAAA,CAAc,KAAA;;;KClIzB,uBAAA;AAAA,iBAkJW,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":";;;;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"}