@runfusion/fusion 0.2.6 → 0.3.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.
- package/dist/bin.js +8488 -6999
- package/dist/client/assets/{AgentDetailView-BMrHuWGs.css → AgentDetailView-C1b9PC5l.css} +1 -1
- package/dist/client/assets/{AgentDetailView-CBdzWtd-.js → AgentDetailView-CJIxNRq-.js} +3 -3
- package/dist/client/assets/{AgentsView-DPlnCa_B.js → AgentsView-BS17exn3.js} +5 -5
- package/dist/client/assets/ChatView-BUlq3WNJ.js +1 -0
- package/dist/client/assets/{DevServerView-BY5cGz23.js → DevServerView-qMPpnXRb.js} +2 -2
- package/dist/client/assets/DirectoryPicker-CTwgv9LY.js +1 -0
- package/dist/client/assets/DirectoryPicker-DzKVmxOf.css +1 -0
- package/dist/client/assets/{DocumentsView-lQwJmc4G.js → DocumentsView-DOz1KFGN.js} +1 -1
- package/dist/client/assets/{InsightsView-DUiZZ0z8.js → InsightsView-CHZTJUic.js} +2 -2
- package/dist/client/assets/MemoryView-V0QdeO3e.js +2 -0
- package/dist/client/assets/{NodesView-DgyM-ktg.js → NodesView-BtGNRj2z.js} +1 -1
- package/dist/client/assets/PiExtensionsManager-D9Ye2Vak.js +11 -0
- package/dist/client/assets/PiExtensionsManager-kgTOHPE9.css +1 -0
- package/dist/client/assets/PluginManager-DRiIqol2.css +1 -0
- package/dist/client/assets/PluginManager-LeHp0jJ_.js +1 -0
- package/dist/client/assets/{RoadmapsView-ANn2jmsU.js → RoadmapsView-C413ISVU.js} +2 -2
- package/dist/client/assets/SettingsModal--vWmKBpT.css +1 -0
- package/dist/client/assets/SettingsModal-BZLL2xAP.js +31 -0
- package/dist/client/assets/SettingsModal-CDWvhvrd.css +1 -0
- package/dist/client/assets/SettingsModal-olTBmYJs.js +1 -0
- package/dist/client/assets/SetupWizardModal-BMa6p24b.css +1 -0
- package/dist/client/assets/{SetupWizardModal-UxlAtKWA.js → SetupWizardModal-WdaR2eQQ.js} +1 -1
- package/dist/client/assets/SkillsView-BcE57w8i.js +1 -0
- package/dist/client/assets/{folder-open-J7yPbaCt.js → folder-open-Ec4hU1xL.js} +1 -1
- package/dist/client/assets/index-CCYdhck-.js +616 -0
- package/dist/client/assets/index-lJ5WOmO9.css +1 -0
- package/dist/client/assets/{upload-B_grq4hM.js → upload-BksRDuGJ.js} +1 -1
- package/dist/client/assets/users-EFU4n9Qr.js +6 -0
- package/dist/client/index.html +2 -2
- package/dist/extension.js +1271 -205
- package/dist/pi-claude-cli/index.ts +72 -28
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/pi-claude-cli/src/__tests__/event-bridge.test.ts +34 -0
- package/dist/pi-claude-cli/src/__tests__/mcp-config.test.ts +22 -0
- package/dist/pi-claude-cli/src/__tests__/prompt-builder.test.ts +72 -10
- package/dist/pi-claude-cli/src/__tests__/provider.test.ts +9 -9
- package/dist/pi-claude-cli/src/event-bridge.ts +17 -6
- package/dist/pi-claude-cli/src/mcp-config.ts +36 -3
- package/dist/pi-claude-cli/src/prompt-builder.ts +111 -7
- package/dist/pi-claude-cli/src/provider.ts +18 -2
- package/package.json +6 -5
- package/skill/fusion/SKILL.md +6 -1
- package/skill/fusion/references/engine-tools.md +54 -0
- package/skill/fusion/references/extension-tools.md +83 -84
- package/skill/fusion/references/fusion-capabilities.md +33 -31
- package/dist/client/assets/ChatView-BXzYysNG.js +0 -1
- package/dist/client/assets/DirectoryPicker-DZ90eSBn.js +0 -1
- package/dist/client/assets/MemoryView-DvSmMN6G.js +0 -2
- package/dist/client/assets/PiExtensionsManager-K7HQ08L4.css +0 -1
- package/dist/client/assets/PiExtensionsManager-wxB-q06A.js +0 -11
- package/dist/client/assets/PluginManager-LH02ybSH.js +0 -1
- package/dist/client/assets/PluginManager-tCFMZMLL.css +0 -1
- package/dist/client/assets/SkillsView-DEjGh7wW.js +0 -1
- package/dist/client/assets/index-BdJsO65L.css +0 -1
- package/dist/client/assets/index-CHoVMPAA.js +0 -649
|
@@ -23,7 +23,20 @@ export interface PiMessage {
|
|
|
23
23
|
content: string | unknown[];
|
|
24
24
|
toolName?: string;
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Minimal pi-ai Tool shape — the subset we read from `Context.tools` to build
|
|
28
|
+
* the deferred-tools system-prompt addendum.
|
|
29
|
+
*/
|
|
30
|
+
export interface PiToolLike {
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type PiContext = {
|
|
36
|
+
systemPrompt?: string;
|
|
37
|
+
messages: PiMessage[];
|
|
38
|
+
tools?: ReadonlyArray<PiToolLike>;
|
|
39
|
+
};
|
|
27
40
|
import {
|
|
28
41
|
mapPiToolNameToClaude,
|
|
29
42
|
translatePiArgsToClaude,
|
|
@@ -49,7 +62,7 @@ type AnthropicContentBlock =
|
|
|
49
62
|
* Each message is labeled with its role:
|
|
50
63
|
* - USER: for user messages
|
|
51
64
|
* - ASSISTANT: for assistant messages
|
|
52
|
-
* - TOOL RESULT (
|
|
65
|
+
* - TOOL RESULT ({toolName}): for tool result messages
|
|
53
66
|
*/
|
|
54
67
|
/** Module-level counter for placeholder images, reset per buildPrompt call. */
|
|
55
68
|
let placeholderImageCount = 0;
|
|
@@ -200,7 +213,7 @@ export function buildResumePrompt(context: PiContext): string | AnthropicContent
|
|
|
200
213
|
const claudeToolName = msg.toolName
|
|
201
214
|
? mapPiToolNameToClaude(msg.toolName)
|
|
202
215
|
: "unknown";
|
|
203
|
-
parts.push(`TOOL RESULT (
|
|
216
|
+
parts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
204
217
|
}
|
|
205
218
|
parts.push(toolResultContentToText(msg.content));
|
|
206
219
|
} else if (msg.role === "user") {
|
|
@@ -270,7 +283,7 @@ export function buildPrompt(context: PiContext): string | AnthropicContentBlock[
|
|
|
270
283
|
const claudeToolName = message.toolName
|
|
271
284
|
? mapPiToolNameToClaude(message.toolName)
|
|
272
285
|
: "unknown";
|
|
273
|
-
historyParts.push(`TOOL RESULT (
|
|
286
|
+
historyParts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
274
287
|
}
|
|
275
288
|
// Extract text portion of tool result
|
|
276
289
|
historyParts.push(toolResultContentToText(message.content));
|
|
@@ -334,7 +347,7 @@ export function buildPrompt(context: PiContext): string | AnthropicContentBlock[
|
|
|
334
347
|
const claudeToolName = message.toolName
|
|
335
348
|
? mapPiToolNameToClaude(message.toolName)
|
|
336
349
|
: "unknown";
|
|
337
|
-
parts.push(`TOOL RESULT (
|
|
350
|
+
parts.push(`TOOL RESULT (${claudeToolName}):`);
|
|
338
351
|
}
|
|
339
352
|
parts.push(toolResultContentToText(message.content));
|
|
340
353
|
}
|
|
@@ -372,7 +385,7 @@ export function buildSystemPrompt(
|
|
|
372
385
|
const parts: string[] = [];
|
|
373
386
|
|
|
374
387
|
if (context.systemPrompt) {
|
|
375
|
-
parts.push(context.systemPrompt);
|
|
388
|
+
parts.push(rewriteCustomToolReferences(context.systemPrompt, context.tools));
|
|
376
389
|
}
|
|
377
390
|
|
|
378
391
|
// Look for AGENTS.md
|
|
@@ -396,9 +409,100 @@ export function buildSystemPrompt(
|
|
|
396
409
|
);
|
|
397
410
|
}
|
|
398
411
|
|
|
412
|
+
const customToolsAddendum = buildCustomToolsAddendum(context.tools);
|
|
413
|
+
if (customToolsAddendum) {
|
|
414
|
+
parts.push(customToolsAddendum);
|
|
415
|
+
}
|
|
416
|
+
|
|
399
417
|
return parts.join("\n\n");
|
|
400
418
|
}
|
|
401
419
|
|
|
420
|
+
/** Pi built-in tool names — these go through pi's wrapped built-ins, not MCP. */
|
|
421
|
+
const BUILT_IN_PI_TOOLS = new Set([
|
|
422
|
+
"read",
|
|
423
|
+
"write",
|
|
424
|
+
"edit",
|
|
425
|
+
"bash",
|
|
426
|
+
"grep",
|
|
427
|
+
"find",
|
|
428
|
+
"ls",
|
|
429
|
+
]);
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Rewrite bare references to custom pi tool names (e.g. `fn_review_spec`,
|
|
433
|
+
* `fn_review_spec()`) in the system prompt so they appear as their
|
|
434
|
+
* MCP-prefixed names (`mcp__custom-tools__fn_review_spec`). Engine prompts are
|
|
435
|
+
* written for direct API tool calls; under pi-claude-cli the same tools are
|
|
436
|
+
* reachable only through the MCP shim. Without this rewrite, models like
|
|
437
|
+
* Sonnet 4.6 inconsistently translate the names — sometimes calling MCP
|
|
438
|
+
* variants, sometimes silently skipping the call (observed in triage where
|
|
439
|
+
* `fn_review_spec` was never invoked even though the prompt said "MUST call").
|
|
440
|
+
*
|
|
441
|
+
* Only rewrites whole-word matches anchored to a non-identifier boundary, so
|
|
442
|
+
* substrings inside other identifiers stay intact. Skips already-prefixed
|
|
443
|
+
* occurrences (`mcp__custom-tools__fn_review_spec`) and pi built-ins.
|
|
444
|
+
*/
|
|
445
|
+
function rewriteCustomToolReferences(
|
|
446
|
+
prompt: string,
|
|
447
|
+
tools: ReadonlyArray<PiToolLike> | undefined,
|
|
448
|
+
): string {
|
|
449
|
+
if (!prompt || !tools || tools.length === 0) {
|
|
450
|
+
return prompt;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
let result = prompt;
|
|
454
|
+
for (const tool of tools) {
|
|
455
|
+
if (BUILT_IN_PI_TOOLS.has(tool.name)) continue;
|
|
456
|
+
// \b doesn't treat `_` as a word boundary the way we want here, so anchor
|
|
457
|
+
// the match between either start-of-string/non-identifier-char and either
|
|
458
|
+
// end-of-string/non-identifier-char. Also negative-lookbehind for
|
|
459
|
+
// `mcp__custom-tools__` so we don't double-prefix.
|
|
460
|
+
const escaped = tool.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
461
|
+
const pattern = new RegExp(
|
|
462
|
+
`(?<![A-Za-z0-9_])(?<!mcp__custom-tools__)${escaped}(?![A-Za-z0-9_])`,
|
|
463
|
+
"g",
|
|
464
|
+
);
|
|
465
|
+
result = result.replace(pattern, `mcp__custom-tools__${tool.name}`);
|
|
466
|
+
}
|
|
467
|
+
return result;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Build a system-prompt addendum that maps each custom pi tool to its
|
|
472
|
+
* MCP-exposed name (`mcp__custom-tools__<name>`) and explains Claude Code's
|
|
473
|
+
* deferred-tool protocol. Without this, the model sees instructions like
|
|
474
|
+
* "call fn_review_spec()" but only finds `mcp__custom-tools__fn_review_spec`
|
|
475
|
+
* via ToolSearch — and may report "tool not found" or skip the call.
|
|
476
|
+
*
|
|
477
|
+
* Returns an empty string when there are no custom tools so the addendum
|
|
478
|
+
* doesn't pollute prompts on plain chat sessions with only built-ins.
|
|
479
|
+
*/
|
|
480
|
+
function buildCustomToolsAddendum(
|
|
481
|
+
tools: ReadonlyArray<PiToolLike> | undefined,
|
|
482
|
+
): string {
|
|
483
|
+
if (!tools || tools.length === 0) return "";
|
|
484
|
+
const customNames = tools
|
|
485
|
+
.map((t) => t.name)
|
|
486
|
+
.filter((name) => !BUILT_IN_PI_TOOLS.has(name));
|
|
487
|
+
if (customNames.length === 0) return "";
|
|
488
|
+
|
|
489
|
+
const lines = customNames
|
|
490
|
+
.sort()
|
|
491
|
+
.map((name) => `- \`${name}\` is exposed as \`mcp__custom-tools__${name}\``);
|
|
492
|
+
|
|
493
|
+
return [
|
|
494
|
+
"## Custom tool naming (Claude Code deferred-tools protocol)",
|
|
495
|
+
"",
|
|
496
|
+
"The following pi extension tools are available, but Claude Code exposes",
|
|
497
|
+
"them under MCP-prefixed names. When a system prompt or task instruction",
|
|
498
|
+
"asks you to call one of these by its short name, use the MCP-prefixed",
|
|
499
|
+
"name instead. Their schemas are deferred — call `ToolSearch` with",
|
|
500
|
+
'`select:mcp__custom-tools__<name>` first, then call the tool directly.',
|
|
501
|
+
"",
|
|
502
|
+
...lines,
|
|
503
|
+
].join("\n");
|
|
504
|
+
}
|
|
505
|
+
|
|
402
506
|
/**
|
|
403
507
|
* Converts user message content to text.
|
|
404
508
|
* Handles string content and array of content blocks.
|
|
@@ -462,7 +566,7 @@ function contentToText(content: string | unknown[]): string {
|
|
|
462
566
|
: typeof rawArgs === "string"
|
|
463
567
|
? JSON.stringify(rawArgs)
|
|
464
568
|
: "{}";
|
|
465
|
-
return `
|
|
569
|
+
return `[Prior tool call — already executed; result follows in TOOL RESULT (${claudeName}):] args=${argsStr}`;
|
|
466
570
|
}
|
|
467
571
|
// Unknown block types are represented as a placeholder
|
|
468
572
|
return `[${String(block.type)}]`;
|
|
@@ -44,8 +44,23 @@ import { createEventBridge } from "./event-bridge.js";
|
|
|
44
44
|
import { handleControlRequest } from "./control-handler.js";
|
|
45
45
|
import { mapThinkingEffort } from "./thinking-config.js";
|
|
46
46
|
import { isPiKnownClaudeTool } from "./tool-mapping.js";
|
|
47
|
-
/**
|
|
48
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Inactivity safety net for the Claude CLI subprocess.
|
|
49
|
+
*
|
|
50
|
+
* Set very high (30 minutes) because the caller is the authoritative source of
|
|
51
|
+
* truth for "this session is stuck": Fusion's engine runs a `StuckTaskDetector`
|
|
52
|
+
* with a configurable heartbeat (default 1 hour) and aborts the session via
|
|
53
|
+
* `AbortSignal` when it decides the agent has gone quiet. pi-claude-cli already
|
|
54
|
+
* forwards that signal to the subprocess (`forceKillProcess` on `signal.abort`).
|
|
55
|
+
*
|
|
56
|
+
* A short timeout here was racing the engine: Sonnet 4.6 with extended thinking
|
|
57
|
+
* on the triage prompt (~40k chars) routinely goes >3 minutes between thinking
|
|
58
|
+
* deltas, and we were killing those subprocesses before they could write
|
|
59
|
+
* PROMPT.md and call `fn_review_spec`. The half-hour ceiling is just a
|
|
60
|
+
* last-resort guard for catastrophically hung processes when no abort signal
|
|
61
|
+
* arrives (e.g. someone embeds pi-claude-cli without a stuck detector).
|
|
62
|
+
*/
|
|
63
|
+
const INACTIVITY_TIMEOUT_MS = 30 * 60_000;
|
|
49
64
|
|
|
50
65
|
/** Extended stream options: pi's SimpleStreamOptions plus optional cwd and mcpConfigPath */
|
|
51
66
|
type StreamViaCLiOptions = SimpleStreamOptions & {
|
|
@@ -120,6 +135,7 @@ export function streamViaCli(
|
|
|
120
135
|
newSessionId: !resumeSessionId ? options?.sessionId : undefined,
|
|
121
136
|
});
|
|
122
137
|
const getStderr = captureStderr(proc);
|
|
138
|
+
const spawnTime = Date.now();
|
|
123
139
|
|
|
124
140
|
// Register in global process registry for teardown cleanup
|
|
125
141
|
registerProcess(proc);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|
|
@@ -75,10 +75,10 @@
|
|
|
75
75
|
"typescript": "^5.7.0",
|
|
76
76
|
"vitest": "^3.1.0",
|
|
77
77
|
"yaml": "^2.8.3",
|
|
78
|
-
"@fusion/core": "0.
|
|
79
|
-
"@fusion/
|
|
80
|
-
"@fusion/
|
|
81
|
-
"@fusion/pi-claude-cli": "0.
|
|
78
|
+
"@fusion/core": "0.3.0",
|
|
79
|
+
"@fusion/engine": "0.3.0",
|
|
80
|
+
"@fusion/dashboard": "0.3.0",
|
|
81
|
+
"@fusion/pi-claude-cli": "0.3.0"
|
|
82
82
|
},
|
|
83
83
|
"repository": {
|
|
84
84
|
"type": "git",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
},
|
|
87
87
|
"scripts": {
|
|
88
88
|
"dev": "tsx src/bin.ts",
|
|
89
|
+
"prebuild": "node ../../scripts/sync-fusion-skill-tools.mjs",
|
|
89
90
|
"build": "tsup",
|
|
90
91
|
"build:exe": "bun run build.ts",
|
|
91
92
|
"build:exe:all": "bun run build.ts --all",
|
package/skill/fusion/SKILL.md
CHANGED
|
@@ -21,14 +21,18 @@ Mission → Milestone → Slice → Feature → Task
|
|
|
21
21
|
|
|
22
22
|
**Available tools:** Fusion registers tools via the pi extension (prefixed `fn_*`). No CLI commands or Bash needed — use the registered tools directly.
|
|
23
23
|
|
|
24
|
-
**Naming boundary:** The published skill surface
|
|
24
|
+
**Naming boundary:** The published pi-extension skill surface uses `fn_*` tool names (for example `fn_task_create`, `fn_mission_create`). Engine runtime sessions also inject additional `fn_*` tools (for example `fn_review_spec`, `fn_review_step`, `fn_spawn_agent`) that are not user-invokable extension tools.
|
|
25
|
+
|
|
26
|
+
**Engine runtime tools:** Triage/executor/merger/heartbeat sessions include auto-injected engine tools that do not come from the pi extension registration list. See `references/engine-tools.md` for the canonical runtime-only catalog and usage boundaries.
|
|
25
27
|
|
|
26
28
|
**Tool categories:**
|
|
29
|
+
<!-- BEGIN: tool-categories (auto-generated by scripts/sync-fusion-skill-tools.mjs — do not edit by hand) -->
|
|
27
30
|
- **Task tools** — `fn_task_create`, `fn_task_update`, `fn_task_list`, `fn_task_show`, `fn_task_attach`, `fn_task_pause`, `fn_task_unpause`, `fn_task_retry`, `fn_task_duplicate`, `fn_task_refine`, `fn_task_archive`, `fn_task_unarchive`, `fn_task_delete`, `fn_task_plan`
|
|
28
31
|
- **GitHub tools** — `fn_task_import_github`, `fn_task_import_github_issue`, `fn_task_browse_github_issues`
|
|
29
32
|
- **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_delete`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_slice_activate`, `fn_feature_link_task`
|
|
30
33
|
- **Agent tools** — `fn_agent_stop`, `fn_agent_start`
|
|
31
34
|
- **Skills tools** — `fn_skills_search`, `fn_skills_install`
|
|
35
|
+
<!-- END: tool-categories -->
|
|
32
36
|
- **Dashboard** — Use `/fn` command to start/stop the dashboard
|
|
33
37
|
|
|
34
38
|
</essential_principles>
|
|
@@ -100,6 +104,7 @@ For these operations, guide the user to the dashboard (`/fn`) or CLI commands do
|
|
|
100
104
|
| references/extension-tools.md | All pi extension tools with parameters |
|
|
101
105
|
| references/best-practices.md | Tips for effective Fusion usage |
|
|
102
106
|
| references/fusion-capabilities.md | Complete feature catalog |
|
|
107
|
+
| references/engine-tools.md | Engine session-scoped runtime tools (not extension-invokable) |
|
|
103
108
|
| references/skill-patterns.md | Patterns used in this skill's design |
|
|
104
109
|
|
|
105
110
|
</reference_index>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Engine Session-Scoped Tools
|
|
2
|
+
|
|
3
|
+
These tools are **not** part of the pi extension's user-invokable `extension.ts` surface. They are injected by the engine at runtime for specific agent session types.
|
|
4
|
+
|
|
5
|
+
- Source files: `packages/engine/src/agent-tools.ts`, `triage.ts`, `executor.ts`, `merger.ts`, `agent-heartbeat.ts`
|
|
6
|
+
- Availability: only when the engine creates a session for the matching agent role
|
|
7
|
+
- Important: do not tell users to call these directly from the generic pi extension tool list
|
|
8
|
+
|
|
9
|
+
## Shared runtime tools (`agent-tools.ts`)
|
|
10
|
+
|
|
11
|
+
| Tool | Agent Types | Purpose | Parameters |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| `fn_task_create` | triage, executor, heartbeat | Create a follow-up task from within an agent run | `description` (string), `dependencies?` (string[]) |
|
|
14
|
+
| `fn_task_log` | executor, heartbeat | Write significant task log entries | `message` (string), `outcome?` (string) |
|
|
15
|
+
| `fn_task_document_write` | triage, executor, heartbeat | Save/update a named task document revision | `key` (string), `content` (string), `author?` (string) |
|
|
16
|
+
| `fn_task_document_read` | triage, executor, heartbeat | Read one task document or list all | `key?` (string) |
|
|
17
|
+
| `fn_memory_search` | triage, executor, heartbeat | Search project/agent memory snippets | `query` (string), `limit?` (number) |
|
|
18
|
+
| `fn_memory_get` | triage, executor, heartbeat | Read a bounded memory file window | `path` (string), `startLine?` (number), `lineCount?` (number) |
|
|
19
|
+
| `fn_memory_append` | executor, heartbeat (when writable backend enabled) | Append long-term/daily memory notes | `scope?` (`project` \| `agent`), `layer` (`long-term` \| `daily`), `content` (string) |
|
|
20
|
+
| `fn_reflect_on_performance` | executor | Generate reflection insights from prior runs | `focus_area?` (string) |
|
|
21
|
+
| `fn_list_agents` | triage, executor, heartbeat | List agents (optionally filtered) | `role?` (string), `state?` (string), `includeEphemeral?` (boolean) |
|
|
22
|
+
| `fn_delegate_task` | triage, executor, heartbeat | Create and assign a new task to a specific agent | `agent_id` (string), `description` (string), `dependencies?` (string[]) |
|
|
23
|
+
| `fn_send_message` | executor, heartbeat | Send inbox messages to agents/users | `to_id` (string), `content` (string), `type?` (`agent-to-agent` \| `agent-to-user`), `reply_to_message_id?` (string) |
|
|
24
|
+
| `fn_read_messages` | executor, heartbeat | Read inbox messages | `unread_only?` (boolean), `limit?` (number) |
|
|
25
|
+
|
|
26
|
+
## Triage-only runtime tools (`triage.ts`)
|
|
27
|
+
|
|
28
|
+
| Tool | Purpose | Parameters |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `fn_task_list` | List active tasks during specification (duplicate check, discovery) | none |
|
|
31
|
+
| `fn_task_get` | Fetch full task detail including PROMPT.md | `id` (string) |
|
|
32
|
+
| `fn_review_spec` | Spawn spec reviewer and return `APPROVE`/`REVISE`/`RETHINK`/`UNAVAILABLE` | none |
|
|
33
|
+
|
|
34
|
+
## Executor-only runtime tools (`executor.ts`)
|
|
35
|
+
|
|
36
|
+
| Tool | Purpose | Parameters |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `fn_task_update` | Update a spec step status (`pending`/`in-progress`/`done`/`skipped`) | `step` (number), `status` (enum) |
|
|
39
|
+
| `fn_task_add_dep` | Add a dependency to current task (confirmation-gated) | `task_id` (string), `confirm?` (boolean) |
|
|
40
|
+
| `fn_task_done` | Mark task complete and optionally store summary | `summary?` (string) |
|
|
41
|
+
| `fn_review_step` | Spawn step plan/code reviewer | `step` (number), `type` (`plan` \| `code`), `step_name` (string), `baseline?` (string) |
|
|
42
|
+
| `fn_spawn_agent` | Spawn child agent in separate worktree | `name` (string), `role` (enum), `task` (string) |
|
|
43
|
+
|
|
44
|
+
## Merger-only runtime tools (`merger.ts`)
|
|
45
|
+
|
|
46
|
+
| Tool | Purpose | Parameters |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `fn_report_build_failure` | Explicitly signal merge-time build verification failure | `message` (string) |
|
|
49
|
+
|
|
50
|
+
## Heartbeat-only runtime tools (`agent-heartbeat.ts`)
|
|
51
|
+
|
|
52
|
+
| Tool | Purpose | Parameters |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `fn_heartbeat_done` | Signal end of heartbeat run with optional summary | `summary?` (string) |
|