@enderfga/claw-orchestrator 7.14.0 → 7.16.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 (145) hide show
  1. package/README.md +162 -135
  2. package/configs/autoloop-reviewer-prompt.md +1 -1
  3. package/configs/engines/README.md +31 -11
  4. package/dist/bin/acp-server.js +7 -12
  5. package/dist/bin/acp-server.js.map +1 -1
  6. package/dist/bin/cli.js +84 -46
  7. package/dist/bin/cli.js.map +1 -1
  8. package/dist/bin/mcp-server.js +2 -54
  9. package/dist/bin/mcp-server.js.map +1 -1
  10. package/dist/src/acp-server.d.ts +17 -9
  11. package/dist/src/acp-server.js +149 -30
  12. package/dist/src/acp-server.js.map +1 -1
  13. package/dist/src/autoloop/agent-tools.d.ts +2 -0
  14. package/dist/src/autoloop/agent-tools.js +7 -0
  15. package/dist/src/autoloop/agent-tools.js.map +1 -1
  16. package/dist/src/autoloop/dispatcher.d.ts +6 -0
  17. package/dist/src/autoloop/dispatcher.js +72 -9
  18. package/dist/src/autoloop/dispatcher.js.map +1 -1
  19. package/dist/src/autoloop/planner-tools.js +2 -0
  20. package/dist/src/autoloop/planner-tools.js.map +1 -1
  21. package/dist/src/claude-goal-session.d.ts +147 -0
  22. package/dist/src/claude-goal-session.js +355 -0
  23. package/dist/src/claude-goal-session.js.map +1 -0
  24. package/dist/src/council.d.ts +8 -0
  25. package/dist/src/council.js +45 -12
  26. package/dist/src/council.js.map +1 -1
  27. package/dist/src/dashboard/index.html +28 -14
  28. package/dist/src/embedded-server.js +27 -8
  29. package/dist/src/embedded-server.js.map +1 -1
  30. package/dist/src/engine-spawn.js +3 -1
  31. package/dist/src/engine-spawn.js.map +1 -1
  32. package/dist/src/fanout.d.ts +13 -3
  33. package/dist/src/fanout.js +10 -0
  34. package/dist/src/fanout.js.map +1 -1
  35. package/dist/src/inbox-manager.d.ts +9 -0
  36. package/dist/src/inbox-manager.js +8 -2
  37. package/dist/src/inbox-manager.js.map +1 -1
  38. package/dist/src/index.d.ts +2 -0
  39. package/dist/src/index.js +135 -53
  40. package/dist/src/index.js.map +1 -1
  41. package/dist/src/kernel/agent-step.d.ts +6 -0
  42. package/dist/src/kernel/agent-step.js.map +1 -1
  43. package/dist/src/kernel/conditions.d.ts +1 -1
  44. package/dist/src/kernel/conditions.js +1 -1
  45. package/dist/src/kernel/engine.d.ts +28 -8
  46. package/dist/src/kernel/engine.js +93 -19
  47. package/dist/src/kernel/engine.js.map +1 -1
  48. package/dist/src/kernel/nodes/agent.js +2 -0
  49. package/dist/src/kernel/nodes/agent.js.map +1 -1
  50. package/dist/src/kernel/nodes/council.js +9 -4
  51. package/dist/src/kernel/nodes/council.js.map +1 -1
  52. package/dist/src/kernel/nodes/fanout.js +5 -0
  53. package/dist/src/kernel/nodes/fanout.js.map +1 -1
  54. package/dist/src/kernel/nodes/goal.d.ts +19 -5
  55. package/dist/src/kernel/nodes/goal.js +81 -34
  56. package/dist/src/kernel/nodes/goal.js.map +1 -1
  57. package/dist/src/kernel/nodes/subflow.js +9 -1
  58. package/dist/src/kernel/nodes/subflow.js.map +1 -1
  59. package/dist/src/kernel/nodes/ultraapp.d.ts +1 -0
  60. package/dist/src/kernel/nodes/ultraapp.js +1 -0
  61. package/dist/src/kernel/nodes/ultraapp.js.map +1 -1
  62. package/dist/src/kernel/nodes/verifier.js +5 -1
  63. package/dist/src/kernel/nodes/verifier.js.map +1 -1
  64. package/dist/src/kernel/projections.d.ts +1 -0
  65. package/dist/src/kernel/projections.js +7 -1
  66. package/dist/src/kernel/projections.js.map +1 -1
  67. package/dist/src/kernel/templates/index.d.ts +16 -11
  68. package/dist/src/kernel/templates/index.js +14 -8
  69. package/dist/src/kernel/templates/index.js.map +1 -1
  70. package/dist/src/kernel/types.d.ts +37 -13
  71. package/dist/src/kernel/types.js.map +1 -1
  72. package/dist/src/logger.d.ts +6 -0
  73. package/dist/src/logger.js +14 -0
  74. package/dist/src/logger.js.map +1 -1
  75. package/dist/src/mcp-annotations.d.ts +13 -0
  76. package/dist/src/mcp-annotations.js +100 -0
  77. package/dist/src/mcp-annotations.js.map +1 -0
  78. package/dist/src/models.d.ts +7 -0
  79. package/dist/src/models.js +9 -0
  80. package/dist/src/models.js.map +1 -1
  81. package/dist/src/openai-compat.d.ts +11 -5
  82. package/dist/src/openai-compat.js +55 -54
  83. package/dist/src/openai-compat.js.map +1 -1
  84. package/dist/src/persistent-acp-session.d.ts +7 -0
  85. package/dist/src/persistent-acp-session.js +26 -2
  86. package/dist/src/persistent-acp-session.js.map +1 -1
  87. package/dist/src/persistent-codex-app-session.d.ts +2 -0
  88. package/dist/src/persistent-codex-app-session.js +18 -9
  89. package/dist/src/persistent-codex-app-session.js.map +1 -1
  90. package/dist/src/persistent-codex-session.d.ts +14 -3
  91. package/dist/src/persistent-codex-session.js +22 -19
  92. package/dist/src/persistent-codex-session.js.map +1 -1
  93. package/dist/src/persistent-custom-session.d.ts +9 -0
  94. package/dist/src/persistent-custom-session.js +41 -21
  95. package/dist/src/persistent-custom-session.js.map +1 -1
  96. package/dist/src/persistent-grok-session.js +1 -1
  97. package/dist/src/persistent-grok-session.js.map +1 -1
  98. package/dist/src/persistent-session.d.ts +9 -0
  99. package/dist/src/persistent-session.js +23 -0
  100. package/dist/src/persistent-session.js.map +1 -1
  101. package/dist/src/run-ledger.d.ts +3 -3
  102. package/dist/src/session-manager.d.ts +45 -1
  103. package/dist/src/session-manager.js +199 -34
  104. package/dist/src/session-manager.js.map +1 -1
  105. package/dist/src/types.d.ts +34 -11
  106. package/dist/src/types.js.map +1 -1
  107. package/dist/src/ultraapp/build.d.ts +5 -11
  108. package/dist/src/ultraapp/build.js +5 -11
  109. package/dist/src/ultraapp/build.js.map +1 -1
  110. package/dist/src/ultraapp/council-adapter.d.ts +5 -2
  111. package/dist/src/ultraapp/council-adapter.js +6 -6
  112. package/dist/src/ultraapp/council-adapter.js.map +1 -1
  113. package/dist/src/ultraapp/files.d.ts +7 -0
  114. package/dist/src/ultraapp/files.js +7 -1
  115. package/dist/src/ultraapp/files.js.map +1 -1
  116. package/dist/src/ultraapp/manager.d.ts +23 -3
  117. package/dist/src/ultraapp/manager.js +170 -72
  118. package/dist/src/ultraapp/manager.js.map +1 -1
  119. package/dist/src/ultraapp/narrator.js +1 -1
  120. package/dist/src/ultraapp/narrator.js.map +1 -1
  121. package/dist/src/ultraapp/versions.d.ts +27 -5
  122. package/dist/src/ultraapp/versions.js +58 -13
  123. package/dist/src/ultraapp/versions.js.map +1 -1
  124. package/openclaw.plugin.json +4 -13
  125. package/package.json +13 -6
  126. package/skills/SKILL.md +52 -24
  127. package/skills/references/acp.md +140 -61
  128. package/skills/references/autoloop.md +148 -38
  129. package/skills/references/claude-cli-tracking.md +9 -6
  130. package/skills/references/cli.md +139 -108
  131. package/skills/references/council.md +44 -22
  132. package/skills/references/dashboard.md +37 -21
  133. package/skills/references/getting-started.md +49 -15
  134. package/skills/references/inbox.md +13 -8
  135. package/skills/references/mcp.md +25 -17
  136. package/skills/references/multi-engine.md +161 -145
  137. package/skills/references/observability.md +90 -58
  138. package/skills/references/openai-compat.md +172 -82
  139. package/skills/references/sessions.md +101 -65
  140. package/skills/references/tools.md +217 -158
  141. package/skills/references/ultra.md +7 -7
  142. package/skills/references/ultraapp.md +101 -56
  143. package/skills/references/verification.md +112 -56
  144. package/skills/references/workflow.md +275 -97
  145. package/assets/banner.jpg +0 -0
@@ -5,9 +5,9 @@ HTTP server. It lets you **launch and observe** Council sessions, Autoloop
5
5
  runs and Forge (Ultraapp) builds, and browse durable workflow runs, from a
6
6
  browser — no CLI, no webchat, no plugin tool calls needed.
7
7
 
8
- URL: `http://127.0.0.1:18796/dash` (local) or whatever public hostname you
9
- front the embedded server with (the recommended setup uses a path-based
10
- reverse proxy, e.g. `https://<your-host>/dash`).
8
+ URL: `http://127.0.0.1:18796/dash` (or `/dashboard`) locally, or whatever public
9
+ hostname you front the embedded server with (the recommended setup uses a
10
+ path-based reverse proxy, e.g. `https://<your-host>/dash`).
11
11
 
12
12
  ## Tabs
13
13
 
@@ -23,6 +23,17 @@ view-only (start runs with `workflow_start`). Council and Autoloop open a
23
23
  modal form (because they need workspace/task input); Forge POSTs an empty
24
24
  body and drops you into an interview (the spec is built conversationally).
25
25
 
26
+ - The **Council** form takes a task, a project directory and an optional round
27
+ limit (default 15). It starts a fixed team of three Claude agents — a planner,
28
+ an implementer and a reviewer — with `bypassPermissions`. Use `council_start`
29
+ for your own personas, engines or models.
30
+ - The **Autoloop** form takes a workspace and an optional Planner model; the run
31
+ id is generated. Other role choices are available through `POST /autoloop/new`
32
+ or `autoloop_start`.
33
+
34
+ The header shows the spend recorded in the run ledger over the last 24 hours,
35
+ across every engine, refreshed every 30 seconds.
36
+
26
37
  ## Standalone deployment
27
38
 
28
39
  The recommended way to run the dashboard 24/7 is a separate `clawo serve`
@@ -117,32 +128,36 @@ that both read the file always agree.
117
128
 
118
129
  ## Resuming a terminated autoloop run
119
130
 
120
- Opening a run whose `status` is `terminated` (because its process has
121
- exited, or because you're viewing it cross-process) fetches
122
- `/autoloop/<id>/chat_history`, replays the conversation into the Planner pane,
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`;
128
- the orchestrator re-attaches the Planner (reusing the persisted Claude
129
- session ID when available, so Claude's context picks up where it left
130
- off) and the dashboard reconnects to `/events` for live updates.
131
+ Opening any autoloop run fetches `/autoloop/<id>/chat_history` and replays it
132
+ into the three panes, so the conversation survives a page refresh. A green
133
+ **Resume run** button appears in the topbar when the run is not live in this
134
+ server's process (it has exited, or another process owns it), or when its status
135
+ is `paused` or `terminated`. It follows later SSE state: a pause adds it, and
136
+ returning to an active status removes it.
137
+
138
+ Clicking it POSTs `/autoloop/<id>/resume`. Timeout fields are included only when
139
+ `pending_dispatch` exists — the button then sends that dispatch's id with a
140
+ send timeout one minute longer than the one that expired; an ordinary or
141
+ activity-lease pause resumes with an empty timeout body. The orchestrator
142
+ re-attaches the Planner (reusing its persisted conversation where the engine
143
+ supports resume, so its context picks up where it left off) and the dashboard
144
+ reconnects to `/events` for live updates.
131
145
 
132
146
  If the run used a **custom engine** for any role, the button first asks
133
147
  `/autoloop/<id>/resume-requirements` and prompts for one reference name per
134
148
  role — the name of a `CLAWO_CUSTOM_ENGINE_<NAME>` variable on the orchestrator
135
- host. The config itself is never stored and never sent; only the name is.
149
+ host, whose value is the JSON custom-engine config. The config itself is never
150
+ stored and never sent; only the name is.
136
151
 
137
152
  A run without a `chat.jsonl` or a persisted session still resumes, with a blank
138
- Planner pane and a fresh Claude context.
153
+ Planner pane and a fresh Planner context.
139
154
 
140
155
  ## Cross-process visibility
141
156
 
142
157
  Every council, autoloop and workflow run is a durable kernel run stored under
143
- `~/.claw-orchestrator/wf/`, so the dashboard lists runs started by any process —
144
- the OpenClaw plugin, `clawo serve`, or the CLI — sorted newest-first, until the
145
- run records are deleted. Forge runs are read from
158
+ `~/.claw-orchestrator/wf/` (or `$CLAWO_WF_DIR`), so the dashboard lists runs
159
+ started by any process — the OpenClaw plugin, `clawo serve`, or the CLI — sorted
160
+ newest-first, until the run records are deleted. Forge runs are read from
146
161
  `~/.claw-orchestrator/ultraapps/`.
147
162
 
148
163
  ## Reverse-proxy integration
@@ -172,11 +187,12 @@ launchctl kickstart -k "gui/$(id -u)/com.clawo.serve"
172
187
 
173
188
  ## Runs tab
174
189
 
175
- Lists durable workflow runs. Because runs are checkpointed to
190
+ Lists the 50 most recent durable workflow runs. Because runs are checkpointed to
176
191
  disk, this sees runs started by other processes and by earlier sessions, not just
177
192
  what the current server started.
178
193
 
179
- Each row shows the run state and its verdict as one of three things:
194
+ Each row shows the run state, its recorded cost when there is one, and its verdict
195
+ as one of three things:
180
196
 
181
197
  - **verified** — an acceptance contract ran and passed.
182
198
  - **refuted** — a contract ran and a required check failed.
@@ -13,9 +13,26 @@ clawo serve
13
13
  # Drive sessions from the command line
14
14
  clawo session-start myproject -d ~/project
15
15
  clawo session-send myproject "fix the auth bug"
16
+ clawo session-status myproject
16
17
  clawo session-stop myproject
17
18
  ```
18
19
 
20
+ `clawo serve` listens on `127.0.0.1:18796` (`-p/--port`, `-H/--host`; `OPENCLAW_SERVER_HOST`
21
+ also sets the bind address) and prints the dashboard URL, `http://127.0.0.1:18796/dashboard`.
22
+ Apart from `clawo engines` and `clawo acp`, which run locally, the other `clawo` commands are
23
+ HTTP clients of that server: they read its address from `CLAWO_API_URL` (default
24
+ `http://127.0.0.1:18796`) and its token as described under
25
+ [Embedded Server Authentication](#embedded-server-authentication), and a request that fails or
26
+ cannot reach the server exits with status 1. `session-start -e <engine>` picks the engine
27
+ (default `claude`; `codex`, `codex-app`, `agy`, `grok`, `opencode`, `acp` with
28
+ `--acp-agent <id>`, `custom` with `--custom-engine <id>`);
29
+ `session-send --message-file <file>` sends a long message, and `--json` on `session-send` and
30
+ `session-status` prints the full result. See [cli.md](./cli.md) for every command.
31
+
32
+ `clawo serve` does not read the OpenClaw plugin configuration below; it allows 32 concurrent
33
+ sessions and reaps idle ones after 60 minutes (`OPENCLAW_SERVE_MAX_SESSIONS`,
34
+ `OPENCLAW_SERVE_TTL_MINUTES`).
35
+
19
36
  ### As OpenClaw Plugin
20
37
 
21
38
  ```bash
@@ -23,9 +40,11 @@ openclaw plugins install @enderfga/claw-orchestrator --dangerously-force-unsafe-
23
40
  openclaw gateway restart
24
41
  ```
25
42
 
26
- > **Why `--dangerously-force-unsafe-install`?** Claw Orchestrator spawns Claude Code / Codex / Antigravity / Grok Build / OpenCode CLI subprocesses via `child_process`, which OpenClaw's security scanner flags by design. The flag is required — there is no way to drive coding CLIs without process spawning.
43
+ > **Why `--dangerously-force-unsafe-install`?** Claw Orchestrator spawns Claude Code / Codex / Antigravity / Grok Build / OpenCode / ACP agent subprocesses via `child_process`, which OpenClaw's security scanner flags by design. The flag is required — there is no way to drive coding CLIs without process spawning.
27
44
 
28
- Agents automatically get access to all session, council, and management tools.
45
+ Agents automatically get access to all session, council, and management tools. The plugin starts
46
+ the same embedded HTTP server on the first tool call (set `CLAWO_NO_EMBEDDED_SERVER=1` to skip
47
+ it), so the `clawo` CLI and the dashboard work against a running plugin too.
29
48
 
30
49
  ### TypeScript Library
31
50
 
@@ -49,12 +68,15 @@ await manager.stopSession('backend-fix');
49
68
  ## Requirements
50
69
 
51
70
  - **Node.js >= 22**
52
- - **Claude Code CLI >= 2.1** — `npm install -g @anthropic-ai/claude-code`
71
+ - **Claude Code CLI >= 2.1.259** — `npm install -g @anthropic-ai/claude-code`. A session with no permission-prompt tool passes `--permission-prompts none`, which 2.1.259 added
53
72
  - **OpenClaw >= 2026.3.0** — for plugin mode (optional)
54
- - **OpenAI Codex CLI >= 0.112** — `npm install -g @openai/codex` (optional, for codex engine)
73
+ - **OpenAI Codex CLI** — `npm install -g @openai/codex` (optional). The `codex` engine needs >= 0.119 for `codex exec resume`, which every send after the first uses. The `codex-app` engine and its goal RPCs are tested with 0.164.0
55
74
  - **Antigravity CLI** — `curl -fsSL https://antigravity.google/cli/install.sh | bash` (optional, for the `agy` engine — Google's successor to the sunset Gemini CLI)
56
- - **Grok Build CLI** — optional, for the `grok` engine
57
- - **OpenCode CLI** — `npm install -g opencode-ai` (optional, for the `opencode` engine)
75
+ - **Grok Build CLI** — see `x.ai/cli` (optional, for the `grok` engine)
76
+ - **OpenCode CLI 1.x** — `npm install -g opencode-ai` (optional, for the `opencode` engine). OpenCode 2 (the `@opencode/cli` package) is refused at session start
77
+ - **An ACP agent** — optional, for the `acp` engine: any agent that serves the Agent Client Protocol on stdio, such as Kimi Code (`kimi acp`), dsh (`dsh --profile acp`) or `opencode acp`
78
+
79
+ Tested versions of each engine are in the [README](../../README.md#engine-compatibility).
58
80
 
59
81
  ### Engine Authentication
60
82
 
@@ -65,6 +87,7 @@ Each engine requires its own authentication before use:
65
87
  - **Antigravity** — run `agy` once and complete the Google OAuth login
66
88
  - **Grok** — run `grok` once and sign in (grok.com account or `XAI_API_KEY`)
67
89
  - **OpenCode** — run `opencode auth login`, or set a provider key such as `ANTHROPIC_API_KEY`
90
+ - **ACP agents** — the agent's own login or environment (for example `KIMI_MODEL_*` for Kimi Code, `DEEPSEEK_API_KEY` for dsh); see [Multi-Engine](./multi-engine.md#acp-agents-engine-acp)
68
91
 
69
92
  The plugin does not manage authentication — it expects each CLI to be ready to run.
70
93
 
@@ -76,7 +99,9 @@ Authentication on the embedded HTTP server (used by the CLI and standalone mode)
76
99
  | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
77
100
  | `OPENCLAW_SERVER_TOKEN` | Unset: a random token is generated. Set to a value: use that token. Set to `disabled`: turn auth off (single-user hosts only) |
78
101
 
79
- On start the server writes the token to `~/.openclaw/server-token` (mode 0600) and reuses it across restarts; the CLI reads it automatically. Every request except `/health` must carry it as `Authorization: Bearer <token>` or the `clawo_auth` cookie. Browsers sign in once via `/login?token=<token>&redirect=/dashboard`, which sets the cookie.
102
+ On start the server writes the token to `~/.openclaw/server-token` (mode 0600) and reuses it across restarts; delete the file and restart the server to rotate it. Every request except `/health` must carry it as `Authorization: Bearer <token>`, the `clawo_auth` cookie, or a `?token=` query parameter. Browsers sign in once via `/login?token=<token>&redirect=/dashboard`, which sets the cookie and redirects, so the token does not stay in the address bar.
103
+
104
+ The CLI finds the token on its own: `CLAWO_AUTH_TOKEN`, then `OPENCLAW_SERVER_TOKEN`, then the token file.
80
105
 
81
106
  ### OpenAI-Compatible Endpoint
82
107
 
@@ -97,7 +122,7 @@ See [openai-compat.md](./openai-compat.md) for the full session-keying rules, `X
97
122
 
98
123
  ## Configuration
99
124
 
100
- In `~/.openclaw/openclaw.json`:
125
+ In plugin mode, in `~/.openclaw/openclaw.json`:
101
126
 
102
127
  ```jsonc
103
128
  {
@@ -107,16 +132,10 @@ In `~/.openclaw/openclaw.json`:
107
132
  "enabled": true,
108
133
  "config": {
109
134
  "claudeBin": "claude",
110
- "defaultModel": "claude-opus-5-5",
111
135
  "defaultPermissionMode": "acceptEdits",
112
136
  "defaultEffort": "auto",
113
137
  "maxConcurrentSessions": 5,
114
138
  "sessionTtlMinutes": 120,
115
- "proxy": {
116
- "enabled": false,
117
- "bigModel": "gemini-3.1-pro-preview",
118
- "smallModel": "gemini-3-flash-preview",
119
- },
120
139
  },
121
140
  },
122
141
  },
@@ -124,13 +143,28 @@ In `~/.openclaw/openclaw.json`:
124
143
  }
125
144
  ```
126
145
 
146
+ | Key | Default | Meaning |
147
+ | ----------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
148
+ | `claudeBin` | `claude` | Claude Code binary |
149
+ | `defaultModel` | unset | Model for a session that names none, on an engine that runs that model; the claude engine takes any model. Other engines, and every engine when it is unset, run their own default |
150
+ | `defaultPermissionMode` | `acceptEdits` | Permission mode for a session that names none |
151
+ | `defaultEffort` | `auto` | Effort for a session that names none |
152
+ | `maxConcurrentSessions` | `5` | Most sessions open at once; a start beyond it is refused |
153
+ | `sessionTtlMinutes` | `120` | Idle sessions are stopped after this long |
154
+ | `pricingOverrides` | none | Per-model rates, USD per 1M tokens: `{"gpt-5.5": {"input": 0, "output": 0, "cached": 0}}` for a flat-rate plan. See [Zeroing a model's pricing](./observability.md#zeroing-a-models-pricing) |
155
+ | `proxy.enabled` | on | `false` stops the plugin from registering the multi-model proxy routes on the OpenClaw gateway |
156
+
127
157
  ## Next Steps
128
158
 
129
159
  - [Sessions](./sessions.md) — persistent session lifecycle and management
130
160
  - [Session Inbox](./inbox.md) — cross-session messaging
131
- - [Multi-Engine](./multi-engine.md) — one interface over Claude Code, Codex, Antigravity, Grok Build, OpenCode and custom CLIs
161
+ - [Multi-Engine](./multi-engine.md) — one interface over Claude Code, Codex, Antigravity, Grok Build, OpenCode, ACP agents and custom CLIs
132
162
  - [Council](./council.md) — multi-agent collaboration with consensus voting
133
163
  - [Ultraplan & Ultrareview](./ultra.md) — deep planning and fleet code review
164
+ - [Workflows](./workflow.md) — durable runs and the `solve`, `council`, `fanout` and `goal` templates
165
+ - [Verification](./verification.md) — acceptance contracts the runtime checks itself
166
+ - [Observability](./observability.md) — the run ledger and spend caps
167
+ - [Dashboard](./dashboard.md) — the browser UI served at `/dashboard`
134
168
  - [Tools Reference](./tools.md) — complete tool API reference (78 tools)
135
169
  - [CLI Reference](./cli.md) — command-line interface
136
170
  - [MCP Server](./mcp.md) — expose the tools to any MCP host
@@ -15,15 +15,17 @@ Session A (planner) SessionManager Session B (coder)
15
15
  │ │ queue in inbox │
16
16
  │ │ │ │
17
17
  │ │ ... B becomes idle │
18
- │ ├── deliverInbox(B) ────►│ deliver queued msgs
18
+ │ caller ── deliverInbox(B) ─────────────────────►│ deliver queued msgs
19
19
  ```
20
20
 
21
- - **Idle sessions** receive messages immediately as a new user turn
22
- - **Busy sessions** have messages queued in an inbox (max 200 messages)
21
+ - **Idle sessions** (ready and not busy) receive messages immediately as a new user turn. The call does not wait for the recipient's reply
22
+ - **A delivered message is an ordinary turn**: it goes through the same send path as `session_send`, so the recipient's spend cap applies and the turn gets its own run-ledger row and a place in the conversation a handoff carries
23
+ - **Busy sessions** have messages queued in an inbox (max 200 messages); so does an idle session whose turn could not start — for example one that has reached its spend cap
24
+ - **Queued messages wait for a caller**: nothing delivers them on its own. Call `sessionDeliverInbox()` once the session is idle
23
25
  - Messages are wrapped in `<cross-session-message>` XML tags
24
26
  - Supports broadcast to all sessions via `to: "*"`; a broadcast skips the sender
25
- - Sender and target must be existing sessions, otherwise the call fails
26
- - Returns `{ delivered, queued }`
27
+ - Sender and target must be live sessions on this SessionManager, otherwise the call fails
28
+ - Returns `{ delivered, queued }`. On a broadcast, `delivered` is true when any recipient got the message at once and `queued` when any recipient's copy was queued; a broadcast that fails for one recipient is logged and does not stop the others
27
29
 
28
30
  ## Usage
29
31
 
@@ -49,7 +51,7 @@ const all = manager.sessionInbox('coder', false);
49
51
 
50
52
  ### Deliver Queued Messages
51
53
 
52
- When a session finishes a task and becomes idle, deliver its queued messages:
54
+ When a session finishes a task and becomes idle, deliver its queued messages. All unread messages go in one turn, each in its own envelope, and are marked read. The call does not wait for the reply; if the turn cannot start (spend cap reached) it throws and the messages stay unread:
53
55
 
54
56
  ```typescript
55
57
  const count = await manager.sessionDeliverInbox('coder');
@@ -64,6 +66,8 @@ console.log(`Delivered ${count} queued messages`);
64
66
  | `session_inbox` | Read inbox messages |
65
67
  | `session_deliver_inbox` | Deliver queued messages to idle session |
66
68
 
69
+ `team_send` (CLI: `clawo session-team-send`) sends through the same inbox, with the summary `team message from <sender>`. The three tools above have no CLI command.
70
+
67
71
  ## Message Format
68
72
 
69
73
  Messages delivered to sessions are wrapped in XML:
@@ -74,10 +78,11 @@ The auth module needs rate limiting. Please add a token bucket...
74
78
  </cross-session-message>
75
79
  ```
76
80
 
77
- Attribute values are XML-escaped, and any `cross-session-message` tag inside the body is escaped, so a sender cannot forge a second envelope.
81
+ The `summary` attribute is present only when a summary was given. Attribute values are XML-escaped, and any `cross-session-message` tag inside the body is escaped, so a sender cannot forge a second envelope.
78
82
 
79
83
  ## Inbox Limits
80
84
 
81
85
  - **Max size**: 200 messages per session
82
86
  - **Eviction**: oldest read messages dropped first, then oldest unread
83
- - **No TTL**: messages, read or unread, stay in memory until evicted or the process exits. They are not persisted to disk.
87
+ - **No TTL**: messages, read or unread, stay in memory until evicted, the session is stopped, or the process exits. They are not persisted to disk.
88
+ - **Stopping clears the inbox**: `stopSession()` drops the session's messages, so a new session started under the same name does not receive mail meant for the old one. A stop that keeps the session resumable (`keepPersisted: true`, used when a session is restarted to continue the same conversation) leaves them in place.
@@ -58,10 +58,12 @@ npm install -g @enderfga/claw-orchestrator
58
58
 
59
59
  When invoked, `clawo-mcp`:
60
60
 
61
- 1. Sets `CLAWO_NO_EMBEDDED_SERVER=1` so the orchestrator does not bind its HTTP control plane (port 18796) — MCP-only deployments do not need it.
61
+ 1. Sets `CLAWO_NO_EMBEDDED_SERVER=1` (unless the variable is already set) so the orchestrator does not bind its HTTP control plane (port 18796) — MCP-only deployments do not need it.
62
62
  2. Captures the plugin's registered tools via an in-memory shim.
63
63
  3. Speaks MCP over stdio. All log lines go to stderr; stdout is reserved for the protocol.
64
64
 
65
+ A `tools/call` returns the tool's result as text content blocks. A tool that throws, or a name that is not advertised, comes back as a result with `isError: true` and the message as text.
66
+
65
67
  ---
66
68
 
67
69
  ## Host configuration
@@ -115,7 +117,8 @@ Hermes prefixes tool names with `mcp_<server>_`. The model sees the prefixed nam
115
117
  }
116
118
  ```
117
119
 
118
- For Claude Code (`~/.claude.json` or per-project `.mcp.json`), use the same shape under `mcpServers`.
120
+ For Claude Code, run `claude mcp add clawo -- clawo-mcp` (add `-e KEY=value` for each variable), or
121
+ write the same shape under `mcpServers` in `~/.claude.json` or a per-project `.mcp.json`.
119
122
 
120
123
  ### Codex CLI
121
124
 
@@ -245,9 +248,9 @@ Hosts deliberately do not forward your full shell environment to MCP subprocesse
245
248
  | `GEMINI_API_KEY` | Multi-model proxy (Gemini models) |
246
249
  | `GATEWAY_URL`, `GATEWAY_KEY` | Routing through an OpenClaw / Anthropic-style gateway |
247
250
  | `CLAWO_MCP_TOOLS` | Comma-separated allowlist of tool names; unlisted tools are not advertised |
248
- | `CLAWO_NO_EMBEDDED_SERVER` | Suppresses port 18796 binding. `clawo-mcp` sets this automatically |
251
+ | `CLAWO_NO_EMBEDDED_SERVER` | `1` suppresses port 18796 binding. `clawo-mcp` sets it when it is unset |
249
252
 
250
- The engines themselves (`claude`, `codex`, `agy`, `grok`, `opencode`) must also be installed and authenticated on the host machine — `clawo-mcp` spawns them as subprocesses, it does not bundle them.
253
+ The engines themselves (`claude`, `codex`, `agy`, `grok`, `opencode`, and any ACP agent you start with `engine: 'acp'`, such as `kimi` or `dsh`) must also be installed and authenticated on the host machine — `clawo-mcp` spawns them as subprocesses, it does not bundle them.
251
254
 
252
255
  ---
253
256
 
@@ -279,11 +282,14 @@ For "let the model commission an ultrareview before merging":
279
282
 
280
283
  `clawo-mcp` advertises [tool annotations](https://modelcontextprotocol.io/specification/server/tools#annotations) so hosts can prefer safer tools when reasoning:
281
284
 
282
- | Annotation | Tools |
283
- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
284
- | `readOnlyHint` + `idempotentHint` | `session_list`, `sessions_overview`, `coding_session_status`, `session_grep`, `session_inbox`, `coding_agents_list`, `team_list`, `council_status`, `council_review`, `ultraplan_status`, `ultrareview_status`, `autoloop_status`, `autoloop_list`, `codex_goal_get` |
285
- | `destructiveHint` | `session_stop`, `council_abort`, `council_accept`, `council_reject`, `autoloop_stop`, `project_purge` |
286
- | `openWorldHint` | All tools that make outbound model API calls (most session / council / ultraplan / autoloop tools) |
285
+ | Annotation | Tools |
286
+ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
287
+ | `readOnlyHint` + `idempotentHint` | `session_list`, `sessions_overview`, `coding_session_status`, `session_grep`, `session_inbox`, `coding_agents_list`, `team_list`, `council_status`, `council_review`, `ultraplan_status`, `ultrareview_status`, `autoloop_status`, `autoloop_list`, `codex_goal_get`, `claude_goal_status`, `claude_agents_list`, `plugin_details`, `codex_models`, `codex_thread_list`, `fanout_status`, `workflow_status`, `workflow_list`, `ultraapp_list`, `ultraapp_get`, `ultraapp_status` |
288
+ | `destructiveHint` | `session_stop`, `council_abort`, `council_accept`, `council_reject`, `autoloop_stop`, `project_purge`, `codex_interrupt`, `codex_rollback`, `fanout_abort`, `workflow_cancel`, `ultraapp_build_cancel`, `ultraapp_promote_version`, `ultraapp_stop_container`, `ultraapp_delete` |
289
+ | `openWorldHint` | `session_start`, `session_send`, `session_handoff`, `team_send`, `session_send_to`, `session_deliver_inbox`, `council_start`, `council_inject`, `ultraplan_start`, `ultrareview_start`, `autoloop_start`, `autoloop_chat`, `codex_resume`, `codex_review`, `codex_goal_set`, `codex_goal_resume`, `session_compact`, `claude_goal_set`, `codex_steer`, `fanout_start`, `workflow_start`, `workflow_resume`, `workflow_approve`, `verify_run`, `ultraapp_new`, `ultraapp_answer`, `ultraapp_add_file`, `ultraapp_spec_edit`, `ultraapp_build_start`, `ultraapp_feedback` |
290
+ | none | `autoloop_reset_agent`, `codex_goal_pause`, `codex_goal_clear`, `session_update_tools`, `session_switch_model`, `claude_goal_clear`, `codex_fork`, `workflow_steer`, `ultraapp_start_container` |
291
+
292
+ Every registered tool has an entry. A hint that is not set takes the MCP default — not read-only, destructive, open-world — so the tools in the last row are advertised at the defaults, and so is each unset hint in the other rows.
287
293
 
288
294
  ---
289
295
 
@@ -292,7 +298,7 @@ For "let the model commission an ultrareview before merging":
292
298
  **The host shows no tools after restart**
293
299
 
294
300
  - Confirm `clawo-mcp` resolves on PATH: `which clawo-mcp`. If you used a non-global install, use the absolute path in `command`.
295
- - Confirm the host logs (Hermes: `~/.hermes/logs/`, Claude Desktop: View → Open Logs Folder). Look for the `[clawo-mcp]` lines.
301
+ - Confirm the host logs (Hermes: `~/.hermes/logs/`, Claude Desktop: View → Open Logs Folder). Look for the `[clawo-mcp]` lines; a server that started prints `mcp server ready — exposing N of M tools over stdio`.
296
302
 
297
303
  **Engine starts but fails with `command not found`**
298
304
 
@@ -304,7 +310,7 @@ For "let the model commission an ultrareview before merging":
304
310
 
305
311
  **Tool list comes back empty**
306
312
 
307
- - `CLAWO_MCP_TOOLS` filter is set to names that don't exist. Drop it and check `tools/list` again, then add back the correct names. Stderr will print a warning.
313
+ - `CLAWO_MCP_TOOLS` filter is set to names that don't exist. Stderr prints a warning that lists every available tool name; correct the filter from that list, or drop it to expose everything.
308
314
 
309
315
  **Port 18796 in use error**
310
316
 
@@ -314,10 +320,12 @@ For "let the model commission an ultrareview before merging":
314
320
 
315
321
  ## MCP vs OpenClaw plugin: when to use which
316
322
 
317
- | Use case | Recommended form |
318
- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
319
- | You already run OpenClaw and want the tools available to every OpenClaw agent | OpenClaw plugin |
320
- | You want to drive coding agents from Hermes Agent, Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf, Goose, or another MCP host | MCP server |
321
- | You want to call the orchestrator from a non-MCP custom runtime (Python, Go, …) | Standalone `clawo serve` HTTP API |
323
+ | Use case | Recommended form |
324
+ | ------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
325
+ | You already run OpenClaw and want the tools available to every OpenClaw agent | OpenClaw plugin |
326
+ | You want to drive coding agents from Hermes Agent, Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf, Goose, or another MCP host | MCP server |
327
+ | You want to call the orchestrator from a non-MCP custom runtime (Python, Go, …) | Standalone `clawo serve` HTTP API |
328
+ | You want an OpenAI-compatible client (a webchat, a gateway) to talk to a coding session | `/v1/chat/completions` on `clawo serve` — see [`openai-compat.md`](./openai-compat.md) |
329
+ | You want an editor (Zed, JetBrains, Neovim, Emacs, VS Code) to use the orchestrator as its coding agent | ACP agent (`clawo acp`) — see [`acp.md`](./acp.md) |
322
330
 
323
- The same package supports all three — they share the SessionManager and tool definitions. Pick whichever entry point matches your host.
331
+ The same package supports all of these — they share the SessionManager, and the MCP server and the OpenClaw plugin share the tool definitions. Pick whichever entry point matches your host.