@enderfga/claw-orchestrator 7.15.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.
@@ -348,9 +348,13 @@ compact, through the app-server's own thread compaction.
348
348
  Subprocess deaths (Claude session lost), failed `git commit` in an iter, and
349
349
  other phase-bound failures surface as `phase_error` messages instead of
350
350
  silently masquerading as a "clarification request". An empty or whitespace-only
351
- Coder reply is also a phase error. Only a non-empty reply without
352
- `iter_complete` is treated as a clarification request. The runner counts
353
- consecutive `phase_error`s and:
351
+ Coder reply is also a phase error. A non-empty Coder reply without a valid
352
+ `iter_complete` returns `directive_ack` (`understood: false`) without review or
353
+ iteration advance. Structured `request_clarification` keeps a short
354
+ `clarification` question. Any other incomplete turn puts fixed status/decision
355
+ wording, a labelled sanitized truncated reply tail, and a write-time persisted
356
+ path (`iter/<n>/coder_reply_<dispatch_id>.txt`) or generic not-persisted result
357
+ into `clarification`. The runner counts consecutive `phase_error`s and:
354
358
 
355
359
  1. Fires `on_phase_error` on each one (defaults to error / both channels).
356
360
  2. After `phaseErrorCircuit` consecutive errors (default **3**) emits a
@@ -2,12 +2,13 @@
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.310** (as of 2026-10-26, plugin v7.15.0)
5
+ ## Currently tracked: **Claude Code CLI 2.1.310** (as of 2026-10-28, plugin v7.16.0)
6
6
 
7
7
  ## Sync history
8
8
 
9
9
  | Plugin Version | Claude CLI Version | Date | Notable integrations |
10
10
  | ------------------- | ------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | v7.16.0 | 2.1.310 | 2026-10-28 | Pins as tracked in v7.15.0; not re-run live this release (installed: CC 2.1.312, Codex 0.165.0, agy 1.4.9). Integrated: `/goal` on Claude Code behind the `goal` node — measured on CC 2.1.312 in stream-json mode (bare `/goal` probe, Stop-hook turns, `interrupt` control request). |
11
12
  | v7.15.0 | 2.1.310 | 2026-10-26 | Engine versions as tracked in v7.14.0 (agy 1.4.7 is installed but not yet run live; the pin stays 1.4.6). Integrated: `codex-app` passes reasoning effort — `turn/start` `effort` and `model_reasoning_effort` in the thread `config` on `thread/start` / `thread/resume` (Codex 0.164.0). |
12
13
  | 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. |
13
14
  | 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. |
@@ -263,34 +263,36 @@ clawo fanout "<task>" [--engines <list>] [--synthesize] [--check "<command>"]...
263
263
 
264
264
  ## `clawo goal`
265
265
 
266
- Run a Codex `/goal` on one `codex-app` thread, then have the runtime check the
267
- result: goal → verify → repair on the same thread. See [workflow.md](./workflow.md#goal).
266
+ Run a `/goal` on one thread — a Codex `codex-app` thread, or a Claude Code
267
+ session with `--engine claude` — then have the runtime check the result: goal →
268
+ verify → repair on the same thread. See [workflow.md](./workflow.md#goal).
268
269
 
269
270
  ```bash
270
271
  clawo goal "<objective>" | --objective-file <file>
271
272
  [--check "<command>"]... [--contract <file>] [--check-timeout <minutes>]
272
- [--launcher <arg>]... [--model <model>] [--effort <level>] [--sandbox <mode>] [--thread <id>]
273
+ [--engine codex|claude] [--launcher <arg>]... [--model <model>] [--effort <level>] [--sandbox <mode>] [--thread <id>]
273
274
  [--token-budget N] [--goal-timeout <minutes>] [--max-repairs N]
274
275
  [--cwd <dir>] [--wait] [--json]
275
276
  ```
276
277
 
277
- | Option | Default | Notes |
278
- | ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------- |
279
- | `--objective-file` | — | Read the objective from a file instead of the argument. Codex accepts at most 4,000 characters |
280
- | `-c, --check` | — | A command check, repeatable, run after the goal. Split on whitespace; quote-needing commands go in `--contract` |
281
- | `--contract` | — | A contract JSON file; `--check` entries are appended to it |
282
- | `--check-timeout` | 10 | Minutes for each `--check` (at least 1). The verifier's node timeout is sized from the checks |
283
- | `--launcher` | — | Run codex under this command, one argv element per flag: `--launcher ./sandbox.sh --launcher task --launcher "0 1"` |
284
- | `-m, --model` | codex's own | Codex model |
285
- | `--effort` | codex's own | Codex reasoning effort |
286
- | `--sandbox` | `workspace-write` | Codex's own sandbox mode. With an outer sandbox as the boundary, `danger-full-access` |
287
- | `--thread` | — | Start on this existing codex thread: its goal is replaced, its history kept |
288
- | `--token-budget` | — | The goal stops as `budgetLimited` past this |
289
- | `--goal-timeout` | none | Wall-clock minutes for one goal pass |
290
- | `--max-repairs` | `1` | Times a red verdict sends the goal back to the same thread |
291
- | `--cwd` | current directory | Project directory |
292
- | `-w, --wait` | off | Follow the run; exit `0` only if it completes |
293
- | `--json` | off | Print `{ runId, state }`, or with `--wait` the final run record |
278
+ | Option | Default | Notes |
279
+ | ------------------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------ |
280
+ | `--objective-file` | — | Read the objective from a file instead of the argument. A goal accepts at most 4,000 characters |
281
+ | `-e, --engine` | `codex` | Who runs the goal: `codex` (a `codex-app` thread) or `claude` (a Claude Code session) |
282
+ | `-c, --check` | — | A command check, repeatable, run after the goal. Split on whitespace; quote-needing commands go in `--contract` |
283
+ | `--contract` | — | A contract JSON file; `--check` entries are appended to it |
284
+ | `--check-timeout` | 10 | Minutes for each `--check` (at least 1). The verifier's node timeout is sized from the checks |
285
+ | `--launcher` | — | Run the engine under this command, one argv element per flag: `--launcher ./sandbox.sh --launcher task --launcher "0 1"` |
286
+ | `-m, --model` | the engine's own | Model |
287
+ | `--effort` | the engine's own | Reasoning effort |
288
+ | `--sandbox` | `workspace-write` | Codex's own sandbox mode (claude has none). With an outer sandbox as the boundary, `danger-full-access` |
289
+ | `--thread` | — | Start on this existing codex thread or claude session: its goal is replaced, its history kept |
290
+ | `--token-budget` | — | The goal stops as `budgetLimited` past this |
291
+ | `--goal-timeout` | none | Wall-clock minutes for one goal pass |
292
+ | `--max-repairs` | `1` | Times a red verdict sends the goal back to the same thread |
293
+ | `--cwd` | current directory | Project directory |
294
+ | `-w, --wait` | off | Follow the run; exit `0` only if it completes |
295
+ | `--json` | off | Print `{ runId, state }`, or with `--wait` the final run record |
294
296
 
295
297
  `clawo workflow show <runId>` prints the goal's status, tokens, time, resume
296
298
  attempts and thread id while it runs; `clawo workflow steer <runId> "<text>"`
@@ -370,23 +370,31 @@ Run one task across N engine/model agents **in parallel** and collect their answ
370
370
 
371
371
  ### `fanout_start`
372
372
 
373
- | Parameter | Type | Required | Description |
374
- | ------------------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
375
- | `task` | string | yes | Shared task sent to every agent, optionally after its `persona`. |
376
- | `projectDir` | string | yes | Working directory all agents run in. |
377
- | `agents` | array | yes | Up to 16 specs: `{ name, engine?, model?, effort?, prompt?, persona?, baseUrl?, permissionMode?, customEngine?, acpAgent? }`. Names must be unique (each forms a session name); `permissionMode` defaults to `bypassPermissions`. |
378
- | `synthesize` | boolean | | Run a final synthesis pass over the successful results (needs ≥2). |
379
- | `synthesisModel` / `synthesisEngine` | string | | Model/engine for the synthesis pass (default engine `claude`). |
380
- | `synthesisAcpAgent` | string | | With `synthesisEngine: 'acp'`: the ACP agent preset the synthesis pass starts. |
381
- | `agentTimeoutMs` | number | | Per-agent timeout (default 600000). |
382
- | `maxTurnsPerAgent` | number | | Max agent loop turns (default 30). |
383
- | `maxBudgetUsd` | number | | Per-agent spend cap. |
373
+ | Parameter | Type | Required | Description |
374
+ | ------------------------------------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
375
+ | `task` | string | yes | Shared task sent to every agent, optionally after its `persona`. |
376
+ | `projectDir` | string | yes | Working directory all agents run in. |
377
+ | `agents` | array | yes | Up to 16 specs: `{ name, engine?, model?, effort?, prompt?, persona?, baseUrl?, permissionMode?, sandboxMode?, customEngine?, acpAgent? }`. Names must be unique (each forms a session name); `permissionMode` defaults to `bypassPermissions`. |
378
+ | `synthesize` | boolean | | Run a final synthesis pass over the successful results (needs ≥2). |
379
+ | `synthesisModel` / `synthesisEngine` | string | | Model/engine for the synthesis pass (default engine `claude`). |
380
+ | `synthesisAcpAgent` | string | | With `synthesisEngine: 'acp'`: the ACP agent preset the synthesis pass starts. |
381
+ | `agentTimeoutMs` | number | | Per-agent timeout (default 600000). |
382
+ | `maxTurnsPerAgent` | number | | Max agent loop turns (default 30). |
383
+ | `maxBudgetUsd` | number | | Per-agent spend cap. |
384
384
 
385
385
  Runs in the background; returns `{ ok, id, status, ... }`. Poll with `fanout_status`.
386
386
  Each agent's optional `effort` accepts `low`, `medium`, `high`, `xhigh`, `max`,
387
387
  `ultra`, or `auto`. Omit it to keep the session default. The engine applies or
388
388
  clamps the value as documented for `session_start`.
389
389
 
390
+ Per-agent `permissionMode` uses the same enum and each engine's own permission
391
+ handling as `session_start`. Workers that must not write should set
392
+ `sandboxMode` to `read-only`. Per-agent `sandboxMode` (`read-only` \|
393
+ `workspace-write` \| `danger-full-access`) uses the same values and per-engine
394
+ behavior as `session_start` (omit to keep the session default). These worker
395
+ fields do not constrain optional synthesis, and `fanout_start` does not expose a
396
+ synthesis permission override.
397
+
390
398
  Per-agent `persona` provides role instructions without replacing the shared
391
399
  task. Fan-out sends `<persona>\n\n## Shared task\n\n<task>`. A non-empty
392
400
  per-agent `prompt` keeps its original full-override semantics: it is sent by
@@ -157,12 +157,12 @@ is unrecoverable and reads back as "not found".
157
157
  | `agent` | One session, one turn. A new session per attempt unless `sessionName` pins one |
158
158
  | `fanout` | N agents in parallel on a shared prompt, optional synthesis pass. Succeeds when at least one agent does |
159
159
  | `council` | The council engine; its votes are recorded as advisory. Fails only when the council itself errors |
160
- | `verifier` | Runs an acceptance contract, writes evidence — see [`verification.md`](./verification.md). `"contract": "run"` with no run-level contract passes through and verifies nothing; an inline contract with no recognised check is refused at start |
160
+ | `verifier` | Runs an acceptance contract, writes evidence — see [`verification.md`](./verification.md). `"contract": "run"` with no run-level contract passes through and verifies nothing; an inline contract with no recognised check is refused at start |
161
161
  | `human_gate` | Parks the run until a person answers; a rejection fails the run |
162
162
  | `router` | Picks the next node from declarative conditions; a backwards route is the loop |
163
163
  | `subflow` | Runs another workflow as a child run and adopts its verdict, with the tree digest the verdict was taken against; a child that ends `unverified` hands up no verdict |
164
164
  | `autoloop` | A long-lived Planner / Coder / Reviewer loop; its executor is injected. On the node's first visit (`visits === 1`) the shared fresh-start boundary applies (dirty-worktree refusal + run-local `tasks/<config.runId>/.gitignore`); resume and later visits skip it. |
165
- | `goal` | A Codex `/goal` on one `codex-app` thread, run until the goal finishes — see [below](#goal) |
165
+ | `goal` | A `/goal` on one Codex `codex-app` thread or Claude Code session, run until the goal finishes — see [below](#goal) |
166
166
  | `ultraapp_synth`, `ultraapp_deploy` | UltraApp's synth and deploy stages; their executors are injected too |
167
167
 
168
168
  ### Spec and node fields
@@ -194,12 +194,12 @@ The kind-specific fields:
194
194
  | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
195
195
  | `agent` | `prompt` (required); `engine`, `model`, `effort`, `acpAgent` (a bundled ACP preset id, for `engine: "acp"`); `cwd` (default: the run's); `sessionName`, to reuse one named session across nodes; `permissionMode` (default `bypassPermissions`); `appendSystemPrompt`, standing instructions for the session |
196
196
  | `fanout` | `prompt` (required, the shared task) and `agents` (required); `synthesize`, `synthesisEngine` (default `claude`), `synthesisModel`, `synthesisAcpAgent`, `synthesisPermissionMode` (default `bypassPermissions`); `maxTurnsPerAgent` and `maxBudgetUsd`, per agent; `cwd`; `agentTimeoutMs` |
197
- | `council` | `task` (required) and `agents` (required); `projectDir` (default: the run's cwd); `maxRounds` (default 15, as for `council_start`); `maxTurnsPerAgent` and `maxBudgetUsd`, per agent; `defaultPermissionMode`; `agentTimeoutMs` |
197
+ | `council` | `task` (required) and `agents` (required); `projectDir` (default: the run's cwd); `maxRounds` (default 15, as for `council_start`); `maxTurnsPerAgent` and `maxBudgetUsd`, per agent; `defaultPermissionMode`; `agentTimeoutMs` |
198
198
  | `verifier` | `contract` (required): an inline contract, or `"run"` for the run-level one; `cwd` (default: the run's) |
199
199
  | `human_gate` | `prompt` (required) |
200
200
  | `router` | `routes` (required): `[{ "when": <condition>, "to": <node id> }]`, first match wins; `default`, taken when nothing matches (omitted: fall through to the next node) |
201
201
  | `subflow` | `workflow` (required): an inline `WorkflowSpec`, or the id of an existing run, whose stored spec runs again as a new child run. Template names do not resolve here |
202
- | `goal` | `objective` (required); `cwd`, `model`, `effort`, `sandboxMode`, `launcher`, `threadId`, `tokenBudget`, `capacityRetry`, `stallMs` — see [Goal](#goal) |
202
+ | `goal` | `objective` (required); `engine`, `cwd`, `model`, `effort`, `sandboxMode`, `launcher`, `threadId`, `tokenBudget`, `capacityRetry`, `stallMs` — see [Goal](#goal) |
203
203
  | `autoloop` | `workspace` and `config` (the `autoloop_start` options). Started by `autoloop_start` |
204
204
  | `ultraapp_synth`, `ultraapp_deploy` | `appRunId`, `runDir`, `slug`; the deploy stage adds `version` and `codebasePath`. Started by UltraApp builds |
205
205
 
@@ -333,7 +333,7 @@ specs and post them.
333
333
  | `solve` | `triage` (fan-out) → `approve` (human gate, only with `humanGate`) → `implement` (agent) → `review` (fan-out, only with `reviewers`) → `verify` → `repair-gate` (router) | `agents` (the triage scouts; default one agent on the default engine), `implementer` (`engine`, `model`), `reviewers`, `humanGate`, `maxRepairs` (default 3), `contract` |
334
334
  | `council` | `council`, then `__verify` when a contract is declared | `agents`, `maxRounds` (default 15), `contract` |
335
335
  | `fanout` | `fanout`, then `__verify` when a contract is declared | `agents`, `contract` |
336
- | `goal` | `goal` → `verify` → `repair-gate` (router); `task` is the objective. See [below](#goal) | `model`, `tokenBudget`, `launcher`, `maxRepairs` (default 1), `contract` |
336
+ | `goal` | `goal` → `verify` → `repair-gate` (router); `task` is the objective. See [below](#goal) | `engine` (`codex` default, or `claude`), `model`, `tokenBudget`, `launcher`, `maxRepairs` (default 1), `contract` |
337
337
 
338
338
  `solve` is the shape above: the triage and review fan-outs add a synthesis pass
339
339
  when they have two or more agents, `implement` and `review` continue on failure so
@@ -349,16 +349,19 @@ somewhere to deploy to), which only UltraApp starts.
349
349
 
350
350
  ## Goal
351
351
 
352
- A `goal` node runs one Codex `/goal` on one `codex-app` thread. Codex's
353
- app-server runs the goal itself: `thread/goal/set` starts its turn loop, which
354
- keeps going until the goal is `complete`, out of budget, `blocked`, or stopped
355
- by a usage limit. The node adds what an unattended run needs around that loop.
352
+ A `goal` node runs one `/goal` on one thread: a Codex `codex-app` thread by
353
+ default, or a Claude Code session with `"engine": "claude"` (see
354
+ [On Claude Code](#on-claude-code)). Codex's app-server runs the goal itself:
355
+ `thread/goal/set` starts its turn loop, which keeps going until the goal is
356
+ `complete`, out of budget, `blocked`, or stopped by a usage limit. The node adds
357
+ what an unattended run needs around that loop.
356
358
 
357
359
  ```jsonc
358
360
  {
359
361
  "id": "goal",
360
362
  "kind": "goal",
361
363
  "objective": "Reach the goal described in GOAL.md …",
364
+ "engine": "codex", // default; or "claude"
362
365
  "cwd": "/work/task/ws",
363
366
  "model": "gpt-6.1-sol", // optional; codex's own default otherwise
364
367
  "effort": "high", // optional reasoning effort
@@ -417,6 +420,47 @@ by a usage limit. The node adds what an unattended run needs around that loop.
417
420
  reason. Cancel interrupts the running turn and pauses the goal, and so does a
418
421
  `timeoutMs` that runs out. Like `autoloop`, the node has no default timeout.
419
422
 
423
+ ### On Claude Code
424
+
425
+ With `"engine": "claude"` the same node drives Claude Code's `/goal` (CLI
426
+ 2.1.139 or later) through `ClaudeGoalSession`. Claude Code has no goal RPCs or
427
+ goal notifications, so the adapter reads the goal from what the CLI does in
428
+ stream-json mode:
429
+
430
+ - `/goal <objective>` sets the goal and starts working. A Stop hook — a separate
431
+ model judging the condition against the session — runs after every turn and
432
+ feeds the turn back while the condition does not hold, all inside one send;
433
+ one `result` arrives when the goal is met, and the goal clears itself.
434
+ - A bare `/goal` answers at once, without a model turn — `Goal active: …` or
435
+ `No goal set.` A failed turn clears the goal too, so a gone goal is not proof:
436
+ the goal is `complete` only when a turn that started with it set ended without
437
+ an error and it is gone after. A goal still set with nothing driving it, a
438
+ failed turn, and a reopened session whose goal is gone are `paused`, which the
439
+ node resumes within its bound. Resuming sends a short "continue" message when
440
+ the goal is still set and sets it again (`/goal <objective>`) when it is not,
441
+ so a goal that was already met costs one turn to confirm.
442
+ - A failed turn is read from its text: usage limits become `usageLimited`,
443
+ overloaded and 5xx errors the matching transient codes, so the node backs off
444
+ and resumes as it does for Codex. A failed login is `blocked` at once.
445
+ - When the Stop hook blocks the agent's stop nine times running, the CLI ends
446
+ the turn anyway and says so; the goal is then `blocked` (the agent keeps
447
+ asking to stop, and continuing only repeats that). The template's verifier
448
+ still judges the tree. Write the objective as a condition the agent can show
449
+ it met from inside the session; one that depends on something after the
450
+ agent stops can never be met.
451
+ - The session id is the thread id. A new session is started with
452
+ `--session-id` so it is known before the goal is set, and the session is kept
453
+ out of the registry with `skipPersistence` (not `noSessionPersistence`, which
454
+ would stop the CLI writing the transcript `--resume` needs). A reopened
455
+ process resumes it with `--resume`; the goal is still set there, so the node
456
+ continues it at once.
457
+ - Steers are written into the running turn, which the CLI folds in. Cancel and
458
+ pause send stream-json's `interrupt` control request; the goal stays set.
459
+ - `tokensUsed` counts the session's input, output and cache-read tokens, and is
460
+ carried across reopened processes. `tokenBudget` counts from when the current
461
+ objective was set; past it the turn is interrupted and the goal ends
462
+ `budgetLimited`. `sandboxMode` does not apply; put the boundary in `launcher`.
463
+
420
464
  The `goal` template wraps this in `goal → verify → repair-gate`. The goal node
421
465
  continues on failure, so a goal that ran out of budget is still judged. The
422
466
  verifier's node timeout is sized from the contract — the sum of every check's