poe-code 3.0.197 → 3.0.199

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 (100) hide show
  1. package/dist/cli/commands/configure.d.ts +0 -7
  2. package/dist/cli/commands/configure.js +11 -14
  3. package/dist/cli/commands/configure.js.map +1 -1
  4. package/dist/cli/commands/provider.js +8 -1
  5. package/dist/cli/commands/provider.js.map +1 -1
  6. package/dist/cli/constants.d.ts +1 -1
  7. package/dist/cli/constants.js +0 -1
  8. package/dist/cli/constants.js.map +1 -1
  9. package/dist/index.js +221 -263
  10. package/dist/index.js.map +4 -4
  11. package/dist/providers/claude-code.js +6 -21
  12. package/dist/providers/claude-code.js.map +3 -3
  13. package/dist/providers/codex.js +6 -21
  14. package/dist/providers/codex.js.map +3 -3
  15. package/dist/providers/create-provider.js +0 -2
  16. package/dist/providers/create-provider.js.map +1 -1
  17. package/dist/providers/goose.js +14 -26
  18. package/dist/providers/goose.js.map +3 -3
  19. package/dist/providers/kimi.js +6 -21
  20. package/dist/providers/kimi.js.map +3 -3
  21. package/dist/providers/opencode.js +6 -21
  22. package/dist/providers/opencode.js.map +3 -3
  23. package/dist/providers/poe-agent.js +66 -85
  24. package/dist/providers/poe-agent.js.map +4 -4
  25. package/dist/utils/command-checks.d.ts +2 -1
  26. package/dist/utils/command-checks.js +3 -1
  27. package/dist/utils/command-checks.js.map +1 -1
  28. package/package.json +4 -1
  29. package/packages/memory/dist/cache.js +1 -1
  30. package/packages/memory/dist/explain.js +1 -1
  31. package/packages/memory/dist/index.js +9 -7
  32. package/packages/memory/dist/index.js.map +3 -3
  33. package/packages/memory/dist/query.js +1 -1
  34. package/packages/memory/dist/tokens.js +1 -1
  35. package/packages/superintendent/dist/cli.d.ts +2 -0
  36. package/packages/superintendent/dist/cli.js +41 -0
  37. package/packages/superintendent/dist/commands/builder-group.d.ts +52 -0
  38. package/packages/superintendent/dist/commands/builder-group.js +73 -0
  39. package/packages/superintendent/dist/commands/complete.d.ts +19 -0
  40. package/packages/superintendent/dist/commands/complete.js +54 -0
  41. package/packages/superintendent/dist/commands/index.d.ts +4 -0
  42. package/packages/superintendent/dist/commands/index.js +4 -0
  43. package/packages/superintendent/dist/commands/inspector-group.d.ts +115 -0
  44. package/packages/superintendent/dist/commands/inspector-group.js +133 -0
  45. package/packages/superintendent/dist/commands/install.d.ts +31 -0
  46. package/packages/superintendent/dist/commands/install.js +148 -0
  47. package/packages/superintendent/dist/commands/plan-path.d.ts +9 -0
  48. package/packages/superintendent/dist/commands/plan-path.js +40 -0
  49. package/packages/superintendent/dist/commands/poe-agent-runner.d.ts +5 -0
  50. package/packages/superintendent/dist/commands/poe-agent-runner.js +27 -0
  51. package/packages/superintendent/dist/commands/run.d.ts +86 -0
  52. package/packages/superintendent/dist/commands/run.js +945 -0
  53. package/packages/superintendent/dist/commands/superintendent-group.d.ts +325 -0
  54. package/packages/superintendent/dist/commands/superintendent-group.js +238 -0
  55. package/packages/superintendent/dist/config-scope.d.ts +8 -0
  56. package/packages/superintendent/dist/config-scope.js +9 -0
  57. package/packages/superintendent/dist/direct-execution.d.ts +1 -0
  58. package/packages/superintendent/dist/direct-execution.js +20 -0
  59. package/packages/superintendent/dist/document/parse.d.ts +59 -0
  60. package/packages/superintendent/dist/document/parse.js +409 -0
  61. package/packages/superintendent/dist/document/tasks.d.ts +12 -0
  62. package/packages/superintendent/dist/document/tasks.js +96 -0
  63. package/packages/superintendent/dist/document/write.d.ts +6 -0
  64. package/packages/superintendent/dist/document/write.js +156 -0
  65. package/packages/superintendent/dist/index.d.ts +12 -0
  66. package/packages/superintendent/dist/index.js +15 -0
  67. package/packages/superintendent/dist/mcp.d.ts +24 -0
  68. package/packages/superintendent/dist/mcp.js +202 -0
  69. package/packages/superintendent/dist/runtime/agentic-tools.d.ts +33 -0
  70. package/packages/superintendent/dist/runtime/agentic-tools.js +74 -0
  71. package/packages/superintendent/dist/runtime/loop.d.ts +88 -0
  72. package/packages/superintendent/dist/runtime/loop.js +446 -0
  73. package/packages/superintendent/dist/runtime/resolve-cwd.d.ts +2 -0
  74. package/packages/superintendent/dist/runtime/resolve-cwd.js +10 -0
  75. package/packages/superintendent/dist/runtime/run-builder.d.ts +13 -0
  76. package/packages/superintendent/dist/runtime/run-builder.js +102 -0
  77. package/packages/superintendent/dist/runtime/run-inspector.d.ts +16 -0
  78. package/packages/superintendent/dist/runtime/run-inspector.js +119 -0
  79. package/packages/superintendent/dist/runtime/run-owner-review.d.ts +18 -0
  80. package/packages/superintendent/dist/runtime/run-owner-review.js +208 -0
  81. package/packages/superintendent/dist/runtime/run-superintendent.d.ts +13 -0
  82. package/packages/superintendent/dist/runtime/run-superintendent.js +208 -0
  83. package/packages/superintendent/dist/runtime/system-prompt.d.ts +17 -0
  84. package/packages/superintendent/dist/runtime/system-prompt.js +54 -0
  85. package/packages/superintendent/dist/runtime/templates.d.ts +22 -0
  86. package/packages/superintendent/dist/runtime/templates.js +23 -0
  87. package/packages/superintendent/dist/runtime/types.d.ts +4 -0
  88. package/packages/superintendent/dist/runtime/types.js +1 -0
  89. package/packages/superintendent/dist/runtime/workflow-tool.d.ts +29 -0
  90. package/packages/superintendent/dist/runtime/workflow-tool.js +83 -0
  91. package/packages/superintendent/dist/state/machine.d.ts +14 -0
  92. package/packages/superintendent/dist/state/machine.js +53 -0
  93. package/packages/superintendent/dist/templates/SKILL_superintendent.md +193 -0
  94. package/packages/superintendent/dist/testing/index.d.ts +2 -0
  95. package/packages/superintendent/dist/testing/index.js +1 -0
  96. package/packages/superintendent/dist/testing/simulation.d.ts +57 -0
  97. package/packages/superintendent/dist/testing/simulation.js +346 -0
  98. package/dist/providers/tiny-http-mcp-server.d.ts +0 -22
  99. package/dist/providers/tiny-http-mcp-server.js +0 -1471
  100. package/dist/providers/tiny-http-mcp-server.js.map +0 -7
@@ -0,0 +1,446 @@
1
+ import path from "node:path";
2
+ import * as fsPromises from "node:fs/promises";
3
+ import { lockWorkflow, makeRunLogFileName, resolveWorkflowPath } from "@poe-code/agent-harness-tools";
4
+ import { spawn } from "@poe-code/agent-spawn";
5
+ import { parseSuperintendentDoc } from "../document/parse.js";
6
+ import { parseTaskBoard } from "../document/tasks.js";
7
+ import { updateStatus } from "../document/write.js";
8
+ import { createLoopState } from "../state/machine.js";
9
+ import { runBuilder } from "./run-builder.js";
10
+ import { runInspector } from "./run-inspector.js";
11
+ import { runOwnerReview } from "./run-owner-review.js";
12
+ import { runSuperintendent } from "./run-superintendent.js";
13
+ import { collectReferencedInspectors } from "./templates.js";
14
+ export async function runLoop(input, callbacks) {
15
+ const options = normalizeOptions(input, callbacks);
16
+ const releaseLock = await lockWorkflow(options.docPath, {
17
+ fs: options.fs
18
+ });
19
+ try {
20
+ return await withInjectedAgentRunner(options, async () => {
21
+ let state = createLoopState(await readDocument(options.fs, options.docPath));
22
+ let context = {
23
+ inspectors: {},
24
+ inspectorLogs: {}
25
+ };
26
+ while (true) {
27
+ const stopReason = readLoopStopReason(options, state);
28
+ if (stopReason) {
29
+ return finishLoop(options.callbacks, state, stopReason);
30
+ }
31
+ if (state.state === "in_progress") {
32
+ const roundStartState = { ...state };
33
+ const roundSnapshot = await readDocumentContent(options.fs, options.docPath);
34
+ state = beginRound(state);
35
+ emitStateChange(options.callbacks, state);
36
+ await writeLoopState(options.fs, options.docPath, state);
37
+ options.callbacks.onBuilderStart?.();
38
+ let builderResult;
39
+ try {
40
+ builderResult = await options.runners.builder(await readDocument(options.fs, options.docPath), createTemplateContext(context), buildRoleOptions(options, "builder"));
41
+ }
42
+ catch (error) {
43
+ await restoreDocument(options.fs, options.docPath, roundSnapshot);
44
+ const normalizedError = toError(error);
45
+ options.callbacks.onBuilderFailed?.(normalizedError);
46
+ throw normalizedError;
47
+ }
48
+ options.callbacks.onBuilderComplete?.(builderResult);
49
+ context = {
50
+ ...context,
51
+ builder: builderResult,
52
+ inspectors: {},
53
+ inspectorLogs: {}
54
+ };
55
+ await writeLoopState(options.fs, options.docPath, state);
56
+ const stopReason = readInterruptionReason(options, state);
57
+ if (stopReason) {
58
+ if (stopReason === "aborted") {
59
+ state = await rollbackRoundStatus(options, roundStartState);
60
+ }
61
+ return finishLoop(options.callbacks, state, stopReason);
62
+ }
63
+ const docForInspectors = await readDocument(options.fs, options.docPath);
64
+ const inspectorEntries = filterAutoRunInspectors(docForInspectors);
65
+ for (const [name, config] of inspectorEntries) {
66
+ options.callbacks.onInspectorStart?.(name);
67
+ const inspectorSnapshot = await readDocumentContent(options.fs, options.docPath);
68
+ let inspectorResult;
69
+ try {
70
+ inspectorResult = await options.runners.inspector(name, config, await readDocument(options.fs, options.docPath), createTemplateContext(context), buildRoleOptions(options, `inspector-${name}`));
71
+ }
72
+ catch (error) {
73
+ await restoreDocument(options.fs, options.docPath, inspectorSnapshot);
74
+ const normalizedError = toError(error);
75
+ options.callbacks.onInspectorFailed?.(name, normalizedError);
76
+ throw normalizedError;
77
+ }
78
+ options.callbacks.onInspectorComplete?.(inspectorResult);
79
+ context = {
80
+ ...context,
81
+ inspectors: {
82
+ ...context.inspectors,
83
+ [inspectorResult.name]: inspectorResult.summary
84
+ },
85
+ inspectorLogs: {
86
+ ...context.inspectorLogs,
87
+ ...(inspectorResult.log_path
88
+ ? { [inspectorResult.name]: inspectorResult.log_path }
89
+ : {})
90
+ }
91
+ };
92
+ await writeLoopState(options.fs, options.docPath, state);
93
+ const stopReason = readInterruptionReason(options, state);
94
+ if (stopReason) {
95
+ if (stopReason === "aborted") {
96
+ state = await rollbackRoundStatus(options, roundStartState);
97
+ }
98
+ return finishLoop(options.callbacks, state, stopReason);
99
+ }
100
+ }
101
+ const superintendentResult = await executeSuperintendent(options, context);
102
+ context = {
103
+ ...context,
104
+ superintendentSummary: superintendentResult.summary,
105
+ ...(superintendentResult.log_path
106
+ ? { superintendentLogPath: superintendentResult.log_path }
107
+ : {})
108
+ };
109
+ if (superintendentResult.transition?.action === "request_review") {
110
+ context = {
111
+ ...context,
112
+ ownerFeedback: undefined
113
+ };
114
+ state = {
115
+ ...state,
116
+ state: "review",
117
+ reviewTurn: 0
118
+ };
119
+ emitStateChange(options.callbacks, state);
120
+ }
121
+ await writeLoopState(options.fs, options.docPath, state);
122
+ if (state.state === "in_progress") {
123
+ options.callbacks.onRoundComplete?.(state.round);
124
+ }
125
+ {
126
+ const stopReason = readLoopStopReason(options, state);
127
+ if (stopReason) {
128
+ if (stopReason === "aborted" && state.state === "in_progress") {
129
+ state = await rollbackRoundStatus(options, roundStartState);
130
+ }
131
+ return finishLoop(options.callbacks, state, stopReason);
132
+ }
133
+ }
134
+ continue;
135
+ }
136
+ if (context.ownerFeedback &&
137
+ shouldContinueReview(await readDocument(options.fs, options.docPath))) {
138
+ const superintendentResult = await executeSuperintendent(options, context);
139
+ if (superintendentResult.transition?.action !== "request_review") {
140
+ throw new Error("Superintendent must call request_review to continue a review exchange");
141
+ }
142
+ context = {
143
+ ...context,
144
+ superintendentSummary: superintendentResult.summary,
145
+ ...(superintendentResult.log_path
146
+ ? { superintendentLogPath: superintendentResult.log_path }
147
+ : {}),
148
+ ownerFeedback: undefined
149
+ };
150
+ await writeLoopState(options.fs, options.docPath, state);
151
+ {
152
+ const stopReason = readInterruptionReason(options, state);
153
+ if (stopReason) {
154
+ return finishLoop(options.callbacks, state, stopReason);
155
+ }
156
+ }
157
+ continue;
158
+ }
159
+ options.callbacks.onOwnerStart?.();
160
+ const ownerSnapshot = await readDocumentContent(options.fs, options.docPath);
161
+ let ownerResult;
162
+ try {
163
+ ownerResult = await options.runners.ownerReview(await readDocument(options.fs, options.docPath), createTemplateContext(context), buildRoleOptions(options, "owner"));
164
+ }
165
+ catch (error) {
166
+ await restoreDocument(options.fs, options.docPath, ownerSnapshot);
167
+ throw toError(error);
168
+ }
169
+ options.callbacks.onOwnerComplete?.(ownerResult);
170
+ if (ownerResult.transition.action === "approve_completion") {
171
+ context = {
172
+ ...context,
173
+ ...(ownerResult.log_path ? { ownerLogPath: ownerResult.log_path } : {})
174
+ };
175
+ state = {
176
+ ...state,
177
+ state: "completed"
178
+ };
179
+ }
180
+ else {
181
+ context = {
182
+ ...context,
183
+ ownerFeedback: ownerResult.transition.feedback,
184
+ ...(ownerResult.log_path ? { ownerLogPath: ownerResult.log_path } : {})
185
+ };
186
+ state = applyOwnerFeedback(state, shouldContinueReview(await readDocument(options.fs, options.docPath)));
187
+ }
188
+ emitStateChange(options.callbacks, state);
189
+ await writeLoopState(options.fs, options.docPath, state);
190
+ if (state.state !== "review") {
191
+ options.callbacks.onRoundComplete?.(state.round);
192
+ }
193
+ {
194
+ const stopReason = readLoopStopReason(options, state);
195
+ if (stopReason) {
196
+ return finishLoop(options.callbacks, state, stopReason);
197
+ }
198
+ }
199
+ }
200
+ });
201
+ }
202
+ finally {
203
+ await releaseLock();
204
+ }
205
+ }
206
+ function normalizeOptions(input, callbacks) {
207
+ if (typeof input !== "string") {
208
+ return {
209
+ docPath: resolveWorkflowPath(input.docPath, input.cwd, input.homeDir),
210
+ cwd: input.cwd,
211
+ homeDir: input.homeDir,
212
+ fs: input.fs ?? createDefaultFs(),
213
+ callbacks: input.callbacks ?? {},
214
+ runners: resolveRunners(input.runners),
215
+ ...(input.runAgent ? { runAgent: input.runAgent } : {}),
216
+ ...(input.signal ? { signal: input.signal } : {}),
217
+ ...(input.logDir ? { logDir: input.logDir } : {})
218
+ };
219
+ }
220
+ const cwd = process.cwd();
221
+ const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? cwd;
222
+ return {
223
+ docPath: resolveWorkflowPath(input, cwd, homeDir),
224
+ cwd,
225
+ homeDir,
226
+ fs: createDefaultFs(),
227
+ callbacks: callbacks ?? {},
228
+ runners: resolveRunners()
229
+ };
230
+ }
231
+ function resolveRunners(overrides) {
232
+ return {
233
+ builder: overrides?.builder ?? runBuilder,
234
+ inspector: overrides?.inspector ?? runInspector,
235
+ superintendent: overrides?.superintendent ?? runSuperintendent,
236
+ ownerReview: overrides?.ownerReview ?? runOwnerReview
237
+ };
238
+ }
239
+ function createDefaultFs() {
240
+ const fs = {
241
+ readFile: fsPromises.readFile,
242
+ writeFile: fsPromises.writeFile,
243
+ readdir: fsPromises.readdir,
244
+ open: (filePath, flags) => fsPromises.open(filePath, flags),
245
+ stat: async (filePath) => {
246
+ const stat = await fsPromises.stat(filePath);
247
+ return {
248
+ isFile: () => stat.isFile(),
249
+ isDirectory: () => stat.isDirectory(),
250
+ mtimeMs: stat.mtimeMs
251
+ };
252
+ },
253
+ unlink: async (filePath) => {
254
+ await fsPromises.unlink(filePath);
255
+ },
256
+ mkdir: async (filePath, options) => {
257
+ await fsPromises.mkdir(filePath, options);
258
+ },
259
+ rmdir: async (filePath) => {
260
+ await fsPromises.rmdir(filePath);
261
+ },
262
+ rename: async (oldPath, newPath) => {
263
+ await fsPromises.rename(oldPath, newPath);
264
+ }
265
+ };
266
+ return fs;
267
+ }
268
+ async function readDocument(fs, docPath) {
269
+ const content = await readDocumentContent(fs, docPath);
270
+ return parseSuperintendentDoc(docPath, content);
271
+ }
272
+ async function readDocumentContent(fs, docPath) {
273
+ return fs.readFile(docPath, "utf8");
274
+ }
275
+ async function writeLoopState(fs, docPath, state) {
276
+ const content = await fs.readFile(docPath, "utf8");
277
+ const updatedContent = updateStatus(docPath, content, {
278
+ state: state.state,
279
+ round: state.round,
280
+ review_turn: state.reviewTurn
281
+ });
282
+ await fs.writeFile(docPath, updatedContent, { encoding: "utf8" });
283
+ }
284
+ async function restoreDocument(fs, docPath, content) {
285
+ await fs.writeFile(docPath, content, { encoding: "utf8" });
286
+ }
287
+ async function rollbackRoundStatus(options, state) {
288
+ await writeLoopState(options.fs, options.docPath, state);
289
+ emitStateChange(options.callbacks, state);
290
+ return state;
291
+ }
292
+ function createTemplateContext(context) {
293
+ return {
294
+ ...(context.builder ? { builder: context.builder } : {}),
295
+ inspectors: { ...context.inspectors },
296
+ inspector_logs: { ...context.inspectorLogs },
297
+ ...(context.superintendentSummary
298
+ ? {
299
+ superintendent: {
300
+ summary: context.superintendentSummary,
301
+ ...(context.superintendentLogPath ? { log_path: context.superintendentLogPath } : {})
302
+ }
303
+ }
304
+ : {}),
305
+ ...(context.ownerFeedback
306
+ ? {
307
+ owner: {
308
+ feedback: context.ownerFeedback,
309
+ ...(context.ownerLogPath ? { log_path: context.ownerLogPath } : {})
310
+ }
311
+ }
312
+ : {})
313
+ };
314
+ }
315
+ function beginRound(state) {
316
+ return {
317
+ ...state,
318
+ state: "in_progress",
319
+ round: state.round + 1,
320
+ reviewTurn: 0
321
+ };
322
+ }
323
+ function applyOwnerFeedback(state, continueReview) {
324
+ const nextReviewTurn = state.reviewTurn + 1;
325
+ if (continueReview && nextReviewTurn < state.maxReviewTurns) {
326
+ return {
327
+ ...state,
328
+ state: "review",
329
+ reviewTurn: nextReviewTurn
330
+ };
331
+ }
332
+ return {
333
+ ...state,
334
+ state: "in_progress",
335
+ reviewTurn: 0
336
+ };
337
+ }
338
+ async function executeSuperintendent(options, context) {
339
+ options.callbacks.onSuperintendentStart?.();
340
+ const snapshot = await readDocumentContent(options.fs, options.docPath);
341
+ try {
342
+ const doc = await readDocument(options.fs, options.docPath);
343
+ const result = await options.runners.superintendent(doc, createTemplateContext(context), buildRoleOptions(options, "superintendent"));
344
+ options.callbacks.onSuperintendentComplete?.(result);
345
+ return result;
346
+ }
347
+ catch (error) {
348
+ await restoreDocument(options.fs, options.docPath, snapshot);
349
+ throw toError(error);
350
+ }
351
+ }
352
+ function buildRoleOptions(options, role) {
353
+ return {
354
+ defaultCwd: options.cwd,
355
+ ...(options.logDir ? { logPath: path.join(options.logDir, makeRunLogFileName(role)) } : {})
356
+ };
357
+ }
358
+ function shouldContinueReview(doc) {
359
+ return parseTaskBoard(doc.body).allDone;
360
+ }
361
+ function emitStateChange(callbacks, state) {
362
+ callbacks.onStateChange?.({ ...state });
363
+ }
364
+ function readLoopStopReason(options, state) {
365
+ if (state.state === "completed") {
366
+ return "completed";
367
+ }
368
+ if (state.state === "in_progress" && state.round >= state.maxRounds) {
369
+ return "max_rounds";
370
+ }
371
+ return readInterruptionReason(options, state);
372
+ }
373
+ function readInterruptionReason(options, _state) {
374
+ if (options.signal?.aborted) {
375
+ return "aborted";
376
+ }
377
+ if (options.callbacks.shouldStop?.() === true) {
378
+ return "stopped";
379
+ }
380
+ if (options.callbacks.shouldPause?.() === true) {
381
+ return "paused";
382
+ }
383
+ return undefined;
384
+ }
385
+ function finishLoop(callbacks, state, stopReason) {
386
+ const snapshot = {
387
+ ...state,
388
+ stopReason
389
+ };
390
+ callbacks.onLoopComplete?.(snapshot);
391
+ return snapshot;
392
+ }
393
+ function toError(error) {
394
+ return error instanceof Error ? error : new Error(String(error));
395
+ }
396
+ function filterAutoRunInspectors(doc) {
397
+ const inspectors = doc.frontmatter.inspectors ?? {};
398
+ const configuredNames = new Set(Object.keys(inspectors));
399
+ const selected = new Set();
400
+ const queue = [...collectReferencedInspectors(doc.frontmatter.superintendent.prompt)].filter((name) => configuredNames.has(name));
401
+ while (queue.length > 0) {
402
+ const name = queue.shift();
403
+ if (selected.has(name)) {
404
+ continue;
405
+ }
406
+ selected.add(name);
407
+ const inspectorPrompt = inspectors[name]?.prompt ?? "";
408
+ for (const referenced of collectReferencedInspectors(inspectorPrompt)) {
409
+ if (configuredNames.has(referenced) && !selected.has(referenced)) {
410
+ queue.push(referenced);
411
+ }
412
+ }
413
+ }
414
+ return Object.entries(inspectors).filter(([name]) => selected.has(name));
415
+ }
416
+ async function withInjectedAgentRunner(options, operation) {
417
+ if (!options.runAgent) {
418
+ return operation();
419
+ }
420
+ const spawnApi = spawn;
421
+ const originalAutonomous = spawnApi.autonomous;
422
+ spawnApi.autonomous = async (agent, input) => {
423
+ const result = await options.runAgent?.({
424
+ agent,
425
+ prompt: input.prompt,
426
+ cwd: input.cwd ?? process.cwd(),
427
+ ...(input.mode ? { mode: input.mode } : {}),
428
+ ...(input.mcpServers ? { mcpServers: input.mcpServers } : {}),
429
+ ...(input.logPath ? { logPath: input.logPath } : {}),
430
+ ...(options.signal ? { signal: options.signal } : {})
431
+ });
432
+ if (!result) {
433
+ throw new Error(`Agent \`${agent}\` returned no result.`);
434
+ }
435
+ if (result.exitCode !== 0) {
436
+ throw new Error(result.stderr || result.stdout || `Agent \`${agent}\` failed with exit code ${result.exitCode}`);
437
+ }
438
+ return result;
439
+ };
440
+ try {
441
+ return await operation();
442
+ }
443
+ finally {
444
+ spawnApi.autonomous = originalAutonomous;
445
+ }
446
+ }
@@ -0,0 +1,2 @@
1
+ import type { AgentRoleConfig } from "../document/parse.js";
2
+ export declare function resolveRoleCwd(role: AgentRoleConfig, docPath: string, defaultCwd: string): string;
@@ -0,0 +1,10 @@
1
+ import path from "node:path";
2
+ export function resolveRoleCwd(role, docPath, defaultCwd) {
3
+ if (role.cwd === undefined) {
4
+ return defaultCwd;
5
+ }
6
+ if (path.isAbsolute(role.cwd)) {
7
+ return role.cwd;
8
+ }
9
+ return path.resolve(path.dirname(docPath), role.cwd);
10
+ }
@@ -0,0 +1,13 @@
1
+ import type { SuperintendentDoc } from "../document/parse.js";
2
+ import { type TemplateContext } from "./templates.js";
3
+ export type BuilderResult = {
4
+ summary: string;
5
+ log: string;
6
+ log_path: string;
7
+ };
8
+ export type RunBuilderOptions = {
9
+ promptOverride?: string;
10
+ defaultCwd: string;
11
+ logPath?: string;
12
+ };
13
+ export declare function runBuilder(doc: SuperintendentDoc, context: Partial<TemplateContext>, options: RunBuilderOptions): Promise<BuilderResult>;
@@ -0,0 +1,102 @@
1
+ import { spawn } from "@poe-code/agent-spawn";
2
+ import { resolveRoleCwd } from "./resolve-cwd.js";
3
+ import { resolveTemplate } from "./templates.js";
4
+ export async function runBuilder(doc, context, options) {
5
+ const prompt = options.promptOverride ??
6
+ resolveTemplate(doc.frontmatter.builder.prompt, buildTemplateContext(doc, context));
7
+ const result = await runAutonomous({
8
+ agent: doc.frontmatter.builder.agent,
9
+ mode: doc.frontmatter.builder.mode,
10
+ prompt,
11
+ cwd: resolveRoleCwd(doc.frontmatter.builder, doc.filePath, options.defaultCwd),
12
+ mcpServers: buildMcpServers(doc),
13
+ ...(options.logPath ? { logPath: options.logPath } : {})
14
+ });
15
+ const log = extractLog(result);
16
+ return {
17
+ summary: extractSummary(result, log),
18
+ log,
19
+ log_path: extractLogPath(result, options)
20
+ };
21
+ }
22
+ function buildMcpServers(doc) {
23
+ const merged = {
24
+ ...(doc.frontmatter.mcp ?? {}),
25
+ ...(doc.frontmatter.builder.mcp ?? {})
26
+ };
27
+ if (Object.keys(merged).length === 0) {
28
+ return undefined;
29
+ }
30
+ const servers = {};
31
+ for (const [name, config] of Object.entries(merged)) {
32
+ servers[name] = {
33
+ command: config.command,
34
+ ...(config.args ? { args: [...config.args] } : {}),
35
+ ...(config.timeout !== undefined ? { timeout: config.timeout } : {})
36
+ };
37
+ }
38
+ return servers;
39
+ }
40
+ function buildTemplateContext(doc, context) {
41
+ return {
42
+ ...context,
43
+ plan: {
44
+ ...(context.plan ?? { path: doc.filePath }),
45
+ path: doc.filePath
46
+ }
47
+ };
48
+ }
49
+ async function runAutonomous(input) {
50
+ const spawnApi = spawn;
51
+ if (typeof spawnApi.autonomous === "function") {
52
+ return spawnApi.autonomous(input.agent, {
53
+ cwd: input.cwd,
54
+ prompt: input.prompt,
55
+ mode: input.mode,
56
+ ...(input.mcpServers ? { mcpServers: input.mcpServers } : {}),
57
+ ...(input.logPath ? { logPath: input.logPath } : {})
58
+ });
59
+ }
60
+ const result = await spawn(input.agent, {
61
+ cwd: input.cwd,
62
+ prompt: input.prompt,
63
+ mode: input.mode,
64
+ ...(input.mcpServers ? { mcpServers: input.mcpServers } : {}),
65
+ ...(input.logPath ? { logPath: input.logPath } : {})
66
+ });
67
+ return {
68
+ stdout: result.stdout,
69
+ ...(result.logFile ? { logFile: result.logFile } : {})
70
+ };
71
+ }
72
+ function extractLog(result) {
73
+ if (typeof result === "string") {
74
+ return result;
75
+ }
76
+ return readString(result.log) ?? readString(result.output) ?? readString(result.stdout) ?? readString(result.text) ?? "";
77
+ }
78
+ function extractLogPath(result, options) {
79
+ if (typeof result !== "string") {
80
+ const logFile = readString(result.logFile);
81
+ if (logFile) {
82
+ return logFile;
83
+ }
84
+ }
85
+ return options.logPath ?? "";
86
+ }
87
+ function extractSummary(result, log) {
88
+ if (typeof result !== "string") {
89
+ const explicitSummary = readString(result.summary)?.trim();
90
+ if (explicitSummary) {
91
+ return explicitSummary;
92
+ }
93
+ }
94
+ const firstNonEmptyLine = log
95
+ .split("\n")
96
+ .map((line) => (line.endsWith("\r") ? line.slice(0, -1) : line).trim())
97
+ .find((line) => line.length > 0);
98
+ return firstNonEmptyLine ?? "Builder completed without output.";
99
+ }
100
+ function readString(value) {
101
+ return typeof value === "string" ? value : undefined;
102
+ }
@@ -0,0 +1,16 @@
1
+ import type { AgentRoleConfig, SuperintendentDoc } from "../document/parse.js";
2
+ import { type TemplateContext } from "./templates.js";
3
+ export type InspectorResult = {
4
+ name: string;
5
+ summary: string;
6
+ log_path?: string;
7
+ };
8
+ export type RunInspectorOptions = {
9
+ promptOverride?: string;
10
+ defaultCwd: string;
11
+ logPath?: string;
12
+ };
13
+ export declare function runInspector(name: string, config: AgentRoleConfig, doc: SuperintendentDoc, context: Partial<TemplateContext>, options: RunInspectorOptions): Promise<InspectorResult>;
14
+ export declare function runAllInspectors(doc: SuperintendentDoc, context: Partial<TemplateContext>, options: {
15
+ defaultCwd: string;
16
+ }): Promise<InspectorResult[]>;