@enderfga/claw-orchestrator 7.14.0 → 7.15.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 (137) hide show
  1. package/README.md +160 -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 +71 -40
  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 +23 -1
  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/council.d.ts +8 -0
  22. package/dist/src/council.js +45 -12
  23. package/dist/src/council.js.map +1 -1
  24. package/dist/src/dashboard/index.html +28 -14
  25. package/dist/src/embedded-server.js +27 -8
  26. package/dist/src/embedded-server.js.map +1 -1
  27. package/dist/src/engine-spawn.js +3 -1
  28. package/dist/src/engine-spawn.js.map +1 -1
  29. package/dist/src/fanout.d.ts +13 -3
  30. package/dist/src/fanout.js +10 -0
  31. package/dist/src/fanout.js.map +1 -1
  32. package/dist/src/inbox-manager.d.ts +9 -0
  33. package/dist/src/inbox-manager.js +8 -2
  34. package/dist/src/inbox-manager.js.map +1 -1
  35. package/dist/src/index.d.ts +2 -0
  36. package/dist/src/index.js +117 -51
  37. package/dist/src/index.js.map +1 -1
  38. package/dist/src/kernel/conditions.d.ts +1 -1
  39. package/dist/src/kernel/conditions.js +1 -1
  40. package/dist/src/kernel/engine.d.ts +28 -8
  41. package/dist/src/kernel/engine.js +93 -19
  42. package/dist/src/kernel/engine.js.map +1 -1
  43. package/dist/src/kernel/nodes/agent.js +2 -0
  44. package/dist/src/kernel/nodes/agent.js.map +1 -1
  45. package/dist/src/kernel/nodes/council.js +9 -4
  46. package/dist/src/kernel/nodes/council.js.map +1 -1
  47. package/dist/src/kernel/nodes/fanout.js +5 -0
  48. package/dist/src/kernel/nodes/fanout.js.map +1 -1
  49. package/dist/src/kernel/nodes/goal.d.ts +8 -1
  50. package/dist/src/kernel/nodes/goal.js +40 -19
  51. package/dist/src/kernel/nodes/goal.js.map +1 -1
  52. package/dist/src/kernel/nodes/subflow.js +9 -1
  53. package/dist/src/kernel/nodes/subflow.js.map +1 -1
  54. package/dist/src/kernel/nodes/ultraapp.d.ts +1 -0
  55. package/dist/src/kernel/nodes/ultraapp.js +1 -0
  56. package/dist/src/kernel/nodes/ultraapp.js.map +1 -1
  57. package/dist/src/kernel/nodes/verifier.js +5 -1
  58. package/dist/src/kernel/nodes/verifier.js.map +1 -1
  59. package/dist/src/kernel/projections.d.ts +1 -0
  60. package/dist/src/kernel/projections.js +7 -1
  61. package/dist/src/kernel/projections.js.map +1 -1
  62. package/dist/src/kernel/templates/index.d.ts +6 -3
  63. package/dist/src/kernel/templates/index.js +8 -3
  64. package/dist/src/kernel/templates/index.js.map +1 -1
  65. package/dist/src/kernel/types.d.ts +30 -10
  66. package/dist/src/kernel/types.js.map +1 -1
  67. package/dist/src/logger.d.ts +6 -0
  68. package/dist/src/logger.js +14 -0
  69. package/dist/src/logger.js.map +1 -1
  70. package/dist/src/mcp-annotations.d.ts +13 -0
  71. package/dist/src/mcp-annotations.js +100 -0
  72. package/dist/src/mcp-annotations.js.map +1 -0
  73. package/dist/src/models.d.ts +7 -0
  74. package/dist/src/models.js +9 -0
  75. package/dist/src/models.js.map +1 -1
  76. package/dist/src/openai-compat.d.ts +11 -5
  77. package/dist/src/openai-compat.js +55 -54
  78. package/dist/src/openai-compat.js.map +1 -1
  79. package/dist/src/persistent-acp-session.d.ts +7 -0
  80. package/dist/src/persistent-acp-session.js +26 -2
  81. package/dist/src/persistent-acp-session.js.map +1 -1
  82. package/dist/src/persistent-codex-app-session.d.ts +2 -0
  83. package/dist/src/persistent-codex-app-session.js +18 -9
  84. package/dist/src/persistent-codex-app-session.js.map +1 -1
  85. package/dist/src/persistent-codex-session.d.ts +14 -3
  86. package/dist/src/persistent-codex-session.js +22 -19
  87. package/dist/src/persistent-codex-session.js.map +1 -1
  88. package/dist/src/persistent-custom-session.d.ts +9 -0
  89. package/dist/src/persistent-custom-session.js +41 -21
  90. package/dist/src/persistent-custom-session.js.map +1 -1
  91. package/dist/src/persistent-grok-session.js +1 -1
  92. package/dist/src/persistent-grok-session.js.map +1 -1
  93. package/dist/src/run-ledger.d.ts +3 -3
  94. package/dist/src/session-manager.d.ts +34 -1
  95. package/dist/src/session-manager.js +160 -30
  96. package/dist/src/session-manager.js.map +1 -1
  97. package/dist/src/types.d.ts +34 -11
  98. package/dist/src/types.js.map +1 -1
  99. package/dist/src/ultraapp/build.d.ts +5 -11
  100. package/dist/src/ultraapp/build.js +5 -11
  101. package/dist/src/ultraapp/build.js.map +1 -1
  102. package/dist/src/ultraapp/council-adapter.d.ts +5 -2
  103. package/dist/src/ultraapp/council-adapter.js +6 -6
  104. package/dist/src/ultraapp/council-adapter.js.map +1 -1
  105. package/dist/src/ultraapp/files.d.ts +7 -0
  106. package/dist/src/ultraapp/files.js +7 -1
  107. package/dist/src/ultraapp/files.js.map +1 -1
  108. package/dist/src/ultraapp/manager.d.ts +23 -3
  109. package/dist/src/ultraapp/manager.js +170 -72
  110. package/dist/src/ultraapp/manager.js.map +1 -1
  111. package/dist/src/ultraapp/narrator.js +1 -1
  112. package/dist/src/ultraapp/narrator.js.map +1 -1
  113. package/dist/src/ultraapp/versions.d.ts +27 -5
  114. package/dist/src/ultraapp/versions.js +58 -13
  115. package/dist/src/ultraapp/versions.js.map +1 -1
  116. package/openclaw.plugin.json +4 -13
  117. package/package.json +13 -6
  118. package/skills/SKILL.md +52 -24
  119. package/skills/references/acp.md +140 -61
  120. package/skills/references/autoloop.md +141 -35
  121. package/skills/references/claude-cli-tracking.md +8 -6
  122. package/skills/references/cli.md +122 -93
  123. package/skills/references/council.md +44 -22
  124. package/skills/references/dashboard.md +37 -21
  125. package/skills/references/getting-started.md +49 -15
  126. package/skills/references/inbox.md +13 -8
  127. package/skills/references/mcp.md +25 -17
  128. package/skills/references/multi-engine.md +161 -145
  129. package/skills/references/observability.md +90 -58
  130. package/skills/references/openai-compat.md +172 -82
  131. package/skills/references/sessions.md +101 -65
  132. package/skills/references/tools.md +209 -158
  133. package/skills/references/ultra.md +7 -7
  134. package/skills/references/ultraapp.md +101 -56
  135. package/skills/references/verification.md +112 -56
  136. package/skills/references/workflow.md +227 -93
  137. package/assets/banner.jpg +0 -0
@@ -97,7 +97,7 @@ export class InboxManager {
97
97
  if (unread.length === 0)
98
98
  return 0;
99
99
  const formatted = unread.map((m) => this.wrapCrossSessionMessage(m)).join('\n\n');
100
- await managed.session.send(formatted, { waitForComplete: false });
100
+ await this._send(name, managed.session, formatted, lookup);
101
101
  for (const m of unread)
102
102
  m.read = true;
103
103
  return unread.length;
@@ -107,6 +107,12 @@ export class InboxManager {
107
107
  this.inboxes.delete(name);
108
108
  }
109
109
  // ── Private ─────────────────────────────────────────────────────────────
110
+ async _send(name, session, text, lookup) {
111
+ if (lookup.deliver)
112
+ await lookup.deliver(name, text);
113
+ else
114
+ await session.send(text, { waitForComplete: false });
115
+ }
110
116
  /**
111
117
  * Three outcomes, because two of them are not each other's negation: a name
112
118
  * that `allNames()` lists but `getSession()` no longer knows is neither
@@ -125,7 +131,7 @@ export class InboxManager {
125
131
  // If session is idle, deliver directly
126
132
  if (!managed.session.isBusy && managed.session.isReady) {
127
133
  try {
128
- await managed.session.send(this.wrapCrossSessionMessage(msg), { waitForComplete: false });
134
+ await this._send(sessionName, managed.session, this.wrapCrossSessionMessage(msg), lookup);
129
135
  msg.read = true;
130
136
  return 'delivered';
131
137
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inbox-manager.js","sourceRoot":"","sources":["../../src/inbox-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inbox-manager.js","sourceRoot":"","sources":["../../src/inbox-manager.ts"],"names":[],"mappings":"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"}
@@ -12,12 +12,14 @@ export { SessionManager } from './session-manager.js';
12
12
  export { PersistentClaudeSession } from './persistent-session.js';
13
13
  export { BaseOneShotSession, type OneShotEngineConfig } from './base-oneshot-session.js';
14
14
  export { PersistentCodexSession } from './persistent-codex-session.js';
15
+ export { PersistentCodexAppServerSession } from './persistent-codex-app-session.js';
15
16
  export { PersistentGeminiSession } from './persistent-gemini-session.js';
16
17
  export { PersistentAgySession } from './persistent-agy-session.js';
17
18
  export { PersistentCursorSession } from './persistent-cursor-session.js';
18
19
  export { PersistentGrokSession } from './persistent-grok-session.js';
19
20
  export { PersistentOpencodeSession } from './persistent-opencode-session.js';
20
21
  export { PersistentCustomSession } from './persistent-custom-session.js';
22
+ export { PersistentAcpSession } from './persistent-acp-session.js';
21
23
  export { Council, getDefaultCouncilConfig } from './council.js';
22
24
  export { AutoloopRunner } from './autoloop/runner.js';
23
25
  export { ClaudeAgentDispatcher } from './autoloop/dispatcher.js';
package/dist/src/index.js CHANGED
@@ -22,12 +22,14 @@ export { SessionManager } from './session-manager.js';
22
22
  export { PersistentClaudeSession } from './persistent-session.js';
23
23
  export { BaseOneShotSession } from './base-oneshot-session.js';
24
24
  export { PersistentCodexSession } from './persistent-codex-session.js';
25
+ export { PersistentCodexAppServerSession } from './persistent-codex-app-session.js';
25
26
  export { PersistentGeminiSession } from './persistent-gemini-session.js';
26
27
  export { PersistentAgySession } from './persistent-agy-session.js';
27
28
  export { PersistentCursorSession } from './persistent-cursor-session.js';
28
29
  export { PersistentGrokSession } from './persistent-grok-session.js';
29
30
  export { PersistentOpencodeSession } from './persistent-opencode-session.js';
30
31
  export { PersistentCustomSession } from './persistent-custom-session.js';
32
+ export { PersistentAcpSession } from './persistent-acp-session.js';
31
33
  export { Council, getDefaultCouncilConfig } from './council.js';
32
34
  export { AutoloopRunner } from './autoloop/runner.js';
33
35
  export { ClaudeAgentDispatcher } from './autoloop/dispatcher.js';
@@ -71,6 +73,16 @@ const ACP_AGENT_SCHEMA = {
71
73
  },
72
74
  ],
73
75
  };
76
+ /**
77
+ * `acpAgent` on the surfaces that write their agents into a stored run spec
78
+ * (fan-out, council, workflow templates): a preset id only. An inline config can
79
+ * carry an environment, and the spec is written to disk.
80
+ */
81
+ const AUTOLOOP_ENGINES = ENGINE_TYPES.filter((e) => e !== 'acp');
82
+ const ACP_AGENT_ID_SCHEMA = {
83
+ type: 'string',
84
+ description: 'With engine "acp": the id of a bundled ACP agent preset (`clawo engines`), such as kimi-code or dsh.',
85
+ };
74
86
  const CUSTOM_ENGINE_SCHEMA = {
75
87
  type: 'object',
76
88
  description: 'Custom engine config (required when the corresponding engine is "custom").',
@@ -118,13 +130,23 @@ const CUSTOM_ENGINE_SCHEMA = {
118
130
  },
119
131
  required: ['name', 'bin', 'args'],
120
132
  };
133
+ /**
134
+ * `customEngine` on the surfaces that also take a preset id: session_start,
135
+ * session_handoff and council agents all reach `_createSession`, which expands a
136
+ * string through resolveCustomEngine. Autoloop roles validate an inline config
137
+ * and take CUSTOM_ENGINE_SCHEMA itself.
138
+ */
139
+ const CUSTOM_ENGINE_OR_PRESET_SCHEMA = {
140
+ description: 'Custom engine (required when engine is "custom"): the id of a bundled preset (`clawo engines`), or, from a local caller only, an inline config.',
141
+ oneOf: [{ type: 'string', description: 'Preset id, e.g. "zcode"' }, CUSTOM_ENGINE_SCHEMA],
142
+ };
121
143
  /**
122
144
  * OpenClaw plugin object — standard format
123
145
  */
124
146
  const plugin = {
125
147
  id: 'claw-orchestrator',
126
148
  name: 'Claw Orchestrator',
127
- description: 'Run Claude Code, Codex, Antigravity, Grok Build, OpenCode and custom coding CLIs as one unified runtime — persistent sessions, multi-agent council, worktree isolation, multi-model proxy',
149
+ description: 'Run Claude Code, Codex, Antigravity, Grok Build, OpenCode, any ACP agent and custom coding CLIs as one unified runtime — persistent sessions, multi-agent council, worktree isolation, multi-model proxy',
128
150
  register(api) {
129
151
  const rawConfig = (api.pluginConfig || {});
130
152
  const registerTool = (definition) => {
@@ -216,7 +238,7 @@ const plugin = {
216
238
  engine: {
217
239
  type: 'string',
218
240
  enum: ENGINE_TYPES,
219
- description: 'Engine to use (default: claude). codex = `codex exec` per send (no /goal). codex-app = long-running `codex app-server` with /goal support. agy = Google Antigravity CLI (Gemini CLI successor; plain-text output, tokens estimated, conversation resume handled automatically). opencode = sst/opencode CLI (provider-agnostic; pass model as `provider/model`). acp = any Agent Client Protocol agent, chosen with acpAgent. Use "custom" with customEngine config for any CLI.',
241
+ description: 'Engine to use (default: claude). codex = `codex exec` per send (no /goal). codex-app = long-running `codex app-server` with /goal support. agy = Google Antigravity CLI (stream-json output with reported token usage; the conversation is resumed by its id on each send). grok = xAI Grok Build CLI (reports its own per-turn cost). opencode = sst/opencode CLI (provider-agnostic; pass model as `provider/model`). acp = any Agent Client Protocol agent, chosen with acpAgent. Use "custom" with customEngine config for any CLI. gemini and cursor are legacy, kept for existing callers: use agy and grok instead.',
220
242
  },
221
243
  model: { type: 'string', description: 'Model to use (opus, sonnet, haiku, gpt-5.5, agy-pro, etc.)' },
222
244
  permissionMode: {
@@ -231,6 +253,16 @@ const plugin = {
231
253
  description: 'Tools to auto-approve',
232
254
  },
233
255
  disallowedTools: { type: 'array', maxItems: 200, items: { type: 'string' }, description: 'Tools to deny' },
256
+ tools: {
257
+ type: ['string', 'array'],
258
+ items: { type: 'string' },
259
+ description: 'Claude engine only. The built-in tool set (`--tools`): names such as ["Bash", "Edit", "Read"], "" for none, or "default".',
260
+ },
261
+ addDir: {
262
+ type: 'array',
263
+ items: { type: 'string' },
264
+ description: 'Directories the session may use besides cwd (`--add-dir`). Claude and Codex; a resumed Codex thread keeps the directories its first turn opened.',
265
+ },
234
266
  maxTurns: { type: 'number', description: 'Max agent loop turns' },
235
267
  maxBudgetUsd: { type: 'number', description: 'Max API spend (USD)' },
236
268
  autoCompactPercent: {
@@ -260,14 +292,24 @@ const plugin = {
260
292
  description: 'MCP server config file(s)',
261
293
  },
262
294
  settings: { type: 'string', description: 'Settings.json path or inline JSON' },
295
+ pluginUrl: {
296
+ type: ['string', 'array'],
297
+ items: { type: 'string' },
298
+ description: 'Claude engine only. Plugin .zip URL(s) fetched for this session only (`--plugin-url`).',
299
+ },
263
300
  ultracode: {
264
301
  type: 'boolean',
265
- description: 'Claude engine only. Enable "ultracode" / dynamic workflows: Claude plans a JS orchestration script per substantive task and fans out to subagents. Injected as the ultracode:true settings key (not a --effort value).',
302
+ description: 'Claude engine only. Enable "ultracode" / dynamic workflows: Claude plans a JS orchestration script per substantive task and fans out to subagents. Injected as the ultracode:true settings key (not a --effort value). A workflow runs in the background: session_send returns the launch reply, and the completion arrives later in a turn that no send returns.',
266
303
  },
267
304
  sandboxMode: {
268
305
  type: 'string',
269
306
  enum: ['read-only', 'workspace-write', 'danger-full-access'],
270
- description: 'Sandbox policy. Codex supports all values; other built-in engines map read-only to their native plan/read-only mode.',
307
+ description: 'Sandbox policy. Codex supports all values (default workspace-write). read-only is enforced on claude, agy, grok and opencode through their own plan/read-only modes; a custom engine must map it via permissionModes or the session refuses to start. The acp engine refuses read-only, because the agent runs its own tools; its permission answers follow permissionMode.',
308
+ },
309
+ launcher: {
310
+ type: 'array',
311
+ items: { type: 'string' },
312
+ description: 'Argv prefix every engine process of this session runs under, e.g. a sandbox wrapper: ["/opt/sandbox.sh", "task"]. Any engine. It runs with your authority, like a contract command check.',
271
313
  },
272
314
  codexProfile: {
273
315
  type: 'string',
@@ -356,11 +398,11 @@ const plugin = {
356
398
  enum: ['default', 'flex', 'priority'],
357
399
  description: 'AWS Bedrock service tier (sets ANTHROPIC_BEDROCK_SERVICE_TIER). Only effective when routing through Bedrock.',
358
400
  },
359
- customEngine: CUSTOM_ENGINE_SCHEMA,
401
+ customEngine: CUSTOM_ENGINE_OR_PRESET_SCHEMA,
360
402
  acpAgent: ACP_AGENT_SCHEMA,
361
403
  resumeSessionId: {
362
404
  type: 'string',
363
- description: 'Resume an existing Claude Code session by its ID (e.g. from ~/.claude/sessions/). Replays conversation history via session/load instead of starting fresh.',
405
+ description: "Resume an earlier conversation by the engine's own id instead of starting fresh: a Claude Code session id (`--resume`), a Codex or codex-app thread id, an Antigravity conversation id, a Grok or OpenCode session id, an ACP agent's session id, or a custom engine's id when its config maps a resume flag.",
364
406
  },
365
407
  },
366
408
  },
@@ -384,9 +426,12 @@ const plugin = {
384
426
  effort: {
385
427
  type: 'string',
386
428
  enum: ['low', 'medium', 'high', 'xhigh', 'max', 'ultra'],
387
- description: 'Effort for this message',
429
+ description: 'Effort for this message. agy, grok and opencode pass it to the engine for this turn; on claude, high and above prefix the message with `ultrathink` (a persistent custom engine does the same for high and max). Other engines ignore it.',
430
+ },
431
+ plan: {
432
+ type: 'boolean',
433
+ description: 'Ask for a plan only: claude and persistent custom engines prefix the message with a plan-only instruction. The permission mode is unchanged (start with sandboxMode read-only to enforce it); other engines ignore this flag.',
388
434
  },
389
- plan: { type: 'boolean', description: 'Enable plan mode' },
390
435
  timeout: { type: 'number', description: 'Timeout in ms (default 300000)' },
391
436
  stream: {
392
437
  type: 'boolean',
@@ -440,7 +485,8 @@ const plugin = {
440
485
  type: 'number',
441
486
  description: 'Upper bound on the carried history, in characters (default 240000, minimum 4000). When the conversation is longer, the opening request and the newest turns are kept and the turns between them are left out.',
442
487
  },
443
- customEngine: CUSTOM_ENGINE_SCHEMA,
488
+ customEngine: CUSTOM_ENGINE_OR_PRESET_SCHEMA,
489
+ acpAgent: ACP_AGENT_SCHEMA,
444
490
  },
445
491
  required: ['name', 'engine'],
446
492
  },
@@ -452,6 +498,7 @@ const plugin = {
452
498
  message: args.message,
453
499
  maxChars: args.maxChars,
454
500
  customEngine: args.customEngine,
501
+ acpAgent: args.acpAgent,
455
502
  });
456
503
  return { ok: true, ...result };
457
504
  },
@@ -459,7 +506,7 @@ const plugin = {
459
506
  // ─── Tool: session_stop ───────────────────────────────────────────────
460
507
  registerTool({
461
508
  name: 'session_stop',
462
- description: 'Stop a persistent coding session',
509
+ description: 'Stop a persistent coding session and remove it from the resume registry, so a later session_start under the same name begins a new conversation',
463
510
  parameters: {
464
511
  type: 'object',
465
512
  properties: { name: { type: 'string', description: 'Session name' } },
@@ -473,12 +520,11 @@ const plugin = {
473
520
  // ─── Tool: session_list ───────────────────────────────────────────────
474
521
  registerTool({
475
522
  name: 'session_list',
476
- description: 'List all active coding sessions',
523
+ description: 'List the active coding sessions, and the persisted ones that a session_start under the same name resumes',
477
524
  parameters: { type: 'object', properties: {} },
478
525
  execute: async (_id) => {
479
- if (!manager)
480
- return { ok: true, sessions: [], persisted: [] };
481
- return { ok: true, sessions: manager.listSessions(), persisted: manager.listPersistedSessions() };
526
+ const m = getManager();
527
+ return { ok: true, sessions: m.listSessions(), persisted: m.listPersistedSessions() };
482
528
  },
483
529
  });
484
530
  // ─── Tool: sessions_overview ──────────────────────────────────────────
@@ -502,7 +548,7 @@ const plugin = {
502
548
  // ─── Tool: coding_session_status ──────────────────────────────────────
503
549
  registerTool({
504
550
  name: 'coding_session_status',
505
- description: 'Get detailed status of a coding session (context %, tokens, cost, uptime)',
551
+ description: 'Get detailed status of a coding session: context %, tokens, cost and spend cap, turns, tool calls, retries, start time and last activity',
506
552
  parameters: {
507
553
  type: 'object',
508
554
  properties: { name: { type: 'string', description: 'Session name' } },
@@ -516,7 +562,7 @@ const plugin = {
516
562
  // ─── Tool: session_grep ───────────────────────────────────────────────
517
563
  registerTool({
518
564
  name: 'session_grep',
519
- description: 'Search session history for events matching a regex pattern',
565
+ description: "Search the session's in-memory event history (its 100 most recent events) for a regex pattern, case-insensitive",
520
566
  parameters: {
521
567
  type: 'object',
522
568
  properties: {
@@ -565,7 +611,7 @@ const plugin = {
565
611
  // ─── Tool: team_list ──────────────────────────────────────────────────
566
612
  registerTool({
567
613
  name: 'team_list',
568
- description: 'List teammates in an agent team session (requires enableAgentTeams)',
614
+ description: "List the other active sessions as this session's teammates, with engine, idle/busy/paused state and turn count. Works on every engine; enableAgentTeams is not required.",
569
615
  parameters: {
570
616
  type: 'object',
571
617
  properties: { name: { type: 'string', description: 'Session name' } },
@@ -579,7 +625,7 @@ const plugin = {
579
625
  // ─── Tool: team_send ──────────────────────────────────────────────────
580
626
  registerTool({
581
627
  name: 'team_send',
582
- description: 'Send a message to a specific teammate in an agent team session',
628
+ description: 'Send a message to another active session through the cross-session inbox: delivered now if it is idle, queued if it is busy.',
583
629
  parameters: {
584
630
  type: 'object',
585
631
  properties: {
@@ -597,7 +643,7 @@ const plugin = {
597
643
  // ─── Tool: session_update_tools ───────────────────────────────────────
598
644
  registerTool({
599
645
  name: 'session_update_tools',
600
- description: 'Update allowedTools or disallowedTools for a running session. Restarts the session process with --resume to apply the new tool constraints while preserving conversation history. Rejects if the session is currently busy.',
646
+ description: 'Update allowedTools or disallowedTools for a running session. Restarts the session process with --resume to apply the new tool constraints while preserving conversation history. Rejects if the session is currently busy. Without merge:true both lists are replaced, so a list you omit is cleared.',
601
647
  parameters: {
602
648
  type: 'object',
603
649
  properties: {
@@ -657,7 +703,7 @@ const plugin = {
657
703
  properties: {
658
704
  path: {
659
705
  type: 'string',
660
- description: 'Project path to purge (resolved to absolute). Ignored when all=true. Defaults to current cwd.',
706
+ description: "Project path to purge (resolved to absolute). Ignored when all=true. Defaults to the orchestrator process's working directory.",
661
707
  },
662
708
  all: {
663
709
  type: 'boolean',
@@ -784,7 +830,7 @@ const plugin = {
784
830
  // ─── Tool: codex_review ─────────────────────────────────────────────
785
831
  registerTool({
786
832
  name: 'codex_review',
787
- description: 'Run a non-interactive Codex code review (`codex review`). Pick exactly one diff scope: uncommitted (working-tree changes), base (vs branch), or commit (vs SHA). Output is plain text — Codex `review` does not emit JSON.',
833
+ description: 'Run a non-interactive Codex code review (`codex review`). Pick at most one diff scope — uncommitted (working-tree changes), base (vs branch), or commit (vs SHA); passing two is an error. Output is plain text — Codex `review` does not emit JSON.',
788
834
  parameters: {
789
835
  type: 'object',
790
836
  properties: {
@@ -979,7 +1025,7 @@ const plugin = {
979
1025
  agents: {
980
1026
  type: 'array',
981
1027
  maxItems: 16,
982
- description: 'Agent specs: { name, engine?, model?, effort?, prompt?, persona?, baseUrl?, permissionMode?, customEngine? }.',
1028
+ description: 'Agent specs: { name, engine?, model?, effort?, prompt?, persona?, baseUrl?, permissionMode?, customEngine?, acpAgent? }.',
983
1029
  items: {
984
1030
  type: 'object',
985
1031
  properties: {
@@ -999,6 +1045,7 @@ const plugin = {
999
1045
  description: 'Per-agent role instructions prepended to the shared task when no non-empty prompt is supplied.',
1000
1046
  },
1001
1047
  baseUrl: { type: 'string' },
1048
+ acpAgent: ACP_AGENT_ID_SCHEMA,
1002
1049
  },
1003
1050
  required: ['name'],
1004
1051
  },
@@ -1013,6 +1060,10 @@ const plugin = {
1013
1060
  enum: ENGINE_TYPES,
1014
1061
  description: 'Engine for the synthesis pass (default claude).',
1015
1062
  },
1063
+ synthesisAcpAgent: {
1064
+ ...ACP_AGENT_ID_SCHEMA,
1065
+ description: 'With synthesisEngine "acp": the ACP agent preset the synthesis pass starts.',
1066
+ },
1016
1067
  agentTimeoutMs: { type: 'number', description: 'Per-agent timeout in ms (default 600000).' },
1017
1068
  maxTurnsPerAgent: { type: 'number', description: 'Max agent loop turns (default 30).' },
1018
1069
  maxBudgetUsd: { type: 'number', description: 'Per-agent spend cap (USD).' },
@@ -1027,6 +1078,7 @@ const plugin = {
1027
1078
  synthesize: args.synthesize,
1028
1079
  synthesisModel: args.synthesisModel,
1029
1080
  synthesisEngine: args.synthesisEngine,
1081
+ synthesisAcpAgent: args.synthesisAcpAgent,
1030
1082
  agentTimeoutMs: args.agentTimeoutMs,
1031
1083
  maxTurnsPerAgent: args.maxTurnsPerAgent,
1032
1084
  maxBudgetUsd: args.maxBudgetUsd,
@@ -1071,13 +1123,13 @@ const plugin = {
1071
1123
  template: {
1072
1124
  type: 'string',
1073
1125
  enum: ['solve', 'council', 'fanout', 'goal'],
1074
- description: 'Build a built-in workflow instead of supplying `spec`. `solve` = triage → implement → verify → repair-until-green → review. `goal` = a Codex /goal on one codex-app thread (`task` is the objective) → verify → repair on the same thread.',
1126
+ description: 'Build a built-in workflow instead of supplying `spec`. `solve` = triage → implement → review → verify → repair-until-green. `goal` = a Codex /goal on one codex-app thread (`task` is the objective) → verify → repair on the same thread.',
1075
1127
  },
1076
1128
  task: { type: 'string', description: 'Task text, when using `template`.' },
1077
1129
  agents: {
1078
1130
  type: 'array',
1079
1131
  maxItems: 16,
1080
- description: 'Agents for the template: { name, engine?, model?, effort?, persona? }.',
1132
+ description: 'Agents for the template: { name, engine?, model?, effort?, persona?, acpAgent? }.',
1081
1133
  items: {
1082
1134
  type: 'object',
1083
1135
  properties: {
@@ -1086,6 +1138,7 @@ const plugin = {
1086
1138
  model: { type: 'string' },
1087
1139
  effort: { type: 'string', enum: EFFORT_LEVELS },
1088
1140
  persona: { type: 'string' },
1141
+ acpAgent: ACP_AGENT_ID_SCHEMA,
1089
1142
  },
1090
1143
  required: ['name'],
1091
1144
  },
@@ -1102,6 +1155,7 @@ const plugin = {
1102
1155
  model: { type: 'string' },
1103
1156
  effort: { type: 'string', enum: EFFORT_LEVELS },
1104
1157
  persona: { type: 'string' },
1158
+ acpAgent: ACP_AGENT_ID_SCHEMA,
1105
1159
  },
1106
1160
  required: ['name'],
1107
1161
  },
@@ -1112,9 +1166,11 @@ const plugin = {
1112
1166
  properties: {
1113
1167
  engine: { type: 'string', enum: ENGINE_TYPES },
1114
1168
  model: { type: 'string' },
1169
+ acpAgent: ACP_AGENT_ID_SCHEMA,
1115
1170
  },
1116
1171
  },
1117
1172
  humanGate: { type: 'boolean', description: '`solve` only: park for approval before writing anything.' },
1173
+ maxRounds: { type: 'number', description: '`council` only: max collaboration rounds (default 15).' },
1118
1174
  maxRepairs: {
1119
1175
  type: 'number',
1120
1176
  description: '`solve` / `goal`: repair attempts allowed (default 3 for solve, 1 for goal).',
@@ -1207,7 +1263,7 @@ const plugin = {
1207
1263
  throw new Error('workflow_start needs `spec`, or `template` with `task`');
1208
1264
  const agents = args.agents ?? [{ name: 'agent' }];
1209
1265
  if (template === 'council') {
1210
- spec = councilWorkflow({ task, cwd, agents });
1266
+ spec = councilWorkflow({ task, cwd, agents, maxRounds: args.maxRounds });
1211
1267
  }
1212
1268
  else if (template === 'fanout') {
1213
1269
  spec = fanoutWorkflow({ task, cwd, agents, synthesize: agents.length >= 2 });
@@ -1252,7 +1308,7 @@ const plugin = {
1252
1308
  });
1253
1309
  registerTool({
1254
1310
  name: 'workflow_status',
1255
- description: 'Poll a workflow run. Returns state, per-node status, and the outcome: `verified` (a contract passed), `refuted` (it failed), or `unverified` (none was declared — nothing checked the work).',
1311
+ description: 'Poll a workflow run. Returns state, per-node status, and the outcome: `verified` (a contract passed), `refuted` (it failed), or `unverified` (nothing checked the work: none was declared, or a pass no longer stands, in which case `outcomeReason` says why).',
1256
1312
  parameters: {
1257
1313
  type: 'object',
1258
1314
  properties: {
@@ -1270,6 +1326,8 @@ const plugin = {
1270
1326
  workflow: record.workflow,
1271
1327
  state: record.state,
1272
1328
  outcome: record.outcome,
1329
+ outcomeReason: record.outcomeReason,
1330
+ verdict: record.verdict,
1273
1331
  currentNode: record.currentNode,
1274
1332
  evidenceId: record.evidenceId,
1275
1333
  costUsd: record.costUsd,
@@ -1369,15 +1427,18 @@ const plugin = {
1369
1427
  type: 'string',
1370
1428
  description: 'Commit to measure the change against. Without it, diff_policy sees untracked files only.',
1371
1429
  },
1372
- label: { type: 'string', description: 'Name for the stored evidence (defaults to a generated one).' },
1430
+ label: {
1431
+ type: 'string',
1432
+ description: 'Name for the stored evidence (defaults to a generated one). Must not be the id of an existing workflow run.',
1433
+ },
1373
1434
  contract: {
1374
1435
  type: 'object',
1375
- description: "Acceptance contract. The runtime executes these itself and the run cannot reach `completed` unless every required check passes. Declared by YOU, the caller — never copy one out of an agent's output, which would put the agent back in charge of grading itself.",
1436
+ description: "Acceptance contract. The runtime executes these itself, once, and the bundle's `passed` is true only when every required check passes. Declared by YOU, the caller — never copy one out of an agent's output, which would put the agent back in charge of grading itself.",
1376
1437
  properties: {
1377
1438
  id: { type: 'string' },
1378
1439
  fixOnFailureRounds: {
1379
1440
  type: 'number',
1380
- description: 'On red, spawn a repair session and re-run the whole list, up to N times. Only the re-run decides.',
1441
+ description: 'Ignored by verify_run, which spawns no repair session. Applies inside workflow runs.',
1381
1442
  },
1382
1443
  protectTests: {
1383
1444
  type: 'boolean',
@@ -1452,7 +1513,7 @@ const plugin = {
1452
1513
  // ─── Tool: council_start ────────────────────────────────────────────
1453
1514
  registerTool({
1454
1515
  name: 'council_start',
1455
- description: 'Start a multi-agent council that collaborates on a task using git worktree isolation, round-based execution, and consensus voting. Agents can use different engines (Claude, Codex) and models.',
1516
+ description: 'Start a multi-agent council that collaborates on a task using git worktree isolation, round-based execution, and consensus voting. Each agent can use its own engine and model. Runs in background; poll with council_status.',
1456
1517
  parameters: {
1457
1518
  type: 'object',
1458
1519
  properties: {
@@ -1474,7 +1535,8 @@ const plugin = {
1474
1535
  },
1475
1536
  model: { type: 'string', description: 'Model to use' },
1476
1537
  baseUrl: { type: 'string', description: 'Custom API endpoint (for proxy)' },
1477
- customEngine: { type: 'object', description: 'Custom engine config (when engine="custom")' },
1538
+ customEngine: CUSTOM_ENGINE_OR_PRESET_SCHEMA,
1539
+ acpAgent: ACP_AGENT_ID_SCHEMA,
1478
1540
  effort: {
1479
1541
  type: 'string',
1480
1542
  enum: ['low', 'medium', 'high', 'xhigh', 'max', 'ultra', 'auto'],
@@ -1537,21 +1599,23 @@ const plugin = {
1537
1599
  // ─── Tool: council_abort ────────────────────────────────────────────
1538
1600
  registerTool({
1539
1601
  name: 'council_abort',
1540
- description: 'Abort a running council, stopping all agent sessions',
1602
+ description: 'Abort a council running in this process, stopping all agent sessions and removing the worktrees it created. A council that is not running here is left alone and the call returns ok: false.',
1541
1603
  parameters: {
1542
1604
  type: 'object',
1543
1605
  properties: { id: { type: 'string', description: 'Council session ID' } },
1544
1606
  required: ['id'],
1545
1607
  },
1546
1608
  execute: async (_id, args) => {
1547
- getManager().councilAbort(args.id);
1548
- return { ok: true };
1609
+ const result = getManager().councilAbort(args.id);
1610
+ if (!result.aborted)
1611
+ return { ok: false, aborted: false, state: result.state, error: result.reason };
1612
+ return { ok: true, aborted: true };
1549
1613
  },
1550
1614
  });
1551
1615
  // ─── Tool: council_inject ───────────────────────────────────────────
1552
1616
  registerTool({
1553
1617
  name: 'council_inject',
1554
- description: 'Inject a user message into the next round of a running council. The message will be appended to all agent prompts in the next round.',
1618
+ description: 'Inject a user message into the next round of a running council. The message will be appended to all agent prompts in the next round; a second inject before that round replaces the first. The council must be running in this process.',
1555
1619
  parameters: {
1556
1620
  type: 'object',
1557
1621
  properties: {
@@ -1717,9 +1781,10 @@ const plugin = {
1717
1781
  engines: {
1718
1782
  type: 'array',
1719
1783
  // Excluded: 'custom', because ultrareview spawns reviewers without a
1720
- // customEngine config.
1721
- items: { type: 'string', enum: ENGINE_TYPES.filter((e) => e !== 'custom') },
1722
- description: 'Engines to round-robin reviewers across (default ["claude"]). Every reviewer runs read-only (sandboxMode read-only), so custom is not accepted. Reviewers fan out in parallel; per-agent failures are isolated.',
1784
+ // customEngine config, and 'acp', because an ACP agent cannot be held
1785
+ // to the read-only sandbox every reviewer runs in.
1786
+ items: { type: 'string', enum: ENGINE_TYPES.filter((e) => e !== 'custom' && e !== 'acp') },
1787
+ description: 'Engines to round-robin reviewers across (default ["claude"]). Every reviewer runs read-only (sandboxMode read-only), so custom and acp are not accepted. Reviewers fan out in parallel; per-agent failures are isolated.',
1723
1788
  },
1724
1789
  },
1725
1790
  required: ['cwd'],
@@ -1767,14 +1832,19 @@ const plugin = {
1767
1832
  description: 'Stable run identifier (used to address subsequent chat / status calls)',
1768
1833
  },
1769
1834
  workspace: { type: 'string', description: 'Path to the git workspace where the run lives' },
1770
- planner_engine: { type: 'string', enum: ENGINE_TYPES, description: 'Planner engine (default: claude)' },
1835
+ // No 'acp': a role is configured by engine name alone and cannot name the ACP agent.
1836
+ planner_engine: { type: 'string', enum: AUTOLOOP_ENGINES, description: 'Planner engine (default: claude)' },
1771
1837
  planner_model: {
1772
1838
  type: 'string',
1773
1839
  description: 'Planner model (default: opus for Claude; engine default otherwise)',
1774
1840
  },
1775
1841
  planner_effort: { type: 'string', enum: EFFORT_LEVELS, description: 'Fixed Planner reasoning effort' },
1776
1842
  planner_custom_engine: CUSTOM_ENGINE_SCHEMA,
1777
- coder_engine: { type: 'string', enum: ENGINE_TYPES, description: 'Default Coder engine (default: claude)' },
1843
+ coder_engine: {
1844
+ type: 'string',
1845
+ enum: AUTOLOOP_ENGINES,
1846
+ description: 'Default Coder engine (default: claude)',
1847
+ },
1778
1848
  coder_model: {
1779
1849
  type: 'string',
1780
1850
  description: 'Default Coder model (default: sonnet for Claude; engine default otherwise)',
@@ -1783,7 +1853,7 @@ const plugin = {
1783
1853
  coder_custom_engine: CUSTOM_ENGINE_SCHEMA,
1784
1854
  reviewer_engine: {
1785
1855
  type: 'string',
1786
- enum: ENGINE_TYPES,
1856
+ enum: AUTOLOOP_ENGINES,
1787
1857
  description: 'Default Reviewer engine (default: claude)',
1788
1858
  },
1789
1859
  reviewer_model: {
@@ -1874,13 +1944,9 @@ const plugin = {
1874
1944
  // ─── Tool: autoloop_list ─────────────────────────────────────
1875
1945
  registerTool({
1876
1946
  name: 'autoloop_list',
1877
- description: 'List all v2 autoloop runs in this manager process.',
1947
+ description: 'List the v2 autoloop runs recorded on this machine, running and finished, newest first.',
1878
1948
  parameters: { type: 'object', properties: {} },
1879
- execute: async () => {
1880
- if (!manager)
1881
- return { ok: true, runs: [] };
1882
- return { ok: true, runs: getManager().autoloopList() };
1883
- },
1949
+ execute: async () => ({ ok: true, runs: getManager().autoloopList() }),
1884
1950
  });
1885
1951
  // ─── Tool: autoloop_reset_agent ──────────────────────────────
1886
1952
  registerTool({
@@ -1931,7 +1997,7 @@ const plugin = {
1931
1997
  // ─── ultraapp (read-only) ─────────────────────────────────────────────
1932
1998
  registerTool({
1933
1999
  name: 'ultraapp_list',
1934
- description: 'List all ultraapp runs (interview/build/done) with title, mode, and timestamps. Read-only — to start a new run, open the Forge dashboard tab.',
2000
+ description: 'List all ultraapp runs with title, mode (interview, queued, building, build-complete, deploying, done, failed, cancelled), and timestamps. Read-only — to start a new run, call ultraapp_new or open the Forge dashboard tab.',
1935
2001
  parameters: { type: 'object', properties: {} },
1936
2002
  execute: async () => {
1937
2003
  const ua = getManager().getUltraappManager();
@@ -2061,7 +2127,7 @@ const plugin = {
2061
2127
  });
2062
2128
  registerTool({
2063
2129
  name: 'ultraapp_build_cancel',
2064
- description: 'Cancel a queued or in-flight build. Best-effort for in-flight; the worker is expected to honour its own cancellation signal (v0.2 only emits the event).',
2130
+ description: "Cancel a queued or in-flight build. A queued build leaves the queue; an in-flight build's workflow run is cancelled, and the build stops at its next cancellation check.",
2065
2131
  parameters: {
2066
2132
  type: 'object',
2067
2133
  properties: { runId: { type: 'string' } },
@@ -2075,7 +2141,7 @@ const plugin = {
2075
2141
  });
2076
2142
  registerTool({
2077
2143
  name: 'ultraapp_feedback',
2078
- description: 'Submit a done-mode feedback message (after the run reaches `done`). The text is classified by Haiku into cosmetic / spec-delta / structural and routed: cosmetic runs the patcher (Opus diff + validate + auto-revert + version snapshot); spec-delta flips the run back to `interview` with a focused bootstrap; structural posts a "start fresh" suggestion.',
2144
+ description: 'Submit a done-mode feedback message (after the run reaches `done`). The text is classified by Haiku into cosmetic / spec-delta / structural and routed: cosmetic runs the patcher (Opus diff + validate + auto-revert + version snapshot); spec-delta flips the run back to `interview` with a focused bootstrap; structural posts a "start fresh" suggestion. Before the run reaches `done`, the text is sent to the interview as a free-form answer instead.',
2079
2145
  parameters: {
2080
2146
  type: 'object',
2081
2147
  properties: {
@@ -2092,7 +2158,7 @@ const plugin = {
2092
2158
  });
2093
2159
  registerTool({
2094
2160
  name: 'ultraapp_promote_version',
2095
- description: "Atomically swap which previously-built version is currently deployed. Stops the old container, starts the target version's container, updates the router map. Requires a router to be wired (see clawo serve).",
2161
+ description: 'Make a version the one serving the app. A version deployed before is swapped in (the live one is stopped, the target restarted, the router map updated); one never deployed, such as a patched version, is built and deployed first. Requires a router to be wired (see clawo serve).',
2096
2162
  parameters: {
2097
2163
  type: 'object',
2098
2164
  properties: {