@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
@@ -0,0 +1,355 @@
1
+ /**
2
+ * A Claude Code `/goal` behind the `GoalSession` surface the kernel's `goal`
3
+ * node drives, so one node runs a goal on either engine.
4
+ *
5
+ * Codex's app-server owns a goal: it has RPCs to set, pause and read it, and
6
+ * notifies every status change. Claude Code has none of that. What it has,
7
+ * measured on CLI 2.1.312 in stream-json mode:
8
+ *
9
+ * - `/goal <condition>` sets the goal and starts working. A Stop hook judges
10
+ * the condition after every turn and feeds the turn back while it does not
11
+ * hold, all inside the one send; a single `result` arrives when the goal is
12
+ * met, and the goal clears itself.
13
+ * - A bare `/goal` answers at once, without a model turn: `Goal active: …` or
14
+ * `No goal set. …`. That is the only way to read the goal.
15
+ * - The goal is part of the transcript. A process that dies and is resumed
16
+ * with `--resume` still has it, but nothing drives it until a message comes.
17
+ * - The `interrupt` control request ends the running turn with an
18
+ * `error_during_execution` result and leaves the goal set.
19
+ * - A turn that fails (an auth error, a usage limit) ends with an `is_error`
20
+ * result, and the CLI clears the goal then too ("Goal cleared after an
21
+ * unrecoverable error"). "No goal set" alone does not mean the goal was met.
22
+ * - The condition is judged by a separate model reading the transcript, not by
23
+ * the agent. When it blocks the agent's stop 9 times running, the CLI ends
24
+ * the turn anyway and says so in an `informational` system event; the goal
25
+ * stays set.
26
+ *
27
+ * So the status here is partly the adapter's own bookkeeping. `active` while a
28
+ * goal turn runs. `complete` only when a turn that started with the goal set
29
+ * ended without an error and the goal is gone: the Stop hook let it end. A
30
+ * goal still set with nothing driving it, a failed turn, and a reopened thread
31
+ * whose goal is gone are all `paused`, which the node resumes within its bound;
32
+ * resuming re-arms the goal (`/goal <objective>` again) when the CLI dropped
33
+ * it, so a goal already met costs one turn to confirm. A failed login is
34
+ * `blocked`: resuming cannot fix it. So is a turn the CLI had to end over the
35
+ * Stop hook: the agent asked to stop again and again, and continuing it only
36
+ * repeats that. The node goes on to its verifier either way, and the contract,
37
+ * not the agent or the hook, decides.
38
+ *
39
+ * Tokens are the session's input, output and cache-read tokens; the CLI reports
40
+ * no goal-level count. A reopened process starts its counters at zero, so the
41
+ * node hands over what the thread had already spent.
42
+ */
43
+ import { EventEmitter } from 'node:events';
44
+ import { SESSION_EVENT } from './constants.js';
45
+ /** Sent to pick a goal back up: the Stop hook keeps it going from there. */
46
+ export const CLAUDE_GOAL_CONTINUE = 'Continue working toward the active goal. Pick up from where the work stands now.';
47
+ const PROBE_TIMEOUT_MS = 60_000;
48
+ /** Map a failed turn's text onto the codex error codes the node treats as transient. */
49
+ export function classifyClaudeError(text, apiStatus) {
50
+ const status = typeof apiStatus === 'number' ? apiStatus : Number.NaN;
51
+ if (status === 401 ||
52
+ status === 403 ||
53
+ /not logged in|\/login|invalid api key|authentication|unauthorized/i.test(text)) {
54
+ return 'unauthorized';
55
+ }
56
+ if (status === 429 || /usage limit|rate limit|limit reached|hit your limit|\b429\b/i.test(text)) {
57
+ return 'usageLimitExceeded';
58
+ }
59
+ if (status === 529 || /overloaded|\b529\b/i.test(text))
60
+ return 'serverOverloaded';
61
+ if ((status >= 500 && status < 600) ||
62
+ /\b5\d\d\b|internal server error|api error|ECONNRESET|ETIMEDOUT|socket hang up|fetch failed|network/i.test(text)) {
63
+ return 'internalServerError';
64
+ }
65
+ return null;
66
+ }
67
+ /** Read a bare `/goal` answer. */
68
+ export function parseGoalProbe(text) {
69
+ const t = text.trim();
70
+ if (/^no goal set/i.test(t))
71
+ return { active: false };
72
+ const m = /^goal active:\s*([\s\S]*?)(?:\s*\((?:not yet evaluated|[^()]*)\))?\s*$/i.exec(t);
73
+ if (m)
74
+ return { active: true, objective: m[1].trim() };
75
+ return undefined;
76
+ }
77
+ export class ClaudeGoalSession extends EventEmitter {
78
+ host;
79
+ open;
80
+ _goal = null;
81
+ _lastError = null;
82
+ _turnActive = false;
83
+ _interrupting = false;
84
+ /** The CLI held the goal when the running (or last) turn started. */
85
+ _armed = false;
86
+ /** The CLI's notice that it ended the running turn over the Stop hook. */
87
+ _hookOverride = null;
88
+ _tokensAtOpen;
89
+ _budgetFrom = 0;
90
+ _turnStartedAt = null;
91
+ _timeUsed;
92
+ _seedTokens;
93
+ _onText = (...args) => this.emit(SESSION_EVENT.TEXT, ...args);
94
+ _onClose = (...args) => {
95
+ this._endTurn();
96
+ // What the dead process spent, so the node hands it to the one it reopens.
97
+ if (this._goal)
98
+ this.emit('goal:updated', this._snapshot());
99
+ this.emit(SESSION_EVENT.CLOSE, ...args);
100
+ };
101
+ /** `_settle` reading why the last turn ended; nothing else may probe meanwhile. */
102
+ _settling = null;
103
+ _onResult = (...args) => {
104
+ const settling = this._settle(args[0]).finally(() => {
105
+ if (this._settling === settling)
106
+ this._settling = null;
107
+ });
108
+ this._settling = settling;
109
+ };
110
+ _onSystem = (...args) => {
111
+ const e = args[0];
112
+ if (!this._turnActive || e?.subtype !== 'informational' || typeof e.content !== 'string')
113
+ return;
114
+ if (/blocked the turn from ending \d+ consecutive times/i.test(e.content))
115
+ this._hookOverride = e.content;
116
+ };
117
+ constructor(host, open = {}) {
118
+ super();
119
+ this.host = host;
120
+ this.open = open;
121
+ this._tokensAtOpen = this._sessionTokens();
122
+ this._seedTokens = open.tokensUsed ?? 0;
123
+ this._timeUsed = open.timeUsedSeconds ?? 0;
124
+ host.on(SESSION_EVENT.TEXT, this._onText);
125
+ host.on(SESSION_EVENT.CLOSE, this._onClose);
126
+ host.on(SESSION_EVENT.RESULT, this._onResult);
127
+ host.on(SESSION_EVENT.SYSTEM, this._onSystem);
128
+ }
129
+ /** Stop listening to the host. The session itself is the manager's to stop. */
130
+ detach() {
131
+ this.host.off(SESSION_EVENT.TEXT, this._onText);
132
+ this.host.off(SESSION_EVENT.CLOSE, this._onClose);
133
+ this.host.off(SESSION_EVENT.RESULT, this._onResult);
134
+ this.host.off(SESSION_EVENT.SYSTEM, this._onSystem);
135
+ }
136
+ /** The Claude session id. Named for the interface, which Codex defined. */
137
+ get codexThreadId() {
138
+ return this.host.sessionId || this.open.threadId;
139
+ }
140
+ get goal() {
141
+ return this._goal ? this._snapshot() : null;
142
+ }
143
+ get lastError() {
144
+ return this._lastError;
145
+ }
146
+ get turnActive() {
147
+ return this._turnActive;
148
+ }
149
+ async setGoal(p) {
150
+ if (p.objective !== undefined) {
151
+ this._goal = {
152
+ objective: p.objective,
153
+ status: 'active',
154
+ tokenBudget: p.tokenBudget ?? null,
155
+ tokensUsed: this._tokensUsed(),
156
+ timeUsedSeconds: this._seconds(),
157
+ };
158
+ this._budgetFrom = this._tokensUsed();
159
+ await this._startTurn(`/goal ${p.objective}`, true);
160
+ }
161
+ else if (p.status === 'paused') {
162
+ if (this._turnActive)
163
+ this._interrupt();
164
+ this._setStatus('paused');
165
+ }
166
+ else if (p.status === 'active') {
167
+ await this._settling;
168
+ if (!this._goal)
169
+ throw new Error('no goal to resume: set an objective first');
170
+ this._setStatus('active');
171
+ if (!this._turnActive) {
172
+ // A failed turn or a restart may have cost the CLI its goal: set it again rather than chat.
173
+ const probe = await this._probe();
174
+ if (probe?.active)
175
+ await this._startTurn(CLAUDE_GOAL_CONTINUE, true);
176
+ else
177
+ await this._startTurn(`/goal ${this._goal.objective}`, true);
178
+ }
179
+ }
180
+ return this._snapshot();
181
+ }
182
+ async getGoal() {
183
+ if (this._settling) {
184
+ // A turn just ended and its own probe decides the status: a second `/goal` would race it.
185
+ await this._settling;
186
+ return this._goal ? this._snapshot() : null;
187
+ }
188
+ if (this._turnActive) {
189
+ this._enforceBudget();
190
+ return this._snapshot();
191
+ }
192
+ const status = this._goal?.status;
193
+ if (status === 'complete' || status === 'budgetLimited' || status === 'blocked')
194
+ return this._snapshot();
195
+ const probe = await this._probe();
196
+ if (probe?.active) {
197
+ // Set, and nothing is working on it: a node that sees `paused` resumes it.
198
+ const keep = this._goal?.status === 'usageLimited' ? 'usageLimited' : 'paused';
199
+ this._goal = this._goal
200
+ ? { ...this._goal, status: keep }
201
+ : {
202
+ objective: this.open.objective || probe.objective,
203
+ status: keep,
204
+ tokenBudget: null,
205
+ tokensUsed: 0,
206
+ timeUsedSeconds: 0,
207
+ };
208
+ this._budgetFrom = this._budgetFrom || this._tokensUsed();
209
+ }
210
+ else if (probe && !probe.active) {
211
+ // Gone, but not seen to be met (that is `_settle`'s call): met, or dropped by a failed turn.
212
+ // Paused, so resuming re-arms it; a goal already met then ends in one turn.
213
+ if (this._goal?.status === 'active') {
214
+ this._goal = { ...this._goal, status: 'paused' };
215
+ }
216
+ else if (!this._goal && this.open.resumed && this.open.objective) {
217
+ const objective = this.open.objective;
218
+ this._goal = { objective, status: 'paused', tokenBudget: null, tokensUsed: 0, timeUsedSeconds: 0 };
219
+ }
220
+ }
221
+ return this._goal ? this._snapshot() : null;
222
+ }
223
+ async clearGoal() {
224
+ if (this._turnActive)
225
+ this._interrupt();
226
+ await this.host.send('/goal clear', { waitForComplete: true, timeout: PROBE_TIMEOUT_MS }).catch(() => undefined);
227
+ this._goal = null;
228
+ }
229
+ async steer(text) {
230
+ if (!this._turnActive)
231
+ return { steered: false };
232
+ // A message written during a turn is folded into it by the CLI.
233
+ await this.host.send(text, { waitForComplete: false });
234
+ return { steered: true };
235
+ }
236
+ async interrupt() {
237
+ if (!this._turnActive)
238
+ return { interrupted: false };
239
+ return { interrupted: this._interrupt() };
240
+ }
241
+ // ─── Internals ─────────────────────────────────────────────────────────
242
+ _sessionTokens() {
243
+ try {
244
+ const s = this.host.getStats();
245
+ return (s.tokensIn || 0) + (s.tokensOut || 0) + (s.cachedTokens || 0);
246
+ }
247
+ catch {
248
+ return 0;
249
+ }
250
+ }
251
+ _tokensUsed() {
252
+ return this._seedTokens + Math.max(0, this._sessionTokens() - this._tokensAtOpen);
253
+ }
254
+ _seconds() {
255
+ const running = this._turnStartedAt === null ? 0 : (Date.now() - this._turnStartedAt) / 1000;
256
+ return Math.round(this._timeUsed + running);
257
+ }
258
+ _snapshot() {
259
+ const g = this._goal;
260
+ return { ...g, tokensUsed: this._tokensUsed(), timeUsedSeconds: this._seconds() };
261
+ }
262
+ _setStatus(status) {
263
+ if (!this._goal || this._goal.status === status)
264
+ return;
265
+ this._goal = { ...this._goal, status };
266
+ this.emit('goal:updated', this._snapshot());
267
+ }
268
+ async _startTurn(text, armed) {
269
+ this._turnActive = true;
270
+ this._interrupting = false;
271
+ this._armed = armed;
272
+ this._hookOverride = null;
273
+ this._turnStartedAt = Date.now();
274
+ try {
275
+ await this.host.send(text, { waitForComplete: false });
276
+ }
277
+ catch (err) {
278
+ this._endTurn();
279
+ this._fail(err.message, null);
280
+ }
281
+ }
282
+ _endTurn() {
283
+ if (this._turnStartedAt !== null)
284
+ this._timeUsed += (Date.now() - this._turnStartedAt) / 1000;
285
+ this._turnStartedAt = null;
286
+ this._turnActive = false;
287
+ }
288
+ _interrupt() {
289
+ this._interrupting = true;
290
+ return this.host.interruptTurn();
291
+ }
292
+ _fail(message, code) {
293
+ this._lastError = { message, code, willRetry: false, at: new Date().toISOString() };
294
+ this.emit('codex:error', this._lastError);
295
+ }
296
+ /** Past its budget the goal stops, as Codex's does: `budgetLimited` is terminal. */
297
+ _enforceBudget() {
298
+ const budget = this._goal?.tokenBudget;
299
+ if (!budget || this._goal?.status !== 'active')
300
+ return;
301
+ if (this._tokensUsed() - this._budgetFrom < budget)
302
+ return;
303
+ if (this._turnActive)
304
+ this._interrupt();
305
+ this._setStatus('budgetLimited');
306
+ }
307
+ async _probe() {
308
+ try {
309
+ const r = (await this.host.send('/goal', { waitForComplete: true, timeout: PROBE_TIMEOUT_MS }));
310
+ return typeof r?.text === 'string' ? parseGoalProbe(r.text) : undefined;
311
+ }
312
+ catch {
313
+ return undefined;
314
+ }
315
+ }
316
+ /** A goal turn ended: read why, and what the goal is now. */
317
+ async _settle(event) {
318
+ if (!this._turnActive || !event)
319
+ return;
320
+ this._endTurn();
321
+ this.emit(SESSION_EVENT.RESULT, event);
322
+ const text = typeof event.result === 'string' ? event.result : '';
323
+ const failed = !!event.is_error || event.stop_reason === 'error' || String(event.subtype ?? '').startsWith('error');
324
+ if (this._interrupting) {
325
+ this._interrupting = false;
326
+ // A stop we asked for: pause and budget already set the status.
327
+ if (this._goal?.status === 'active')
328
+ this._setStatus('paused');
329
+ return;
330
+ }
331
+ if (failed) {
332
+ // The CLI drops the goal with a failed turn; resuming re-arms it.
333
+ this._armed = false;
334
+ const code = classifyClaudeError(text, event.api_error_status);
335
+ this._fail(text || String(event.subtype ?? 'the turn failed'), code);
336
+ this._setStatus(code === 'usageLimitExceeded' ? 'usageLimited' : code === 'unauthorized' ? 'blocked' : 'paused');
337
+ return;
338
+ }
339
+ const armed = this._armed;
340
+ const probe = await this._probe();
341
+ this._enforceBudget();
342
+ if (this._goal?.status !== 'active')
343
+ return;
344
+ // Met: the goal was set when the turn started, the turn ended cleanly, and the CLI cleared it.
345
+ if (armed && probe && !probe.active)
346
+ this._setStatus('complete');
347
+ else if (probe?.active && this._hookOverride) {
348
+ this._fail(this._hookOverride, null);
349
+ this._setStatus('blocked');
350
+ }
351
+ else
352
+ this._setStatus('paused');
353
+ }
354
+ }
355
+ //# sourceMappingURL=claude-goal-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-goal-session.js","sourceRoot":"","sources":["../../src/claude-goal-session.ts"],"names":[],"mappings":"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"}
@@ -38,6 +38,12 @@ interface SessionManagerLike {
38
38
  * `split(/\s+/)[0]` truncates any path containing a space.
39
39
  */
40
40
  export declare function councilWorktreePaths(projectDir: string): Promise<string[]>;
41
+ /**
42
+ * The package this module belongs to: the nearest directory above it holding a
43
+ * package.json. A fixed `..` is right from `src/` but lands on `dist/` from the
44
+ * built `dist/src/`, which would leave the package root itself unguarded.
45
+ */
46
+ export declare function programRoot(moduleFile?: string): string;
41
47
  export declare class Council extends EventEmitter {
42
48
  private config;
43
49
  private manager;
@@ -60,6 +66,8 @@ export declare class Council extends EventEmitter {
60
66
  * from a rebuilt session. This is what lets them run after a restart, which
61
67
  * the in-memory registry made impossible.
62
68
  */
69
+ /** Add one send's cost to the council's total. */
70
+ private _charge;
63
71
  adoptSession(session: CouncilSession): void;
64
72
  getSession(): CouncilSession | undefined;
65
73
  injectMessage(message: string): void;
@@ -127,17 +127,26 @@ async function setupWorktrees(projectDir, agents, logger) {
127
127
  if (!isGit) {
128
128
  await spawnAsync('git', ['-C', projectDir, 'init'], { timeout: GIT_CMD_TIMEOUT_MS });
129
129
  }
130
- // Git user config
131
- await spawnAsync('git', ['-C', projectDir, 'config', '--local', 'user.email', 'council@openclaw'], {
132
- timeout: GIT_CMD_TIMEOUT_MS,
133
- }).catch((err) => {
134
- log.error('Failed to set git user.email:', err.message);
135
- });
136
- await spawnAsync('git', ['-C', projectDir, 'config', '--local', 'user.name', 'Council'], {
137
- timeout: GIT_CMD_TIMEOUT_MS,
138
- }).catch((err) => {
139
- log.error('Failed to set git user.name:', err.message);
140
- });
130
+ // Commits here (and the agents' own, in the worktrees) need an identity. Only
131
+ // a missing one is filled in: `.git/config` belongs to the user and outlives
132
+ // the council, so an identity they configured at any level is left alone.
133
+ for (const [key, value] of [
134
+ ['user.email', 'council@openclaw'],
135
+ ['user.name', 'Council'],
136
+ ]) {
137
+ const configured = await spawnAsync('git', ['-C', projectDir, 'config', '--get', key], {
138
+ timeout: GIT_CMD_TIMEOUT_MS,
139
+ })
140
+ .then((r) => r.stdout.trim().length > 0)
141
+ .catch(() => false);
142
+ if (configured)
143
+ continue;
144
+ await spawnAsync('git', ['-C', projectDir, 'config', '--local', key, value], {
145
+ timeout: GIT_CMD_TIMEOUT_MS,
146
+ }).catch((err) => {
147
+ log.error(`Failed to set git ${key}:`, err.message);
148
+ });
149
+ }
141
150
  // Ensure at least one commit
142
151
  const hasCommit = await spawnAsync('git', ['-C', projectDir, 'rev-parse', 'HEAD'], { timeout: GIT_CMD_TIMEOUT_MS })
143
152
  .then(() => true)
@@ -288,6 +297,22 @@ Collaboration ends **only when all members vote YES**.
288
297
 
289
298
  Start working!`;
290
299
  }
300
+ /**
301
+ * The package this module belongs to: the nearest directory above it holding a
302
+ * package.json. A fixed `..` is right from `src/` but lands on `dist/` from the
303
+ * built `dist/src/`, which would leave the package root itself unguarded.
304
+ */
305
+ export function programRoot(moduleFile = fileURLToPath(import.meta.url)) {
306
+ let dir = path.dirname(moduleFile);
307
+ for (;;) {
308
+ if (fs.existsSync(path.join(dir, 'package.json')))
309
+ return dir;
310
+ const parent = path.dirname(dir);
311
+ if (parent === dir)
312
+ return path.resolve(path.dirname(moduleFile), '..');
313
+ dir = parent;
314
+ }
315
+ }
291
316
  /** Resolve the path to configs/ relative to this module (works from both src/ and dist/) */
292
317
  function resolveConfigPath(filename) {
293
318
  const filePath = fileURLToPath(import.meta.url);
@@ -352,6 +377,11 @@ export class Council extends EventEmitter {
352
377
  * from a rebuilt session. This is what lets them run after a restart, which
353
378
  * the in-memory registry made impossible.
354
379
  */
380
+ /** Add one send's cost to the council's total. */
381
+ _charge(result) {
382
+ if (this._session && result.usage)
383
+ this._session.costUsd = (this._session.costUsd ?? 0) + result.usage.costUsd;
384
+ }
355
385
  adoptSession(session) {
356
386
  this._session = session;
357
387
  }
@@ -420,6 +450,7 @@ export class Council extends EventEmitter {
420
450
  maxTurns: this.config.maxTurnsPerAgent || DEFAULT_MAX_TURNS_PER_AGENT,
421
451
  maxBudgetUsd: this.config.maxBudgetUsd,
422
452
  customEngine: agent.customEngine,
453
+ ...(agent.acpAgent === undefined ? {} : { acpAgent: agent.acpAgent }),
423
454
  effort: agent.effort,
424
455
  ultracode: agent.ultracode,
425
456
  });
@@ -431,6 +462,7 @@ export class Council extends EventEmitter {
431
462
  this.emitEvent({ type: 'agent-chunk', sessionId, round, agent: agent.name, content: chunk });
432
463
  },
433
464
  });
465
+ this._charge(result);
434
466
  content = result.output;
435
467
  // Check if response is substantive
436
468
  const stripped = content.replace(/^\[Agent completed[^\]]*\]\s*/i, '').trim();
@@ -448,6 +480,7 @@ export class Council extends EventEmitter {
448
480
  break;
449
481
  try {
450
482
  const followup = await this.manager.sendMessage(sessionName, 'Stop all tool calls. Output your complete report now, including your consensus vote [CONSENSUS: YES] or [CONSENSUS: NO].', { timeout: FOLLOWUP_TIMEOUT_MS, parentRunId: sessionId });
483
+ this._charge(followup);
451
484
  if (followup.output.trim().length > 0) {
452
485
  content = followup.output;
453
486
  if (hasConsensusMarker(content) || content.length >= MIN_COMPLETE_RESPONSE_LENGTH)
@@ -509,7 +542,7 @@ export class Council extends EventEmitter {
509
542
  throw new Error('Council not initialised — call init() first');
510
543
  const trimmedTask = session.task;
511
544
  // Safety check: prevent council from running inside the program's own directory
512
- const moduleRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
545
+ const moduleRoot = programRoot();
513
546
  const resolvedProjectDir = path.resolve(this.config.projectDir);
514
547
  const rel = path.relative(moduleRoot, resolvedProjectDir);
515
548
  const isInside = rel === '' || (!rel.startsWith('..') && !path.isAbsolute(rel));