@enderfga/claw-orchestrator 7.12.1 → 7.14.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 (88) hide show
  1. package/README.md +14 -11
  2. package/configs/engines/README.md +20 -0
  3. package/configs/engines/dsh.json +17 -0
  4. package/configs/engines/kimi-code.json +17 -0
  5. package/dist/bin/cli.js +123 -34
  6. package/dist/bin/cli.js.map +1 -1
  7. package/dist/src/acp-server.js +4 -2
  8. package/dist/src/acp-server.js.map +1 -1
  9. package/dist/src/autoloop/dispatcher.d.ts +19 -0
  10. package/dist/src/autoloop/dispatcher.js +57 -0
  11. package/dist/src/autoloop/dispatcher.js.map +1 -1
  12. package/dist/src/autoloop/runner.d.ts +102 -2
  13. package/dist/src/autoloop/runner.js +367 -44
  14. package/dist/src/autoloop/runner.js.map +1 -1
  15. package/dist/src/autoloop/types.d.ts +17 -0
  16. package/dist/src/autoloop/types.js.map +1 -1
  17. package/dist/src/dashboard/index.html +79 -73
  18. package/dist/src/embedded-server.js +35 -7
  19. package/dist/src/embedded-server.js.map +1 -1
  20. package/dist/src/engine-presets.d.ts +7 -3
  21. package/dist/src/engine-presets.js +39 -6
  22. package/dist/src/engine-presets.js.map +1 -1
  23. package/dist/src/engine-spawn.d.ts +8 -1
  24. package/dist/src/engine-spawn.js +13 -3
  25. package/dist/src/engine-spawn.js.map +1 -1
  26. package/dist/src/index.js +78 -71
  27. package/dist/src/index.js.map +1 -1
  28. package/dist/src/kernel/agent-step.d.ts +3 -0
  29. package/dist/src/kernel/agent-step.js.map +1 -1
  30. package/dist/src/kernel/engine.d.ts +5 -2
  31. package/dist/src/kernel/engine.js +11 -12
  32. package/dist/src/kernel/engine.js.map +1 -1
  33. package/dist/src/kernel/nodes/autoloop.d.ts +32 -2
  34. package/dist/src/kernel/nodes/autoloop.js +122 -15
  35. package/dist/src/kernel/nodes/autoloop.js.map +1 -1
  36. package/dist/src/kernel/nodes/goal.d.ts +94 -0
  37. package/dist/src/kernel/nodes/goal.js +386 -0
  38. package/dist/src/kernel/nodes/goal.js.map +1 -0
  39. package/dist/src/kernel/nodes/index.d.ts +2 -1
  40. package/dist/src/kernel/nodes/index.js +3 -1
  41. package/dist/src/kernel/nodes/index.js.map +1 -1
  42. package/dist/src/kernel/templates/index.d.ts +27 -3
  43. package/dist/src/kernel/templates/index.js +78 -1
  44. package/dist/src/kernel/templates/index.js.map +1 -1
  45. package/dist/src/kernel/types.d.ts +41 -2
  46. package/dist/src/kernel/types.js.map +1 -1
  47. package/dist/src/persistent-acp-session.d.ts +76 -0
  48. package/dist/src/persistent-acp-session.js +409 -0
  49. package/dist/src/persistent-acp-session.js.map +1 -0
  50. package/dist/src/persistent-agy-session.js +1 -0
  51. package/dist/src/persistent-agy-session.js.map +1 -1
  52. package/dist/src/persistent-codex-app-session.d.ts +55 -26
  53. package/dist/src/persistent-codex-app-session.js +109 -24
  54. package/dist/src/persistent-codex-app-session.js.map +1 -1
  55. package/dist/src/persistent-codex-session.js +1 -0
  56. package/dist/src/persistent-codex-session.js.map +1 -1
  57. package/dist/src/persistent-cursor-session.js +1 -0
  58. package/dist/src/persistent-cursor-session.js.map +1 -1
  59. package/dist/src/persistent-custom-session.js +2 -0
  60. package/dist/src/persistent-custom-session.js.map +1 -1
  61. package/dist/src/persistent-gemini-session.js +1 -0
  62. package/dist/src/persistent-gemini-session.js.map +1 -1
  63. package/dist/src/persistent-grok-session.js +1 -0
  64. package/dist/src/persistent-grok-session.js.map +1 -1
  65. package/dist/src/persistent-opencode-session.js +1 -0
  66. package/dist/src/persistent-opencode-session.js.map +1 -1
  67. package/dist/src/persistent-session.js +1 -0
  68. package/dist/src/persistent-session.js.map +1 -1
  69. package/dist/src/sanitize.d.ts +10 -0
  70. package/dist/src/sanitize.js +26 -0
  71. package/dist/src/sanitize.js.map +1 -1
  72. package/dist/src/session-manager.d.ts +25 -20
  73. package/dist/src/session-manager.js +92 -43
  74. package/dist/src/session-manager.js.map +1 -1
  75. package/dist/src/types.d.ts +35 -1
  76. package/dist/src/types.js +2 -0
  77. package/dist/src/types.js.map +1 -1
  78. package/openclaw.plugin.json +1 -1
  79. package/package.json +2 -2
  80. package/skills/SKILL.md +8 -5
  81. package/skills/references/acp.md +4 -0
  82. package/skills/references/autoloop.md +27 -2
  83. package/skills/references/claude-cli-tracking.md +3 -1
  84. package/skills/references/cli.md +79 -39
  85. package/skills/references/dashboard.md +5 -1
  86. package/skills/references/multi-engine.md +39 -10
  87. package/skills/references/tools.md +77 -65
  88. package/skills/references/workflow.md +87 -13
@@ -8,7 +8,7 @@ export declare const MODEL_ALIASES: Record<string, string>;
8
8
  export type PermissionMode = 'acceptEdits' | 'bypassPermissions' | 'default' | 'manual' | 'dontAsk' | 'plan' | 'auto';
9
9
  export declare const EFFORT_LEVELS: readonly ["low", "medium", "high", "xhigh", "max", "ultra", "auto"];
10
10
  export type EffortLevel = (typeof EFFORT_LEVELS)[number];
11
- export declare const ENGINE_TYPES: readonly ["claude", "codex", "codex-app", "gemini", "agy", "cursor", "grok", "opencode", "custom"];
11
+ export declare const ENGINE_TYPES: readonly ["claude", "codex", "codex-app", "gemini", "agy", "cursor", "grok", "opencode", "custom", "acp"];
12
12
  export type EngineType = (typeof ENGINE_TYPES)[number];
13
13
  /** Common execution binding shared by every directly configured agent. */
14
14
  export interface AgentBinding {
@@ -159,6 +159,26 @@ export interface CustomEngineConfig {
159
159
  */
160
160
  sanitizePatterns?: string[];
161
161
  }
162
+ export interface AcpAgentConfig {
163
+ /** Display name (logs, session ids). */
164
+ name: string;
165
+ /** Command name or path that serves ACP on stdio, e.g. 'kimi'. */
166
+ command: string;
167
+ /** Environment variable that overrides `command` at runtime, e.g. 'KIMI_BIN'. */
168
+ commandEnv?: string;
169
+ /** Arguments after the command, e.g. ['acp']. */
170
+ args?: string[];
171
+ /** Extra environment for the process. */
172
+ env?: Record<string, string>;
173
+ /** Context window in tokens, when the agent does not report one. */
174
+ contextWindow?: number;
175
+ /** Price per million tokens, used only when the agent reports no cost. */
176
+ pricing?: {
177
+ input: number;
178
+ output: number;
179
+ cached?: number;
180
+ };
181
+ }
162
182
  /**
163
183
  * One entry of Claude Code's `--agents` JSON, passed to the CLI verbatim.
164
184
  *
@@ -319,6 +339,12 @@ export interface SessionConfig {
319
339
  * Defaults to 'workspace-write' for Codex.
320
340
  */
321
341
  sandboxMode?: 'read-only' | 'workspace-write' | 'danger-full-access';
342
+ /**
343
+ * Argv prefix the engine binary runs under, e.g. a sandbox wrapper:
344
+ * `['/opt/task/sandbox.sh', 'task', '0 1']`. Set by the caller that owns the
345
+ * session; never taken from an agent.
346
+ */
347
+ launcher?: string[];
322
348
  /**
323
349
  * Codex only. Named config profile from `~/.codex/config.toml`, passed as
324
350
  * `codex exec --profile <name>`. Bundles model + reasoning effort + approval +
@@ -358,6 +384,12 @@ export interface SessionConfig {
358
384
  * `src/engine-presets.ts` for what a preset promises and what it does not.
359
385
  */
360
386
  customEngine?: CustomEngineConfig | string;
387
+ /**
388
+ * The agent to run — required when engine is 'acp'. An inline config, or the
389
+ * id of a bundled preset from `configs/engines/` (the only form accepted over
390
+ * HTTP, as for `customEngine`).
391
+ */
392
+ acpAgent?: AcpAgentConfig | string;
361
393
  }
362
394
  export interface SessionStats {
363
395
  /**
@@ -437,6 +469,8 @@ export interface SessionStats {
437
469
  opencodeSessionId?: string;
438
470
  /** Grok Build session ID captured from the turn's JSON result. Reused via `--resume` for multi-turn context. */
439
471
  grokSessionId?: string;
472
+ /** ACP session id from `session/new`; a later session loads it with `session/load` or `session/resume`. */
473
+ acpSessionId?: string;
440
474
  /**
441
475
  * True when the most recent turn's token counts came from estimateTokens()
442
476
  * because the engine reported no usage. Cost derived from those counts is an
package/dist/src/types.js CHANGED
@@ -22,6 +22,7 @@ export const ENGINE_TYPES = [
22
22
  'grok',
23
23
  'opencode',
24
24
  'custom',
25
+ 'acp',
25
26
  ];
26
27
  /**
27
28
  * The executables the built-in engines actually spawn — the defaults in each
@@ -70,6 +71,7 @@ export function engineHasNativeConversation(engine, customEngine) {
70
71
  case 'opencode':
71
72
  case 'cursor':
72
73
  case 'grok':
74
+ case 'acp':
73
75
  return true;
74
76
  case 'custom':
75
77
  // A persistent custom engine is a long-running stdin/stdout process, so it
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,oDAAoD;AACpD,MAAM,CAAC,MAAM,aAAa,GAA2B,UAAU,EAAE,CAAC;AAUlE,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAU,CAAC;AAGjG,+EAA+E;AAE/E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ;IACR,OAAO;IACP,WAAW;IACX,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,MAAM;IACN,UAAU;IACV,QAAQ;CACA,CAAC;AAUX;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAErH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAA8B,EAC9B,YAAiC;IAEjC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO,CAAC;QACb,KAAK,WAAW,CAAC;QACjB,KAAK,KAAK,CAAC;QACX,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QACd,KAAK,QAAQ;YACX,2EAA2E;YAC3E,gEAAgE;YAChE,OAAO,YAAY,EAAE,UAAU,KAAK,IAAI,CAAC;QAC3C;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,oDAAoD;AACpD,MAAM,CAAC,MAAM,aAAa,GAA2B,UAAU,EAAE,CAAC;AAUlE,+EAA+E;AAC/E,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAU,CAAC;AAGjG,+EAA+E;AAE/E,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ;IACR,OAAO;IACP,WAAW;IACX,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,MAAM;IACN,UAAU;IACV,QAAQ;IACR,KAAK;CACG,CAAC;AAUX;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,UAAU,CAAU,CAAC;AAErH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAA8B,EAC9B,YAAiC;IAEjC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO,CAAC;QACb,KAAK,WAAW,CAAC;QACjB,KAAK,KAAK,CAAC;QACX,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ,CAAC;QACd,KAAK,MAAM,CAAC;QACZ,KAAK,KAAK;YACR,OAAO,IAAI,CAAC;QACd,KAAK,QAAQ;YACX,2EAA2E;YAC3E,gEAAgE;YAChE,OAAO,YAAY,EAAE,UAAU,KAAK,IAAI,CAAC;QAC3C;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "claw-orchestrator",
3
3
  "name": "Claw Orchestrator",
4
- "description": "Run Claude Code, Codex, Antigravity, Grok Build, OpenCode and custom coding CLIs as one unified runtime. Persistent sessions, multi-engine orchestration, multi-agent council, worktree isolation, multi-model proxy, structured output, plan mode workflows.",
4
+ "description": "Run Claude Code, Codex, Antigravity, Grok Build, OpenCode, any ACP agent and custom coding CLIs as one unified runtime. Persistent sessions, multi-engine orchestration, multi-agent council, worktree isolation, multi-model proxy, structured output, plan mode workflows.",
5
5
  "enabledByDefault": false,
6
6
  "configSchema": {
7
7
  "type": "object",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@enderfga/claw-orchestrator",
3
- "version": "7.12.1",
4
- "description": "Claw Orchestrator — run Claude Code, Codex, Antigravity, Grok Build, OpenCode and custom coding CLIs as one unified runtime. Drop into Hermes Agent, Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf, Goose or any Model Context Protocol (MCP) host, install as an OpenClaw plugin, or run standalone. Persistent sessions, multi-agent council, ultraplan, ultrareview, autoloop, tool orchestration.",
3
+ "version": "7.14.0",
4
+ "description": "Claw Orchestrator — run Claude Code, Codex, Antigravity, Grok Build, OpenCode, any ACP agent and custom coding CLIs as one unified runtime. Drop into Hermes Agent, Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf, Goose or any Model Context Protocol (MCP) host, install as an OpenClaw plugin, or run standalone. Persistent sessions, multi-agent council, ultraplan, ultrareview, autoloop, tool orchestration.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
7
7
  "types": "./dist/src/index.d.ts",
package/skills/SKILL.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: claw-orchestrator
3
- description: Manage persistent coding sessions across Claude Code, Codex, Antigravity (agy), Grok Build, and OpenCode engines. Use when orchestrating multi-engine coding agents, starting/sending/stopping sessions, running multi-agent council collaborations, cross-session messaging, ultraplan deep planning, ultrareview parallel code review, autoloop autonomous workspace iteration, ultraapp building deployable web apps from a structured Q&A interview, switching models/tools at runtime, exposing the orchestrator's 78 tools as an MCP server to Hermes Agent / Claude Desktop / Cursor / Cline / Continue / Zed / Windsurf / Goose, or running as an Agent Client Protocol (ACP) agent that Zed / JetBrains / Neovim / Emacs / VS Code / dsh can drive directly. Triggers on "start a session", "send to session", "run council", "ultraplan", "ultrareview", "autoloop", "ultraapp", "Forge tab", "build a web app", "one-click app", "AppSpec", "autonomous iteration", "iterate until goal", "auto research", "switch model", "hand off a session", "session handoff", "switch engine", "continue on codex", "continue on claude", "move this session to another engine", "multi-agent coding", "coding session", "session inbox", "grok session", "grok build", "opencode", "mcp server", "clawo-mcp", "hermes mcp", "model context protocol", "ultracode", "dynamic workflow", "fanout", "fan-out", "best-of-N", "steer turn", "interrupt turn", "fork thread", "rollback turns", "acp", "agent client protocol", "clawo acp", "zed agent", "jetbrains agent", "external agent", "dsh subagent", "deepseek harness", "clawo runs", "run ledger", "session cost", "coding-agent token usage", "spend cap", "budget limit", "maxBudgetUsd", "durable workflow", "resume a run", "verify a coding run", "acceptance contract", "evidence bundle", "did the agent's tests actually pass", "protected tests", "agent edited the tests", "human gate", "repair loop", "clawo workflow", "clawo verify", "clawo solve", "clawo fanout", "fix and verify", "solve from the terminal".
3
+ description: Manage persistent coding sessions across Claude Code, Codex, Antigravity (agy), Grok Build, and OpenCode engines. Use when orchestrating multi-engine coding agents, starting/sending/stopping sessions, running multi-agent council collaborations, cross-session messaging, ultraplan deep planning, ultrareview parallel code review, autoloop autonomous workspace iteration, ultraapp building deployable web apps from a structured Q&A interview, switching models/tools at runtime, exposing the orchestrator's 78 tools as an MCP server to Hermes Agent / Claude Desktop / Cursor / Cline / Continue / Zed / Windsurf / Goose, or running as an Agent Client Protocol (ACP) agent that Zed / JetBrains / Neovim / Emacs / VS Code / dsh can drive directly. Triggers on "start a session", "send to session", "run council", "ultraplan", "ultrareview", "autoloop", "ultraapp", "Forge tab", "build a web app", "one-click app", "AppSpec", "autonomous iteration", "iterate until goal", "auto research", "switch model", "hand off a session", "session handoff", "switch engine", "continue on codex", "continue on claude", "move this session to another engine", "multi-agent coding", "coding session", "session inbox", "grok session", "grok build", "opencode", "mcp server", "clawo-mcp", "hermes mcp", "model context protocol", "ultracode", "dynamic workflow", "fanout", "fan-out", "best-of-N", "steer turn", "interrupt turn", "fork thread", "rollback turns", "acp", "agent client protocol", "clawo acp", "zed agent", "jetbrains agent", "external agent", "dsh subagent", "deepseek harness", "acp engine", "acp agent", "kimi code", "kimi acp", "dsh acp", "any acp agent", "clawo runs", "run ledger", "session cost", "coding-agent token usage", "spend cap", "budget limit", "maxBudgetUsd", "durable workflow", "resume a run", "verify a coding run", "acceptance contract", "evidence bundle", "did the agent's tests actually pass", "protected tests", "agent edited the tests", "human gate", "repair loop", "clawo workflow", "clawo verify", "clawo solve", "clawo fanout", "fix and verify", "solve from the terminal", "codex goal", "/goal", "clawo goal", "long-horizon goal", "unattended codex run", "goal node", "run codex in a sandbox", "launcher".
4
4
  metadata:
5
5
  {
6
6
  'openclaw':
@@ -213,15 +213,18 @@ For setup, the dsh YAML block, and the cancellation/permission limits: see [refe
213
213
 
214
214
  ## Durable workflows
215
215
 
216
- `workflow_start` runs a declarative graph of `agent` / `fanout` / `council` / `verifier` /
217
- `human_gate` / `router` / `subflow` / `autoloop` / `ultraapp_synth` /
216
+ `workflow_start` runs a declarative graph of `agent` / `fanout` / `council` / `goal` /
217
+ `verifier` / `human_gate` / `router` / `subflow` / `autoloop` / `ultraapp_synth` /
218
218
  `ultraapp_deploy` nodes. Every state transition is checkpointed to
219
219
  `~/.claw-orchestrator/wf/<runId>/`, so a run survives a process restart and `workflow_resume`
220
220
  picks it up at the node boundary — nodes already succeeded are not re-run, and the one that
221
221
  was in flight is retried because a half-finished node left no result to trust.
222
222
 
223
- Three built-in templates: `solve` (triage → implement → verify → repair-until-green →
224
- review), `council`, and `fanout`. Retry, per-node timeout, cancel, steer, human gates, and
223
+ Four built-in templates: `solve` (triage → implement → verify → repair-until-green →
224
+ review), `council`, `fanout`, and `goal` (a Codex `/goal` on one `codex-app` thread, run
225
+ unattended for as long as it takes — reattached on resume, resumed after usage limits and
226
+ stalls within a bound, optionally under a sandbox `launcher` — then verify → repair on the
227
+ same thread; `clawo goal` from the terminal). Retry, per-node timeout, cancel, steer, human gates, and
225
228
  bounded loops come from the kernel rather than from each mode's own state machine.
226
229
 
227
230
  For node shapes, routing conditions, and the control surfaces:
@@ -8,6 +8,10 @@ spawns an arbitrary command as a subagent.
8
8
  The model selector spans several engines, and session modes select the
9
9
  orchestration shape: a single agent, a council, a planning pass, or a review.
10
10
 
11
+ The other direction, the orchestrator as an ACP **client** driving an agent such
12
+ as `kimi acp` or `dsh --profile acp`, is the `acp` engine: see
13
+ [multi-engine.md](./multi-engine.md#acp-agents-engine-acp).
14
+
11
15
  ```bash
12
16
  clawo acp # or the dedicated binary:
13
17
  clawo-acp
@@ -138,6 +138,19 @@ A successful increase appends exactly one `timeout_migration` record to
138
138
  pending dispatch identity when available. It does not rewrite the original
139
139
  stored spec, chat or iteration evidence, or any earlier audit bytes.
140
140
 
141
+ A live run paused by `pause_loop` or an expired activity lease, with
142
+ `pending_dispatch` null, continues on `autoloopResume()` / `POST /autoloop/<id>/resume`
143
+ with no timeout fields. That resume clears the lease expiry, sets status back
144
+ to `planning` (or `running` once subagents have been spawned), re-arms the
145
+ activity lease from the resume, and leaves the original hard deadline where it
146
+ was. That call returns once the run is active again; Planner chat accepted
147
+ during the pause was parked, not delivered, and is then delivered once, in
148
+ order, by the background drain. If the hard deadline has already passed, the
149
+ same resume terminates the run with `hard_timeout_exceeded` and delivers
150
+ nothing. A no-option resume of an `awaiting_resume` send-timeout pause is still
151
+ a no-op: the pending dispatch, its reason, and the lease suspension stay as
152
+ they are until an explicit timeout increase names that dispatch.
153
+
141
154
  ## Quick start
142
155
 
143
156
  Over HTTP, against `clawo serve` (default `127.0.0.1:18796`):
@@ -212,7 +225,7 @@ removes partial files, and suppresses both spawn and directives.
212
225
  | `notify_user` | `level` ('info' / 'warn' / 'decision' / 'error'), `summary`, `detail?`, `channel?` ('auto' / 'wechat' / 'webchat' / 'both' / 'email') | Push you out-of-band. |
213
226
  | `spawn_subagents` | `coder_engine?`, `coder_model?`, `reviewer_engine?`, `reviewer_model?`, `initial_directive?` | Start Coder + Reviewer. Omitted values inherit run defaults. An engine change without a model uses the new engine's default. Once a role session has started, changing its engine/model is rejected. Custom configs cannot be emitted by Planner. Only after explicit user approval. |
214
227
  | `send_directive` | `goal`, `constraints?`, `success_criteria?`, `max_attempts?` | Next iter's instruction to Coder. |
215
- | `pause_loop` | `reason` | Halt subloop at next iter boundary; chat keeps working. |
228
+ | `pause_loop` | `reason` | Pause the live run. Planner chat is parked during a pause and is delivered once, in order, on resume. |
216
229
  | `resume_loop` | — | Resume after pause. |
217
230
  | `terminate` | `reason` | End run. |
218
231
  | `update_push_policy` | partial PushPolicy | Mutate notification rules (e.g. when you say "tell me every iter"). |
@@ -390,7 +403,7 @@ Every JSON artifact in the ledger carries a `schema_version` field (currently
390
403
  | `GET /autoloop/<id>/events` | SSE: `snapshot` / `message` / `state` / `push` / `iter_done` / `planner_reply` / `planner_error` / `coder_reply` / `reviewer_reply` / `terminated`. For runs that are NOT in this process's memory (terminated, or live in another process), the endpoint emits a single-shot `snapshot` + `terminated` then closes — the dashboard's existing handlers render history without hanging. A run still in memory that has already reached `terminated` or `crashed` gets the same single-shot pair instead of an open stream that would never receive another event. Every such stream sets `retry: 864000000`, so an `EventSource` does not keep reconnecting to a stream that can only end again. |
391
404
  | `POST /autoloop/<id>/chat` | **202** `{ ok, queued: true }` — body `{ text }`. Fire-and-forget: the Planner's reply streams back via the `/events` SSE channel as a `planner_reply` event (or `planner_error` on failure); the HTTP response intentionally does NOT wait for it, because first-contact replies routinely exceed reverse-proxy idle limits (e.g. Cloudflare Tunnel cuts at ~100s → 524). 400 on empty text. 404 when the run is not in this process's memory: if the store still holds it, the error says so and names `POST /autoloop/<id>/resume`; an unknown or malformed id is plain `not found`. The MCP `autoloop_chat` tool path keeps the synchronous await-and-return-reply semantics (it runs in-process). |
392
405
  | `GET /autoloop/<id>/resume-requirements` | `{ ok, runId, rolesNeedingCustomEngine }` — the roles whose engine was `custom`, so a caller knows which secret references a resume needs. Role names only; nothing sensitive. 404 when there is no such run. |
393
- | `POST /autoloop/<id>/resume` | `{ ok, state }` — restore the role engine/model choices from the run's spec and re-create dispatcher + runner. For recoverable send timeouts, body fields `send_timeout_ms` and `pending_dispatch_id` apply the increase-only migration described above; `allow_decrease`, lease overrides, and hard-cap overrides are rejected. A custom-engine config is never persisted and is never accepted over HTTP, so a role using `custom` is re-supplied by **reference**: `plannerCustomEngineRef` / `coderCustomEngineRef` / `reviewerCustomEngineRef` name an environment variable `CLAWO_CUSTOM_ENGINE_<NAME>` on the orchestrator host, which the server reads and resolves. The name is not sensitive, the value never crosses the wire, and an unknown name is an error rather than a silent start without credentials. Existing engine-specific conversation resume behavior is reused where supported; `chat.jsonl` remains the visual history fallback. 404 when there is no such run. |
406
+ | `POST /autoloop/<id>/resume` | `{ ok, state }` — for a live ordinary or activity-lease pause (`pending_dispatch` null), an empty timeout body continues that run: the response returns once status is `planning` or `running` again, the lease re-arms, the hard deadline stays put, and parked Planner input is then delivered once, in order. A live `awaiting_resume` pause is unchanged unless the body increases the send timeout. Otherwise restore the role engine/model choices from the run's spec and re-create dispatcher + runner. For recoverable send timeouts, body fields `send_timeout_ms` and `pending_dispatch_id` apply the increase-only migration described above; `allow_decrease`, lease overrides, and hard-cap overrides are rejected. A custom-engine config is never persisted and is never accepted over HTTP, so a role using `custom` is re-supplied by **reference**: `plannerCustomEngineRef` / `coderCustomEngineRef` / `reviewerCustomEngineRef` name an environment variable `CLAWO_CUSTOM_ENGINE_<NAME>` on the orchestrator host, which the server reads and resolves. The name is not sensitive, the value never crosses the wire, and an unknown name is an error rather than a silent start without credentials. Existing engine-specific conversation resume behavior is reused where supported; `chat.jsonl` remains the visual history fallback. 404 when there is no such run. |
394
407
  | `POST /autoloop/<id>/delete` | `{ ok }` — stops the loop if still live, deletes the run record from the run store, and purges the role sessions' persisted resume ids so the run cannot be resumed. The ledger directory under `<workspace>/tasks/<run_id>/` is kept on disk. 404 when there is no such run. |
395
408
 
396
409
  The dashboard's 3-pane autoloop view (`/dashboard`) consumes these endpoints:
@@ -486,6 +499,18 @@ retried, and there is no message outbox. A gap or malformed closed tail after a
486
499
  valid prefix refuses the resume with a fixed generic error before any new
487
500
  session or effect; ledger text is never echoed into the error.
488
501
 
502
+ **Accepted chat survives stop and owner loss.** `autoloop_chat` and `POST
503
+ /autoloop/:id/chat` accept a message only once it is in the run's checkpoint;
504
+ otherwise they fail (`autoloop chat could not be persisted`, or a stopping,
505
+ restoring or limit error) and nothing is sent. Up to 1,000 entries and 8 MiB
506
+ can be pending. Chat that was not yet handed to the Planner is delivered once,
507
+ in order, after a resume. Chat that was being delivered when the run stopped is
508
+ not resent: the status gains `unconfirmed_chat` (`count`, `last_at`,
509
+ `history_pending`) and chat history gets one system notice asking to re-send it
510
+ if needed. No further chat is handed over until that notice is recorded; if it
511
+ cannot be written the run pauses with `chat_notice_pending`, and a plain resume
512
+ retries it.
513
+
489
514
  ## Known limitations
490
515
 
491
516
  - **`webchat` channel is a no-op.** No webchat session id is carried at the run
@@ -2,12 +2,14 @@
2
2
 
3
3
  This document tracks which Claude Code CLI version Claw Orchestrator is currently synced to, and which features have been integrated. Recent rows also record the other engines' versions checked in the same sync.
4
4
 
5
- ## Currently tracked: **Claude Code CLI 2.1.307** (as of 2026-10-22, plugin v7.12.1)
5
+ ## Currently tracked: **Claude Code CLI 2.1.310** (as of 2026-10-25, plugin v7.14.0)
6
6
 
7
7
  ## Sync history
8
8
 
9
9
  | Plugin Version | Claude CLI Version | Date | Notable integrations |
10
10
  | ------------------- | ------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | v7.14.0 | 2.1.310 | 2026-10-25 | CC 2.1.307→2.1.310, agy 1.4.4→1.4.6, grok 1.0.67→1.0.70, OpenCode 1.19.3→1.19.4; Codex 0.164.0 unchanged. No flag the wrappers pass changed; one live turn per engine ok. Integrated: the `acp` engine (an ACP client over `@agentclientprotocol/sdk` 1.3.0), run against Kimi Code 2.3.1 (`kimi acp`, model from `KIMI_MODEL_*`), dsh 0.2.1-rc.2 (`dsh --profile acp`, `--patch` honoured) and OpenCode 1.19.4 (`opencode acp`, recall across a resumed session). Kimi Code and dsh report no usage over ACP. |
12
+ | v7.13.0 | 2.1.307 | 2026-10-24 | Codex 0.163.0→0.164.0; the other engines as tracked in v7.12.1. Integrated: Codex 0.164 app-server goal RPCs (`thread/goal/set` / `get` / `clear`, six goal states, `tokenBudget`, `thread/goal/updated`), structured `error` notifications (`codexErrorInfo`, `willRetry`), `turn/steer` during goal turns, and `approvalPolicy` on `thread/start` / `thread/resume`; the `goal` workflow node is built on them. Measured: a goal objective is capped at 4,000 characters, and a thread can be resumed only after its first turn. |
11
13
  | v7.12.1 | 2.1.307 | 2026-10-22 | CC 2.1.302→2.1.307, agy 1.4.0→1.4.4, grok 1.0.62→1.0.67; Codex 0.163.0 and OpenCode 1.19.3 unchanged. No flag the wrappers pass changed. grok 1.0.67 makes `grok-4.7` its default and only model: registered (same prices and 500K window as `grok-4.6`), the `grok` alias moved to it, and a session with no `model` is labelled with the model grok reports. grok read-only re-measured on 1.0.67 (direct and shell writes blocked; the subagent probe hit the free-tier limit). OpenCode 2 still beta-only, still refused. |
12
14
  | v7.12.0 | 2.1.302 | 2026-10-17 | CC 2.1.296→2.1.302, Codex 0.162.1→0.163.0, agy 1.3.2→1.4.0, grok 1.0.50→1.0.62, OpenCode 1.19.0→1.19.3. No flag the wrappers pass changed. grok read-only re-measured on 1.0.62 (direct, shell and subagent writes blocked; the failed-sandbox warning unchanged). OpenCode 2 still beta-only, still refused. Codex 0.163.0 turns Daybreak (security programme, not a model) on for eligible accounts; billing follows the model codex reports. |
13
15
  | v7.11.0 | 2.1.296 | 2026-10-11 | CC 2.1.295→2.1.296, Codex 0.162.0→0.162.1, OpenCode 1.18.35→1.19.0; agy 1.3.2 and grok 1.0.50 unchanged. No flag the wrappers pass changed. OpenCode 1.19.0 offers `opencode upgrade --major` to OpenCode 2 (beta builds `0.0.0-beta-N`, replaces V1): measured on 0.0.0-beta-17823 it drops `step_finish` and `--variant`, and its free tier answers 403 to a custom agent, so the read-only agent is unverifiable — the OpenCode session now refuses a V2 binary at start. |
@@ -72,35 +72,36 @@ Run as an Agent Client Protocol agent over stdio (same as the `clawo-acp` binary
72
72
  clawo session-start [name] [options]
73
73
  ```
74
74
 
75
- | Flag | Description |
76
- | ------------------------------- | ------------------------------------------------------------------------------------------- |
77
- | `-d, --cwd <dir>` | Working directory |
78
- | `-e, --engine <engine>` | Engine: `claude` (default), `codex`, `codex-app`, `agy`, `grok`, `opencode`, or `custom` |
79
- | `-m, --model <model>` | Model name or alias |
80
- | `--permission-mode <mode>` | `acceptEdits` (default), `plan`, `auto`, `bypassPermissions`, `manual`, `dontAsk` |
81
- | `--effort <level>` | `low`, `medium`, `high`, `xhigh`, `max`, `ultra`, `auto` |
82
- | `--allowed-tools <tools>` | Comma-separated tool whitelist |
83
- | `--disallowed-tools <tools>` | Comma-separated tools to deny |
84
- | `--max-turns <n>` | Max agent loop turns |
85
- | `--max-budget <usd>` | API cost ceiling |
86
- | `--system-prompt <text>` | Replace system prompt |
87
- | `--append-system-prompt <text>` | Append to system prompt |
88
- | `--agents <json>` | Custom sub-agents JSON |
89
- | `--agent <name>` | Default agent |
90
- | `--bare` | No CLAUDE.md, no git context |
91
- | `-w, --worktree [name]` | Git worktree |
92
- | `--fallback-model <model>` | Fallback model |
93
- | `--json-schema <schema>` | JSON Schema for structured output |
94
- | `--mcp-config <paths>` | MCP config files (comma-separated) |
95
- | `--settings <pathOrJson>` | Settings.json path or inline JSON |
96
- | `--skip-persistence` | Do not save the session — neither the engine's transcript nor the resume registry |
97
- | `--betas <headers>` | Beta headers (comma-separated) |
98
- | `--enable-agent-teams` | Enable agent teams |
99
- | `--enable-auto-mode` | Enable auto permission mode |
100
- | `--resume-session-id <id>` | Resume an existing session by ID |
101
- | `--base-url <url>` | Custom API endpoint (for proxy) |
102
- | `--add-dir <dirs>` | Comma-separated additional working directories |
103
- | `--custom-engine <preset>` | With `-e custom`: the id of a bundled engine preset (see [`clawo engines`](#clawo-engines)) |
75
+ | Flag | Description |
76
+ | ------------------------------- | ----------------------------------------------------------------------------------------------- |
77
+ | `-d, --cwd <dir>` | Working directory |
78
+ | `-e, --engine <engine>` | Engine: `claude` (default), `codex`, `codex-app`, `agy`, `grok`, `opencode`, `acp`, or `custom` |
79
+ | `-m, --model <model>` | Model name or alias |
80
+ | `--permission-mode <mode>` | `acceptEdits` (default), `plan`, `auto`, `bypassPermissions`, `manual`, `dontAsk` |
81
+ | `--effort <level>` | `low`, `medium`, `high`, `xhigh`, `max`, `ultra`, `auto` |
82
+ | `--allowed-tools <tools>` | Comma-separated tool whitelist |
83
+ | `--disallowed-tools <tools>` | Comma-separated tools to deny |
84
+ | `--max-turns <n>` | Max agent loop turns |
85
+ | `--max-budget <usd>` | API cost ceiling |
86
+ | `--system-prompt <text>` | Replace system prompt |
87
+ | `--append-system-prompt <text>` | Append to system prompt |
88
+ | `--agents <json>` | Custom sub-agents JSON |
89
+ | `--agent <name>` | Default agent |
90
+ | `--bare` | No CLAUDE.md, no git context |
91
+ | `-w, --worktree [name]` | Git worktree |
92
+ | `--fallback-model <model>` | Fallback model |
93
+ | `--json-schema <schema>` | JSON Schema for structured output |
94
+ | `--mcp-config <paths>` | MCP config files (comma-separated) |
95
+ | `--settings <pathOrJson>` | Settings.json path or inline JSON |
96
+ | `--skip-persistence` | Do not save the session — neither the engine's transcript nor the resume registry |
97
+ | `--betas <headers>` | Beta headers (comma-separated) |
98
+ | `--enable-agent-teams` | Enable agent teams |
99
+ | `--enable-auto-mode` | Enable auto permission mode |
100
+ | `--resume-session-id <id>` | Resume an existing session by ID |
101
+ | `--base-url <url>` | Custom API endpoint (for proxy) |
102
+ | `--add-dir <dirs>` | Comma-separated additional working directories |
103
+ | `--custom-engine <preset>` | With `-e custom`: the id of a bundled engine preset (see [`clawo engines`](#clawo-engines)) |
104
+ | `--acp-agent <preset>` | With `-e acp`: the id of a bundled ACP agent preset, e.g. `kimi-code`, `dsh` |
104
105
 
105
106
  The remaining `session_start` options (hook events, permission-prompt tool, debug output, `fromPr`, MCP channels, prompt-cache settings and others) are tool parameters only and have no CLI flag. See [Tools Reference](./tools.md#session_start).
106
107
 
@@ -108,14 +109,19 @@ The remaining `session_start` options (hook events, permission-prompt tool, debu
108
109
 
109
110
  ```bash
110
111
  clawo session-send <name> <message> [options]
112
+ clawo session-send <name> --message-file <file> [options]
111
113
  ```
112
114
 
113
- | Flag | Description |
114
- | -------------------- | -------------------------------- |
115
- | `--effort <level>` | Override effort for this message |
116
- | `--plan` | Enable plan mode |
117
- | `-s, --stream` | Collect streaming chunks |
118
- | `-t, --timeout <ms>` | Timeout (default 300000) |
115
+ | Flag | Description |
116
+ | ----------------------- | ---------------------------------------------------------------------------- |
117
+ | `--message-file <file>` | Read the message from a file (long text, or text starting with `-`) |
118
+ | `--effort <level>` | Override effort for this message |
119
+ | `--plan` | Enable plan mode |
120
+ | `-s, --stream` | Collect streaming chunks |
121
+ | `-t, --timeout <ms>` | Timeout (default 300000) |
122
+ | `--json` | Print the whole result (`ok`, `output`, `sessionId`, `error`, …) as one line |
123
+
124
+ Every command that fails prints `Failed: …` and exits 1.
119
125
 
120
126
  ### session-stop
121
127
 
@@ -132,9 +138,11 @@ clawo session-list
132
138
  ### session-status
133
139
 
134
140
  ```bash
135
- clawo session-status <name>
141
+ clawo session-status <name> [--json]
136
142
  ```
137
143
 
144
+ `--json` prints the whole status (`stats` with turns, tool calls, tokens, cost and the engine's resume id) as one line.
145
+
138
146
  ### session-grep
139
147
 
140
148
  ```bash
@@ -238,6 +246,37 @@ engine may appear more than once. With `--wait` the run is followed to the end
238
246
  and every answer is printed, followed by the synthesis when `--synthesize` was
239
247
  given. Checks run after the fan-out, as for `solve`.
240
248
 
249
+ ## `clawo goal`
250
+
251
+ Run a Codex `/goal` on one `codex-app` thread, then have the runtime check the
252
+ result: goal → verify → repair on the same thread. See [workflow.md](./workflow.md#goal).
253
+
254
+ ```bash
255
+ clawo goal "<objective>" | --objective-file <file>
256
+ [--check "<command>"]... [--contract <file>] [--check-timeout <minutes>]
257
+ [--launcher <arg>]... [--model <model>] [--effort <level>] [--sandbox <mode>] [--thread <id>]
258
+ [--token-budget N] [--goal-timeout <minutes>] [--max-repairs N]
259
+ [--cwd <dir>] [--wait] [--json]
260
+ ```
261
+
262
+ | Option | Default | Notes |
263
+ | ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------- |
264
+ | `--objective-file` | — | Read the objective from a file instead of the argument. Codex accepts at most 4,000 characters |
265
+ | `-c, --check` | — | A command check, repeatable, run after the goal. Split on whitespace; quote-needing commands go in `--contract` |
266
+ | `--check-timeout` | 10 | Minutes for each `--check`. The verifier's node timeout is sized from the checks |
267
+ | `--launcher` | — | Run codex under this command, one argv element per flag: `--launcher ./sandbox.sh --launcher task --launcher "0 1"` |
268
+ | `-m, --model` | codex's own | Codex model |
269
+ | `--sandbox` | `workspace-write` | Codex's own sandbox mode. With an outer sandbox as the boundary, `danger-full-access` |
270
+ | `--thread` | — | Start on this existing codex thread: its goal is replaced, its history kept |
271
+ | `--token-budget` | — | The goal stops as `budgetLimited` past this |
272
+ | `--goal-timeout` | none | Wall-clock minutes for one goal pass |
273
+ | `--max-repairs` | `1` | Times a red verdict sends the goal back to the same thread |
274
+ | `-w, --wait` | off | Follow the run; exit `0` only if it completes |
275
+
276
+ `clawo workflow show <runId>` prints the goal's status, tokens, time, resume
277
+ attempts and thread id while it runs; `clawo workflow steer <runId> "<text>"`
278
+ goes into the running turn.
279
+
241
280
  ## `clawo workflow`
242
281
 
243
282
  ```bash
@@ -245,7 +284,7 @@ clawo workflow list [--state <s>] [--workflow <name>] [--limit N] [--json]
245
284
  clawo workflow show <runId> [--json]
246
285
  clawo workflow resume <runId> # re-attach to a run whose process died
247
286
  clawo workflow cancel <runId>
248
- clawo workflow steer <runId> "<text>" # queue a correction for the next agent node
287
+ clawo workflow steer <runId> "<text>" # a correction for the next agent node, or into a running goal
249
288
  clawo workflow approve <runId> [reject]
250
289
  ```
251
290
 
@@ -269,7 +308,7 @@ files included).
269
308
 
270
309
  ## `clawo engines`
271
310
 
272
- Lists the community engine presets bundled with the installed package, with each
311
+ Lists the community engine presets bundled with the installed package (custom engines and ACP agents), with each
273
312
  one's provenance — who attested it, against which engine version, on what date.
274
313
  Read locally rather than over HTTP, since it is a property of the package and has
275
314
  to work with no server running.
@@ -278,9 +317,10 @@ to work with no server running.
278
317
  clawo engines
279
318
  clawo engines --json
280
319
  clawo session-start my-session -e custom --custom-engine <id>
320
+ clawo session-start my-session -e acp --acp-agent <id> # an ACP agent preset
281
321
  ```
282
322
 
283
- A preset id is the only form of custom engine the CLI can pass: it reaches the
323
+ A preset id is the only form of custom engine or ACP agent the CLI can pass: it reaches the
284
324
  session through the HTTP surface, which refuses inline configs because those name
285
325
  a binary and its arguments. See [multi-engine.md](./multi-engine.md) for the tiers
286
326
  and what a community preset does and does not claim.
@@ -120,7 +120,11 @@ that both read the file always agree.
120
120
  Opening a run whose `status` is `terminated` (because its process has
121
121
  exited, or because you're viewing it cross-process) fetches
122
122
  `/autoloop/<id>/chat_history`, replays the conversation into the Planner pane,
123
- and shows a green **Resume run** button in the topbar. Clicking it POSTs `/autoloop/<id>/resume`;
123
+ and shows a green **Resume run** button in the topbar. The same button is shown
124
+ for any live paused run, and it follows later SSE state: a pause adds it, and
125
+ returning to an active status removes it. Timeout fields are included only when
126
+ `pending_dispatch` exists; an ordinary or activity-lease pause resumes with
127
+ an empty timeout body. Clicking it POSTs `/autoloop/<id>/resume`;
124
128
  the orchestrator re-attaches the Planner (reusing the persisted Claude
125
129
  session ID when available, so Claude's context picks up where it left
126
130
  off) and the dashboard reconnects to `/events` for live updates.
@@ -62,7 +62,7 @@ await manager.startSession({
62
62
 
63
63
  ### OpenAI Codex (`engine: 'codex'`)
64
64
 
65
- Wraps the `codex exec` subcommand. Each `send()` spawns a new process. Tested with `codex` CLI **0.163.0**.
65
+ Wraps the `codex exec` subcommand. Each `send()` spawns a new process. Tested with `codex` CLI **0.164.0**.
66
66
 
67
67
  - Non-interactive execution via `codex exec --sandbox workspace-write --skip-git-repo-check --json`
68
68
  - Real `usage` from the `turn.completed` JSON event (input, output, cached, reasoning tokens). **These are cumulative over the thread, not per turn**, so they replace the session totals rather than being added to them; subtracting consecutive values gives one turn's prompt
@@ -102,19 +102,18 @@ await manager.startSession({
102
102
 
103
103
  ### OpenAI Codex App-Server (`engine: 'codex-app'`)
104
104
 
105
- Wraps `codex app-server --listen stdio:// --enable goals` as a long-running JSON-RPC subprocess. **Required for `/goal` long-horizon objective support** — Codex's exec subcommand has no slash-command surface.
105
+ Wraps `codex app-server --listen stdio:// --enable goals` as a long-running JSON-RPC subprocess. **Required for `/goal` long-horizon objective support** — Codex's exec subcommand has no goal surface. Tested with `codex` CLI **0.164.0**.
106
106
 
107
107
  - Long-running subprocess; one `codex app-server` per session
108
108
  - JSON-RPC 2.0 over stdio with v2 protocol method names (`initialize`, `thread/start`, `turn/start`, ...)
109
109
  - Real-time streaming via `item/agentMessage/delta` notifications
110
110
  - Cumulative token tracking from `thread/tokenUsage/updated` notifications. The same notification's `last` breakdown and `modelContextWindow` drive `contextPercent`, so it reports live occupancy against the window the server enforces rather than a running total over the model's published window
111
111
  - `appendSystemPrompt` is placed at the top of the first message of a new thread (app-server has no system-prompt flag); a resumed thread already carries it
112
- - Goal lifecycle observation via `thread/goal/updated` and `thread/goal/cleared` notifications
113
- - Goal control via the `codex_goal_*` tools (which internally send the `/goal` slash command as user text — see [tools.md](./tools.md#codex-13))
114
- - v2 RPC tools (Codex 0.137): `codex_interrupt` (`turn/interrupt`), `codex_steer` (`turn/steer`), `codex_fork` (`thread/fork`), `codex_rollback` (`thread/rollback`), `codex_models` (`model/list`), `codex_thread_list` (`thread/list`). A `turn/completed` with `status: 'failed'` rejects the turn and increments `toolErrors`.
115
- - Thread resume: starting with `resumeSessionId` loads the existing thread via `thread/resume` instead of `thread/start`.
116
-
117
- > **Feature flag.** `goals` is an experimental Codex feature. The session always passes `--enable goals`; some goal commands may still fail or be ignored by the server.
112
+ - Goals through the typed RPCs `thread/goal/set` / `get` / `clear`: setting an objective starts the server's own turn loop, which runs until the goal is `complete`, `budgetLimited`, `blocked`, `usageLimited` or `paused`. Each change arrives as `thread/goal/updated`. The `codex_goal_*` tools wrap these; the kernel's `goal` node drives them for unattended runs ([workflow.md](./workflow.md#goal))
113
+ - `error` notifications are read as `{ error: { message, codexErrorInfo }, willRetry }`. The session keeps the last one (`lastError`, with `codexErrorInfo` as a name such as `serverOverloaded`) and emits it as `codex:error`; an error notification never throws when nothing listens for errors
114
+ - v2 RPC tools (Codex 0.137): `codex_interrupt` (`turn/interrupt`), `codex_steer` (`turn/steer`, including into a turn the goal loop started), `codex_fork` (`thread/fork`), `codex_rollback` (`thread/rollback`), `codex_models` (`model/list`), `codex_thread_list` (`thread/list`). A `turn/completed` with `status: 'failed'` rejects the turn and increments `toolErrors`.
115
+ - Threads are opened and resumed with `approvalPolicy: "never"`, and a server request the session cannot handle (an approval, a request for user input) gets an error reply at once: nothing here can answer one, and an unanswered request blocks its turn. The sandbox mode is the boundary.
116
+ - Thread resume: starting with `resumeSessionId` loads the existing thread via `thread/resume` instead of `thread/start`. The id the session manager stores and replays (model switch, restart) is the app-server's own thread id. A thread resumed with an active goal continues it on its own.
118
117
 
119
118
  ```typescript
120
119
  await manager.startSession({
@@ -123,12 +122,22 @@ await manager.startSession({
123
122
  model: 'gpt-5.5',
124
123
  cwd: '/project',
125
124
  });
126
- // Then either:
127
- // await manager.codexGoalCommand('codex-goal-task', 'build a tic-tac-toe app');
125
+ await manager.codexGoal('codex-goal-task', { action: 'set', objective: 'build a tic-tac-toe app' });
128
126
  // or via the codex_goal_set tool:
129
127
  // await tool('codex_goal_set', { name: 'codex-goal-task', objective: 'build a tic-tac-toe app' });
130
128
  ```
131
129
 
130
+ ### Running an engine under a launcher
131
+
132
+ `SessionConfig.launcher` is an argv prefix the engine binary runs under, for every
133
+ engine: `launcher: ['/opt/task/sandbox.sh', 'task', '0 1']` spawns
134
+ `/opt/task/sandbox.sh task '0 1' codex app-server …`. This is how a caller puts
135
+ the agent inside its own sandbox (bubblewrap, a container entry point, `taskset`)
136
+ without a custom engine. The launcher is the caller's own command, at the same
137
+ trust level as a contract's command check, which the HTTP API also accepts: set
138
+ it through the SessionManager API, `/session/start` or a workflow spec (the `goal`
139
+ node's `launcher`). It is not a parameter of the `session_start` tool.
140
+
132
141
  ### Google Antigravity (`engine: 'agy'`)
133
142
 
134
143
  Wraps Google's **Antigravity CLI** (`agy`) — the successor to Gemini CLI (consumer
@@ -307,6 +316,26 @@ await manager.startSession({
307
316
  });
308
317
  ```
309
318
 
319
+ ### ACP agents (`engine: 'acp'`)
320
+
321
+ Drives any agent that serves the [Agent Client Protocol](https://agentclientprotocol.com) on stdio, with no per-agent code. Run through it so far: Kimi Code 2.3.1 (`kimi acp`), DeepSeek's dsh 0.2.1-rc.2 (`dsh --profile acp`) and OpenCode 1.19.4 (`opencode acp`). This is the client side of the protocol; [acp.md](./acp.md) is the other side, where the orchestrator is the agent.
322
+
323
+ - `acpAgent` names the agent: a bundled preset id (`kimi-code`, `dsh`; `clawo engines` lists them), or, from a local caller only, an inline `{ name, command, commandEnv?, args?, env?, contextWindow?, pricing? }`. Over HTTP, which includes the `clawo` CLI, only a preset id is accepted, as for `customEngine`.
324
+ - One agent process per session; each send is one `session/prompt` on one ACP session, so the conversation carries over between sends. `initialize` advertises no `fs` or `terminal` capability: the agent reads, writes and runs commands with its own tools.
325
+ - A turn succeeds when the agent ends it with `stopReason: "end_turn"`; any other stop reason (`refusal`, `max_tokens`, `cancelled`, …) fails it. A turn that runs past its timeout is cancelled with `session/cancel`. An agent that exits mid-turn fails the turn and the session.
326
+ - `session/request_permission` is answered at once from `permissionMode`: `bypassPermissions`, `acceptEdits`, `auto` and `dontAsk` pick an allow option, the others a reject option. Nothing waits on a person.
327
+ - Resume: the agent's session id is the resume id (`stats.acpSessionId`). A resumed session reattaches it with `session/resume`, or `session/load` when that is all the agent offers; an agent with neither fails the start rather than opening a new conversation.
328
+ - Usage and cost are whatever the agent reports (`PromptResponse.usage`, `usage_update`). With `pricing` set and no reported cost, the cost is estimated from the reported tokens. Kimi Code 2.3.1 and dsh 0.2.1-rc.2 report neither, so their sessions show 0 tokens and $0. OpenCode reports tokens.
329
+ - The model and credentials are the agent's own configuration, set in its environment:
330
+ - Kimi Code: `KIMI_MODEL_NAME`, `KIMI_MODEL_API_KEY`, `KIMI_MODEL_BASE_URL`, `KIMI_MODEL_MAX_CONTEXT_SIZE`, `KIMI_MODEL_CAPABILITIES`, or a `kimi` login. `KIMI_BIN` overrides the command.
331
+ - dsh: `DEEPSEEK_API_KEY` (and `DEEPSEEK_BASE_URL`); its profile chooses the model. `DSH_BIN` overrides the command.
332
+ - `launcher` applies as for every engine.
333
+
334
+ ```bash
335
+ clawo session-start kimi -e acp --acp-agent kimi-code --permission-mode bypassPermissions -d ./project
336
+ clawo session-send kimi "Fix the failing test in tests/test_io.py"
337
+ ```
338
+
310
339
  ### Community engine presets
311
340
 
312
341
  `customEngine` accepts either an inline `CustomEngineConfig` or the id of a preset