@selesai/code 0.5.29 → 0.6.2
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/CHANGELOG.md +34 -0
- package/README.md +1 -1
- package/dist/config.d.ts +16 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +106 -5
- package/dist/config.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +18 -0
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/system-prompt.test.d.ts +2 -0
- package/dist/core/system-prompt.test.d.ts.map +1 -0
- package/dist/core/system-prompt.test.js +89 -0
- package/dist/core/system-prompt.test.js.map +1 -0
- package/dist/defaults/models.json +13 -45
- package/dist/defaults/settings.json +5 -7
- package/dist/extensions/copy-turn.test.ts +131 -0
- package/dist/extensions/copy-turn.ts +6 -1
- package/dist/extensions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/dist/extensions/package.json +0 -1
- package/dist/extensions/pi-subagents/CHANGELOG.md +3 -0
- package/dist/extensions/pi-subagents/README.md +27 -32
- package/dist/extensions/pi-subagents/agents/architect.md +4 -4
- package/dist/extensions/pi-subagents/agents/builder.md +5 -4
- package/dist/extensions/pi-subagents/agents/commentator.md +3 -2
- package/dist/extensions/pi-subagents/agents/explorer.md +3 -2
- package/dist/extensions/pi-subagents/agents/recapper.md +3 -2
- package/dist/extensions/pi-subagents/agents/researcher.md +4 -3
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +10 -9
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +12 -11
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +10 -11
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +56 -9
- package/dist/extensions/pi-subagents/src/agents/task-aware-routing.ts +125 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +1 -1
- package/dist/extensions/pi-subagents/src/extension/index.ts +5 -1
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +2 -2
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +24 -7
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +23 -5
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +27 -1
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +64 -6
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +16 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +72 -18
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +19 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +127 -31
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +4 -6
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +63 -9
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +21 -0
- package/dist/extensions/pi-subagents/src/shared/types.ts +41 -2
- package/dist/extensions/pi-subagents/src/shared/utils.ts +29 -1
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +5 -1
- package/dist/extensions/pi-subagents/src/tui/render.ts +32 -6
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +111 -6
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +74 -43
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +36 -21
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +5 -3
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -8
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +14 -7
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +227 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +81 -5
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +49 -10
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +18 -2
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -6
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +161 -1
- package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +63 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +6 -1
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +29 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +2 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +12 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +91 -1
- package/dist/extensions/pi-subagents/test/unit/task-aware-routing.test.ts +213 -0
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +23 -1
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +60 -9
- package/dist/extensions/pi-web-agent/package.json +1 -1
- package/dist/skills/pi-subagents/SKILL.md +43 -0
- package/dist/skills/pi-subagents/references/constraints-and-recipes.md +257 -0
- package/dist/skills/pi-subagents/references/execution-controls.md +431 -0
- package/dist/skills/pi-subagents/references/management-authoring-rpc.md +144 -0
- package/dist/skills/pi-subagents/references/prompting-and-roles.md +281 -0
- package/dist/skills/ponytail/SKILL.md +1 -3
- package/docs/plans/subagent-delegation/phase-0-correctness.md +265 -0
- package/docs/plans/subagent-delegation/phase-1-behavioral-contract.md +486 -0
- package/docs/plans/subagent-delegation/phase-2-context-controls.md +282 -0
- package/docs/plans/subagent-delegation/phase-3-advisory-routing.md +362 -0
- package/docs/plans/subagent-delegation/phase-4-optional-enforcement.md +381 -0
- package/package.json +2 -2
- package/dist/extensions/caveman/caveman-instructions.cjs +0 -11
- package/dist/extensions/caveman/index.js +0 -118
- package/dist/extensions/caveman/package.json +0 -8
- package/dist/extensions/caveman/test/extension.test.js +0 -203
- package/dist/extensions/caveman/test/helpers.test.js +0 -58
- package/dist/skills/caveman/SKILL.md +0 -50
|
@@ -9,8 +9,10 @@ import {
|
|
|
9
9
|
buildSubagentToolDescription,
|
|
10
10
|
COMPACT_SUBAGENT_TOOL_DESCRIPTION,
|
|
11
11
|
FULL_SUBAGENT_TOOL_DESCRIPTION,
|
|
12
|
+
SUBAGENT_PARENT_ROUTING_GUIDANCE,
|
|
12
13
|
SUBAGENT_SAFETY_GUIDANCE,
|
|
13
14
|
} from "../../src/extension/tool-description.ts";
|
|
15
|
+
import { BUILTIN_AGENT_NAMES } from "../../src/agents/agents.ts";
|
|
14
16
|
import { SUBAGENT_CHILD_ENV, SUBAGENT_FANOUT_CHILD_ENV } from "../../src/runs/shared/pi-args.ts";
|
|
15
17
|
|
|
16
18
|
const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
@@ -31,9 +33,12 @@ describe("registered subagent tool description", () => {
|
|
|
31
33
|
it("keeps full mode safe and free of hardcoded builtin agent names", () => {
|
|
32
34
|
const description = buildSubagentToolDescription();
|
|
33
35
|
|
|
34
|
-
for (const builtinName of
|
|
36
|
+
for (const builtinName of BUILTIN_AGENT_NAMES) {
|
|
35
37
|
assert.doesNotMatch(description, new RegExp(`\\b${builtinName}\\b`));
|
|
36
38
|
}
|
|
39
|
+
for (const legacyName of ["scout", "worker", "planner"]) {
|
|
40
|
+
assert.doesNotMatch(description, new RegExp(`\\b${legacyName}\\b`));
|
|
41
|
+
}
|
|
37
42
|
assert.match(description, /^To delegate work, call with \{ agent, task \}, \{ tasks \}, or \{ chain \}; omit action\./i);
|
|
38
43
|
assert.match(description, /Use action only for management\/control actions listed below/i);
|
|
39
44
|
assert.match(description, /use \{ action: "list" \} to inspect configured agents\/chains/i);
|
|
@@ -50,6 +55,11 @@ describe("registered subagent tool description", () => {
|
|
|
50
55
|
assert.doesNotMatch(description, /only for foreground runs/i);
|
|
51
56
|
assert.doesNotMatch(description, /omit for async\/background runs/i);
|
|
52
57
|
assert.match(description, /SAFETY-CRITICAL SUBAGENT GUIDANCE/);
|
|
58
|
+
assert.match(description, /PARENT-ONLY SUBAGENT ROUTING/);
|
|
59
|
+
assert.match(description, /call \{ action: "list" \} and select only an executable entry using its current role, context, and tool metadata/i);
|
|
60
|
+
assert.match(description, /Keep tiny targeted reads and simple answers local/i);
|
|
61
|
+
assert.match(description, /broad local investigation, external research, and mutation\/implementation work/i);
|
|
62
|
+
assert.match(description, /parent remains the decision-maker and normally the sole writer/i);
|
|
53
63
|
assert.match(description, /Do not sleep or poll status just to wait/i);
|
|
54
64
|
assert.match(description, /use subagent_wait/i);
|
|
55
65
|
assert.match(description, /interactive session.*normally return control/i);
|
|
@@ -62,6 +72,10 @@ describe("registered subagent tool description", () => {
|
|
|
62
72
|
assert.match(description, /action: "steer"/);
|
|
63
73
|
assert.match(description, /schedule-list/);
|
|
64
74
|
assert.match(description, /action: "eject"/);
|
|
75
|
+
assert.match(description, /action: "eject", agent: "agent-name"/);
|
|
76
|
+
assert.match(description, /action: "disable", agent: "agent-name"/);
|
|
77
|
+
assert.match(description, /action: "enable", agent: "agent-name"/);
|
|
78
|
+
assert.match(description, /action: "reset", agent: "agent-name"/);
|
|
65
79
|
assert.match(description, /action: "disable"/);
|
|
66
80
|
assert.match(description, /action: "grant-spawn-budget"/);
|
|
67
81
|
assert.match(description, /root interactive parent/i);
|
|
@@ -97,6 +111,14 @@ describe("registered subagent tool description", () => {
|
|
|
97
111
|
assert.match(description, /PARALLEL/);
|
|
98
112
|
assert.match(description, /CHAIN/);
|
|
99
113
|
assert.match(description, /action without execution fields/i);
|
|
114
|
+
assert.match(description, /Parent-only routing/);
|
|
115
|
+
assert.match(description, /select only an executable entry using its current role, context, and tool metadata/i);
|
|
116
|
+
assert.match(description, /Keep tiny targeted reads and simple answers local/i);
|
|
117
|
+
assert.match(description, /broad local investigation, external research, and mutation\/implementation work/i);
|
|
118
|
+
assert.match(description, /parent remains the decision-maker and normally the sole writer/i);
|
|
119
|
+
for (const builtinName of BUILTIN_AGENT_NAMES) {
|
|
120
|
+
assert.doesNotMatch(description, new RegExp(`\\b${builtinName}\\b`));
|
|
121
|
+
}
|
|
100
122
|
assert.match(description, /subagent_wait/i);
|
|
101
123
|
assert.match(description, /interactive session.*normally return control/i);
|
|
102
124
|
assert.match(description, /Non-interactive runs.*auto-drain current-session work at agent_end/i);
|
|
@@ -127,6 +149,15 @@ describe("registered subagent tool description", () => {
|
|
|
127
149
|
assert.match(description, /count:/);
|
|
128
150
|
});
|
|
129
151
|
|
|
152
|
+
it("documents task-aware list advice as explicit-only in both modes", () => {
|
|
153
|
+
for (const description of [FULL_SUBAGENT_TOOL_DESCRIPTION, COMPACT_SUBAGENT_TOOL_DESCRIPTION]) {
|
|
154
|
+
assert.match(description, /\{ action: "list", task: "\.\.\." \}/);
|
|
155
|
+
assert.match(description, /advisory/i);
|
|
156
|
+
assert.match(description, /never launches/i);
|
|
157
|
+
assert.match(description, /explicitly call subagent|execute the recommended agent explicitly/i);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
130
161
|
it("renders a custom project description with placeholders and mandatory safety guidance", () => {
|
|
131
162
|
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-project-"));
|
|
132
163
|
const agentDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-agent-"));
|
|
@@ -148,6 +179,8 @@ describe("registered subagent tool description", () => {
|
|
|
148
179
|
assert.match(description, new RegExp(escapeRegex(agentDir)));
|
|
149
180
|
assert.match(description, new RegExp(escapeRegex(projectConfigDir)));
|
|
150
181
|
assert.match(description, /SAFETY-CRITICAL SUBAGENT GUIDANCE/);
|
|
182
|
+
assert.match(description, /PARENT-ONLY SUBAGENT ROUTING/);
|
|
183
|
+
assert.match(description, /select only an executable entry using its current role, context, and tool metadata/i);
|
|
151
184
|
assert.equal(warnings.length, 0);
|
|
152
185
|
});
|
|
153
186
|
|
|
@@ -213,7 +246,7 @@ describe("registered subagent tool description", () => {
|
|
|
213
246
|
assert.ok(warnings.some((message) => message.includes("Ignoring invalid toolDescriptionMode")));
|
|
214
247
|
});
|
|
215
248
|
|
|
216
|
-
function
|
|
249
|
+
function readRegisteredTool(agentDir: string): { description: string; promptGuidelines?: string[] } {
|
|
217
250
|
const script = String.raw`
|
|
218
251
|
import registerSubagentExtension from "./src/extension/index.ts";
|
|
219
252
|
const events = { on() { return () => {}; }, emit() {} };
|
|
@@ -234,7 +267,10 @@ describe("registered subagent tool description", () => {
|
|
|
234
267
|
});
|
|
235
268
|
registerSubagentExtension(fakePi);
|
|
236
269
|
if (!registeredTool) throw new Error("tool not registered");
|
|
237
|
-
process.stdout.write(JSON.stringify(
|
|
270
|
+
process.stdout.write(JSON.stringify({
|
|
271
|
+
description: registeredTool.description,
|
|
272
|
+
promptGuidelines: registeredTool.promptGuidelines ?? null,
|
|
273
|
+
}));
|
|
238
274
|
`;
|
|
239
275
|
const output = execFileSync(
|
|
240
276
|
process.execPath,
|
|
@@ -248,7 +284,7 @@ describe("registered subagent tool description", () => {
|
|
|
248
284
|
],
|
|
249
285
|
{ cwd: projectRoot, env: parentToolEnv(agentDir), encoding: "utf-8" },
|
|
250
286
|
);
|
|
251
|
-
return JSON.parse(output) as string;
|
|
287
|
+
return JSON.parse(output) as { description: string; promptGuidelines?: string[] };
|
|
252
288
|
}
|
|
253
289
|
|
|
254
290
|
function writeExtensionConfig(agentDir: string, config: Record<string, unknown>): void {
|
|
@@ -259,25 +295,40 @@ describe("registered subagent tool description", () => {
|
|
|
259
295
|
|
|
260
296
|
it("registers full, compact, custom, and fallback descriptions from extension config", () => {
|
|
261
297
|
const defaultAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-default-"));
|
|
262
|
-
assert.equal(
|
|
298
|
+
assert.equal(readRegisteredTool(defaultAgentDir).description, FULL_SUBAGENT_TOOL_DESCRIPTION);
|
|
263
299
|
|
|
264
300
|
const compactAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-compact-"));
|
|
265
301
|
writeExtensionConfig(compactAgentDir, { toolDescriptionMode: "compact" });
|
|
266
|
-
assert.equal(
|
|
302
|
+
assert.equal(readRegisteredTool(compactAgentDir).description, COMPACT_SUBAGENT_TOOL_DESCRIPTION);
|
|
267
303
|
|
|
268
304
|
const customAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-custom-"));
|
|
269
305
|
writeExtensionConfig(customAgentDir, { toolDescriptionMode: "custom" });
|
|
270
306
|
fs.writeFileSync(path.join(customAgentDir, "subagent-tool-description.md"), "Registered custom description.", "utf-8");
|
|
271
|
-
const customDescription =
|
|
307
|
+
const customDescription = readRegisteredTool(customAgentDir).description;
|
|
272
308
|
assert.match(customDescription, /Registered custom description/);
|
|
273
309
|
assert.match(customDescription, /SAFETY-CRITICAL SUBAGENT GUIDANCE/);
|
|
274
310
|
|
|
275
311
|
const missingCustomAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-missing-"));
|
|
276
312
|
writeExtensionConfig(missingCustomAgentDir, { toolDescriptionMode: "custom" });
|
|
277
|
-
assert.equal(
|
|
313
|
+
assert.equal(readRegisteredTool(missingCustomAgentDir).description, FULL_SUBAGENT_TOOL_DESCRIPTION);
|
|
278
314
|
|
|
279
315
|
const invalidAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-invalid-"));
|
|
280
316
|
writeExtensionConfig(invalidAgentDir, { toolDescriptionMode: "tiny" });
|
|
281
|
-
assert.equal(
|
|
317
|
+
assert.equal(readRegisteredTool(invalidAgentDir).description, FULL_SUBAGENT_TOOL_DESCRIPTION);
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("registers parent-only routing guidance as promptGuidelines on the parent tool", () => {
|
|
321
|
+
const defaultAgentDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-tool-desc-guidelines-"));
|
|
322
|
+
const registered = readRegisteredTool(defaultAgentDir);
|
|
323
|
+
|
|
324
|
+
assert.ok(Array.isArray(registered.promptGuidelines), "parent subagent tool must expose promptGuidelines");
|
|
325
|
+
assert.equal(registered.promptGuidelines!.length, 1);
|
|
326
|
+
assert.equal(registered.promptGuidelines![0], SUBAGENT_PARENT_ROUTING_GUIDANCE);
|
|
327
|
+
assert.doesNotMatch(SUBAGENT_PARENT_ROUTING_GUIDANCE, new RegExp(BUILTIN_AGENT_NAMES.join("|")));
|
|
328
|
+
assert.match(SUBAGENT_PARENT_ROUTING_GUIDANCE, /\{ action: "list" \}/);
|
|
329
|
+
assert.match(SUBAGENT_PARENT_ROUTING_GUIDANCE, /executable entry/i);
|
|
330
|
+
assert.match(SUBAGENT_PARENT_ROUTING_GUIDANCE, /tiny targeted reads and simple answers local/i);
|
|
331
|
+
assert.match(SUBAGENT_PARENT_ROUTING_GUIDANCE, /broad local investigation, external research, and mutation\/implementation work/i);
|
|
332
|
+
assert.match(SUBAGENT_PARENT_ROUTING_GUIDANCE, /decision-maker and normally the sole writer/i);
|
|
282
333
|
});
|
|
283
334
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-subagents
|
|
3
|
+
description: |
|
|
4
|
+
Delegate work to builtin or custom subagents with single-agent, chain,
|
|
5
|
+
parallel, async, forked-context, and intercom-coordinated workflows. Use
|
|
6
|
+
for advisory review, implementation handoffs, and multi-step tasks where a
|
|
7
|
+
single agent should stay in control while other agents contribute context,
|
|
8
|
+
planning, or execution.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Pi Subagents
|
|
12
|
+
|
|
13
|
+
This skill is for the main parent orchestrator only. Do not inject or follow it inside spawned child subagents. The parent session owns delegation, orchestration, review fanout, and final fix-builder launches. Ordinary children should not run their own subagent workflows; the explicit exception is a delegated fanout child whose resolved builtin `tools` includes `subagent`, and that child may use `subagent` only for the fanout work the parent assigned.
|
|
14
|
+
|
|
15
|
+
Use this skill when the parent orchestrator needs to launch a specialized subagent, compose multiple agents into a workflow, or create/edit agents and chains on demand.
|
|
16
|
+
|
|
17
|
+
## How to use this router
|
|
18
|
+
|
|
19
|
+
Read the matching reference file before acting. Paths are relative to this `SKILL.md`; resolve them against `skills/pi-subagents/` and load them with the read tool.
|
|
20
|
+
|
|
21
|
+
| Task | Read |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| Decide whether to delegate, choose agents, compare tool versus slash commands, apply prompt techniques, or understand builtin roles | `references/prompting-and-roles.md` |
|
|
24
|
+
| Run single, parallel, chain, async, scheduled, forked, worktree, watchdog, clarify, commentator, or intercom-coordinated workflows | `references/execution-controls.md` |
|
|
25
|
+
| List/create/update/delete/eject/disable agents or chains, edit agent files, use prompt-template integration, or expose extension RPC | `references/management-authoring-rpc.md` |
|
|
26
|
+
| Check safety constraints, best practices, standard workflows, or error handling | `references/constraints-and-recipes.md` |
|
|
27
|
+
|
|
28
|
+
Selesai default: use Fable-style parent orchestration for complex work (multiple moving parts, unclear acceptance, cross-cutting code, meaningful user impact, expensive validation, or broad review surface). Lightweight one-off delegation stays lightweight.
|
|
29
|
+
|
|
30
|
+
Routing rule: keep tiny targeted reads and simple answers with the parent. For broad local investigation, external research, or mutation work, call `{ action: "list" }`, choose an executable entry from its runtime metadata, then delegate. Treat list output—not hardcoded role names—as the agent-selection authority.
|
|
31
|
+
|
|
32
|
+
For broad or uncertain requests, read more than one reference. For complex work, start with `references/prompting-and-roles.md` and `references/execution-controls.md`, then consult `references/constraints-and-recipes.md` before launching or reviewing child work.
|
|
33
|
+
|
|
34
|
+
## Always-on constraints
|
|
35
|
+
|
|
36
|
+
- Keep the parent as orchestrator and final decision-maker.
|
|
37
|
+
- Use one writer per cwd/worktree unless isolated worktrees are intentional.
|
|
38
|
+
- For parallel fanout, compare child prompts before launch. Do not send clone prompts with only issue numbers, titles, or broad file globs swapped; each child needs a lane-specific task, source seam, prior evidence, and decision that remains distinct without the item number.
|
|
39
|
+
- Prefer fresh-context review/validation fanout, then synthesize and apply fixes in the parent.
|
|
40
|
+
- Use async/background only when work can proceed independently; do not poll just to wait. For planned human gates in chains, use `{ checkpoint: "name", message?: "..." }` and approve or reject paused async checkpoints with `approve-checkpoint` / `reject-checkpoint`.
|
|
41
|
+
- Preserve capability ceilings, including child tool restrictions and session-scoped allowed-agent restrictions.
|
|
42
|
+
- Escalate unresolved product, architecture, or safety decisions upward instead of letting a child decide silently.
|
|
43
|
+
- As a conservative orchestration policy, do not pass `turnBudget`, a hard `toolBudget`, or a tight `usageBudget` to mutation-capable builders. The default tool budget blocks read/search tools rather than mutation tools, and reported usage has no reservation model. If a builder is interrupted after a tool call starts, checkpoint after the current tool returns with changed files, build/test state, and commit or PR state.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Pi Subagents: Constraints And Recipes
|
|
2
|
+
|
|
3
|
+
This file is a detailed reference loaded from `skills/pi-subagents/SKILL.md`.
|
|
4
|
+
|
|
5
|
+
## Important Constraints
|
|
6
|
+
|
|
7
|
+
- **Forking requires a persisted parent session.** If the current session does not
|
|
8
|
+
have a persisted session file, forked runs fail. Packaged `architect` and `recapper`
|
|
9
|
+
default to forked context; `builder`, `commentator`, `explorer`, and `researcher`
|
|
10
|
+
default to fresh context. Use explicit `context: "fork"` or `context: "fresh"` when
|
|
11
|
+
you intentionally want one context for every child.
|
|
12
|
+
- **Forked runs inherit parent history.** They are branched threads, not fresh
|
|
13
|
+
filtered contexts. Use fresh context for adversarial commentators unless the user explicitly asks for forked context.
|
|
14
|
+
- **Default subagent nesting depth is 2.** Deeper recursive delegation is blocked
|
|
15
|
+
unless configured otherwise.
|
|
16
|
+
- **Attention signals are not lifecycle state.** `needs_attention` means no activity has been observed past the configured threshold. `paused` means the child turn was intentionally interrupted or is awaiting direction; it is not the same as `failed`.
|
|
17
|
+
- **Intercom asks are blocking.** A session can only maintain one pending outbound
|
|
18
|
+
ask wait state at a time.
|
|
19
|
+
- **Keep conversational authority clear.** Advisory subagents should not silently
|
|
20
|
+
become second decision-makers.
|
|
21
|
+
|
|
22
|
+
Runtime config can change orchestration behavior. `intercomBridge.resultDelivery: false` disables only external acknowledged grouped-result delivery when native parent notifications own completion; supervisor asks/progress stay active, and enabled transport failures are still reported. `asyncByDefault` and `forceTopLevelAsync` affect whether launches detach; `waitTool` can make direct `subagent_wait()` calls return immediately while headless auto-drain remains active, and its effective value is propagated to child runtimes; `globalConcurrencyLimit` bounds concurrent fanout, while a positive `maxSubagentSpawnsPerSession` optionally caps cumulative launches (`0` or unset is unlimited). Status and doctor report the budget; static work preflights declared capacity; only the settled root interactive parent can use `grant-spawn-budget` after native confirmation, with total grants bounded by the original cap. Compaction does not reset usage or grants; `singleRunOutputBaseDir` and `worktreeBaseDir` route outputs and worktrees; `completionBatch` groups async notifications. `artifactDir` is `project` (default), `session`, or `temp` and chooses where subagent artifacts are stored. Set `asyncWidget: false` to hide the above-editor background-run widget when a companion footer or dashboard owns that space (fleet inspector remains available). Artifact capture is off by default; set per-run `artifacts: true` when debug files are needed. Async status and result artifacts are versioned with fields such as `lifecycleArtifactVersion`, `workflowGraph`, `steps`, `results`, `totalTokens`, `totalCost`, `turnCount`, `toolCount`, and nested `children`. Child protocol failures expose a structured `protocolError`; `protocol_output_limit` means a child emitted a JSONL line above the 4 MiB live-parser cap. Prefer these artifacts and `status` views over scraping terminal output.
|
|
23
|
+
|
|
24
|
+
## Best Practices
|
|
25
|
+
|
|
26
|
+
### Prefer async orchestration
|
|
27
|
+
|
|
28
|
+
Launch every subagent asynchronously by default. Use `async: true` for explorers, researchers, builders, commentators, validators, commentator checks, one-off builders, chains, and parallel groups unless you intentionally need a foreground/blocking run. The parent should keep moving: inspect code while explorers run, prepare validation while a builder implements, do a local diff pass while commentators review, and synthesize or verify while a fix builder applies accepted feedback. Async is the default orchestration posture; foreground runs are the explicit opt-out.
|
|
29
|
+
|
|
30
|
+
### Use subagent_wait() to block until async runs finish
|
|
31
|
+
|
|
32
|
+
In an interactive chat, do not call `subagent_wait()` merely to wait after launching background work; return control to the user and Pi will wake the session on completion. Override that default when the current request is run-to-completion — for example, the user asked you to stay with the task and report results back this turn or a skill must finish in one turn. In a headless run, Pi auto-drains exact current-session work at `agent_end`; call `subagent_wait()` when this turn must receive results before it ends. In either case, `subagent_wait()` blocks the current turn until the next run completes or needs attention, keeps the turn alive for normal notification delivery, then returns.
|
|
33
|
+
|
|
34
|
+
- `subagent_wait()` — return when the next initially active async run or registered provider item finishes, or a subagent needs attention.
|
|
35
|
+
- `subagent_wait({ all: true })` — block until every async run and provider item active at call time finishes, or a subagent needs attention.
|
|
36
|
+
- `subagent_wait({ id: "..." })` — block on one async or remembered detached foreground run (id or prefix). Provider items are not selected through this parameter.
|
|
37
|
+
- `subagent_wait({ timeoutMs })` — cap the block; active work keeps running if it elapses.
|
|
38
|
+
|
|
39
|
+
Providers are discovered through the versioned `pi-subagents/background-work` registry and must return stable item IDs with exact owning session IDs. Child agents receive no provider automatically: keep `subagent_wait` in the child `tools` allowlist and load provider extensions through `extensions` or `subagentOnlyExtensions`.
|
|
40
|
+
|
|
41
|
+
For non-interactive fleet orchestration, `subagent_wait()` can keep N builders in flight: launch N, wait for the next completion, react to the result, launch a replacement if needed, then wait again. Use `subagent_wait({ all: true })` only when you intentionally want to drain the fleet to zero. If the turn ends first, headless `agent_end` auto-drain still waits for exact current-session work. In an interactive session, return to the user instead of holding the turn open just to await completion.
|
|
42
|
+
|
|
43
|
+
If config or `PI_SUBAGENT_WAIT_TOOL_ENABLED` disables blocking behavior, direct `subagent_wait` calls return immediately. Headless `agent_end` auto-drain remains active as a lifecycle safeguard and surfaces provider, reconciliation, or timeout failures.
|
|
44
|
+
|
|
45
|
+
### Keep writes single-threaded by default
|
|
46
|
+
|
|
47
|
+
A strong pattern is one main decision-maker plus advisory/research/review/validation subagents around it. Use `commentator` for advice and `builder` for the actual write path. Parallelize reading, review, validation, and synthesis support, not normal writes, unless you deliberately isolate writers with worktrees. A child that writes should report what changed, what was left undone, commands run with exit codes, validation evidence, surprises, and any decisions that need parent approval.
|
|
48
|
+
|
|
49
|
+
### Use fork for branched advisory or execution threads
|
|
50
|
+
|
|
51
|
+
Forked runs are useful when the child should reason in a separate thread while
|
|
52
|
+
still inheriting the parent’s accumulated context. They are especially useful for
|
|
53
|
+
`commentator`, which audits inherited decisions and drift. For adversarial code review,
|
|
54
|
+
prefer fresh-context commentators that inspect the repo and diff directly unless the
|
|
55
|
+
user explicitly requests forked context.
|
|
56
|
+
|
|
57
|
+
### Prefer narrow tasks
|
|
58
|
+
|
|
59
|
+
Give subagents specific tasks rather than vague mandates.
|
|
60
|
+
`Review auth.ts for null-check gaps` works better than `Review everything`.
|
|
61
|
+
|
|
62
|
+
### Escalate decisions upward
|
|
63
|
+
|
|
64
|
+
If a subagent encounters an unapproved product, architecture, or scope choice,
|
|
65
|
+
it should use `contact_supervisor` and wait for the reply instead of deciding alone. Generic `intercom` is a fallback only when the bridge-provided supervisor tool is unavailable.
|
|
66
|
+
|
|
67
|
+
### Intervene only on clear control signals
|
|
68
|
+
|
|
69
|
+
Use subagent control proactively when a delegated run emits `needs_attention`, or when a human asks you to regain control. Do not interrupt just because a child has briefly produced no output. Silence can be normal during long tool calls, test runs, or model reasoning.
|
|
70
|
+
|
|
71
|
+
### Name sessions meaningfully
|
|
72
|
+
|
|
73
|
+
Use `/name` so intercom targeting stays stable.
|
|
74
|
+
|
|
75
|
+
## Common Workflows
|
|
76
|
+
|
|
77
|
+
### Recon → Plan → Implement
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
subagent({
|
|
81
|
+
chain: [
|
|
82
|
+
{ agent: "explorer", task: "Map the auth flow and summarize relevant files" },
|
|
83
|
+
{ agent: "architect", task: "Plan the migration from {previous}" },
|
|
84
|
+
{ agent: "builder", task: "Implement the approved plan from {previous}" }
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Fable mode for complex work
|
|
90
|
+
|
|
91
|
+
Fable mode is the default orchestration posture for complex work. It is not a separate runtime mode; it is how the parent session uses `subagent`, `interview`, `subagent_wait`, acceptance contracts, artifacts, and fresh-context review when the work has real complexity. Use it for complex features, broad refactors, migrations, ambiguous goals, multi-system changes, expensive validation, user-visible behavior changes, or any request to plan/orchestrate end to end. Do not force it onto tiny one-shot delegation.
|
|
92
|
+
|
|
93
|
+
Run the work through seven gated phases:
|
|
94
|
+
|
|
95
|
+
1. **Understand** — use `explorer` fanout for breadth, but the parent personally reads the load-bearing files and lets direct source reading decide disagreements. Gate: the parent can quote the exact code or behavior being changed and knows the repo's verification harness.
|
|
96
|
+
2. **Decide** — separate user-owned decisions from implementation judgments. Use `interview` for product, naming, cost, taste, or risk decisions; decide routine engineering details in the parent and state them. Gate: every user-owned decision needed for design is answered.
|
|
97
|
+
3. **Design** — use `architect`, `explorer`, or read-only design/review children for parallel perspectives. Before parallel workstreams, write seam contracts: ownership boundaries, composition points, assumptions, and validation handoffs. Gate: one parent-synthesized plan and written seams for parallel work.
|
|
98
|
+
4. **Implement** — capture a baseline first, then launch one async `builder` as the sole writer for the active worktree unless isolated worktrees were intentionally requested. Break large work into serial milestones instead of concurrent writes. Gate: build/typecheck is green and every output or diff delta is characterized as intended or fixed.
|
|
99
|
+
5. **Verify** — climb the spend ladder: static checks, free end-to-end/dry-run, cheapest live probe, targeted changed-path live test, then full realistic run when warranted. Observe the artifact itself, not only exit codes or scores, and confirm the changed code actually executed. Gate: the highest necessary rung has directly observed evidence matching intent.
|
|
100
|
+
6. **Iterate** — when a gate or commentator finds a defect, the parent names the failure class, searches for siblings, synthesizes fixes, and sends exactly one fix builder for accepted changes. For LLM judges, gates, or detectors, trigger on concrete findings rather than scores, record pass/violations/error verdicts, cache nondeterministic verdicts by input hash, budget enough output tokens, and sanitize judge text before reusing it downstream. Gate: the class is fixed or explicitly bounded, and recurrence detection exists when feasible.
|
|
101
|
+
7. **Ship** — run adversarial fresh-context review/validation outside the implementation path, disposition every finding, rerun affected gates, then have the parent inspect the final diff. Commit, push, release, or open PRs only inside user-approved boundaries. Gate: findings are dispositioned, gates re-pass, and the final summary names evidence, artifacts, residual risks, and output paths.
|
|
102
|
+
|
|
103
|
+
### Clarify → Plan → Implement → Review (self-orchestrated workflow)
|
|
104
|
+
|
|
105
|
+
For straightforward non-trivial work, this sequence is the lightweight version of the parent-owned loop. When the task is complex, use Fable mode above. In either case, factor in the packaged prompt workflows without literally invoking slash commands. Use the same patterns through tools and subagents.
|
|
106
|
+
|
|
107
|
+
Keep builtin agent defaults unless the user explicitly asks for a different model, thinking level, skills, output behavior, context mode, or other override. Do not add overrides just because you are orchestrating; the defaults encode the intended role behavior. In particular, packaged `architect` and `recapper` default to forked context; `builder`, `commentator`, `explorer`, and `researcher` default to fresh context.
|
|
108
|
+
|
|
109
|
+
When the user approves launching a subagent to carry out a plan or workflow, treat that as approval to generate a proper role-specific meta prompt for that subagent. Include the approved plan path or summary, clarified requirements, non-goals, relevant context, role boundaries, files or areas to inspect, acceptance criteria, expected output, and validation expectations. Do not pass vague instructions like “implement the plan fully” or “review this” by themselves.
|
|
110
|
+
|
|
111
|
+
- `/gather-context-and-clarify` maps to: launch `explorer` and, when needed, `researcher`; synthesize findings; then use `interview` to ask every clarification question needed for shared understanding.
|
|
112
|
+
- `/parallel-review` maps to: launch fresh-context `commentator` agents with distinct review angles; synthesize the feedback before applying anything.
|
|
113
|
+
- `/review-loop` maps to: keep the parent in charge of builder → fresh commentators → synthesized fix builder cycles until no fixes worth doing now remain, an unapproved decision appears, or the review-round cap is reached.
|
|
114
|
+
- `/parallel-research` maps to: combine local `explorer` context with external `researcher` evidence when current docs, ecosystem behavior, or API details matter.
|
|
115
|
+
- `/parallel-context-build` maps to: run a chain-mode parallel group of `explorer` agents with distinct temp output paths, then synthesize their context and meta-prompt sections.
|
|
116
|
+
- `/parallel-handoff-plan` maps to: run external `researcher` plus local/strategy `explorer` passes, then a synthesis `explorer` that writes an implementation handoff plan and implementation-ready meta-prompt.
|
|
117
|
+
- `/parallel-cleanup` maps to: use review-only cleanup passes after implementation, especially for simplicity, verbosity, and redundant tests.
|
|
118
|
+
|
|
119
|
+
For feature work, use this sequence as scaffolding for parent-agent behavior:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
clarify → validation contract → architect → async builder → parallel async fresh-context commentators/validators → async fix builder → follow-up review when warranted → parent review
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The validation contract defines acceptance before code is written: expected behavior, acceptance checks, commands or user flows to exercise, and evidence the builder should return. Keep it lightweight for small tasks, but make it explicit enough that commentators and validators are checking the intended outcome rather than the builder’s own assumptions.
|
|
126
|
+
|
|
127
|
+
Use the structured `acceptance` field when the run should carry an explicit acceptance contract. If omitted, subagents infer an effective policy from role, mode, and risk. Evidence levels end at `verified`: use `level: "checked"` for ordinary writer evidence and `level: "verified"` when the runtime should run explicit validation commands. Independent review is orthogonal; use `review: { required: true, agent: "commentator" }` and orchestrate the commentator separately. `review-required` means evidence passed but review is pending, while `reviewed` means a real independent result found no blockers. For commentator/read-only calls, omit `acceptance`. Never explicitly request `level: "reviewed"`; that value remains recognized only so preflight can return an actionable correction. To disable gates, use `{ level: "none", reason: "..." }`; the bare string `"none"` is rejected, and `false` is accepted only as a deprecated shorthand. Child-reported command success is evidence, not runtime verification.
|
|
128
|
+
|
|
129
|
+
The first `builder` implements the approved plan. The parent continues with independent inspection or validation prep while it runs, not parallel edits to the same worktree. When the async builder completes, treat its handoff as the transition into review, not as final completion, unless the user explicitly asked for builder-only work, review-only output, or to stop after implementation. Parallel commentators inspect the resulting diff from fresh context. Validators check behavior with the best available evidence: commands, tests, browser/CLI interaction, screenshots, logs, or manual reproduction notes. The final `builder` applies synthesized review fixes with an explicit `context: "fork"` when the fix needs inherited parent context, then the parent looks over the final diff before completing. The parent may launch these steps as an initial async chain when the workflow is already clear, or as follow-up subagent runs after each async completion. Initial chains should pass `async: true` so the main chat is unblocked; avoid `clarify: true` unless the user asked for foreground clarification. Do not stop after parallel review unless the user explicitly asked for review-only output or the review surfaced a decision that needs approval first.
|
|
130
|
+
|
|
131
|
+
For complex work, risky changes, broad refactors, or many changed lines, increase review and validation fanout rather than trusting one commentator. Use distinct angles such as correctness/regressions, tests/validation, simplicity/maintainability, security/privacy, performance, docs/API contracts, and user-flow behavior. When commentators find non-trivial issues or the fix builder touches many lines, run another focused review round before final validation.
|
|
132
|
+
|
|
133
|
+
When review has already produced concrete findings across several independent areas, use staged fix orchestration: parallel read-only architects for each issue cluster, one sole writer builder for the active worktree, then parallel fresh-context validators. This is the safest way to handle a dirty worktree with many prior changes because it parallelizes judgment without parallelizing writes. Non-blocking suggestions may go into the writer prompt only if they are small, safe, and inside the approved scope; otherwise defer them explicitly.
|
|
134
|
+
|
|
135
|
+
For very large work, split into serial milestones instead of launching a swarm of writers. Each milestone gets one writer, a validation contract, fresh-context review/validation, a fix pass, and parent acceptance before the next milestone starts. Use parallel subagents inside a milestone for read-only context, research, review, and validation only.
|
|
136
|
+
|
|
137
|
+
Keep orchestration authority in the parent session. Child subagents should not launch more subagents, read this skill, or run their own orchestration loops unless the parent intentionally selected a fanout agent whose builtin `tools` includes `subagent`. Spawned subagents do not receive the `pi-subagents` skill, parent-only status/control/slash messages, or prior parent `subagent` tool-call/tool-result artifacts. Ordinary children also do not receive the `subagent` extension tool. Child context filtering strips old hidden orchestration-instruction messages when they appear in inherited history. Every child receives a boundary instruction: ordinary children are told the parent owns orchestration and they must not propose or run subagents; explicit fanout children are told to use `subagent` only for the assigned fanout work, with `maxSubagentDepth` still enforced. Implementation children must call real edit/write tools instead of printing pseudo tool calls. Pass children concrete role-specific work instead.
|
|
138
|
+
|
|
139
|
+
1. Clarify first. This is mandatory. Gather code context with `explorer`, add `researcher` only when external evidence matters, then ask the user clarifying questions with `interview` until scope, acceptance criteria, constraints, and non-goals are clear.
|
|
140
|
+
2. Define the validation contract. State acceptance before implementation: expected behavior, checks to run, user flows to exercise, and evidence required in the builder handoff. For UI, CLI, integration, or workflow changes, include at least one validator angle that uses the product the way a user would rather than only reading code.
|
|
141
|
+
3. Plan when useful. For complex work, call `architect` or write a plan doc yourself and get approval before implementation. For simple work, confirm shared understanding and explicitly note why planning is skipped.
|
|
142
|
+
4. Implement with one writer. After approval, launch `builder` asynchronously with a proper meta prompt that includes clarified requirements, relevant context, plan path or summary, the validation contract, and output expectations. Packaged `builder` defaults to fresh context; pass `context: "fork"` only when inherited parent context is intentionally required. While it runs, prepare validation or inspect adjacent code instead of editing the same worktree.
|
|
143
|
+
5. Require a useful builder handoff. Ask the builder to report changed files, what was implemented, what was left undone, commands run with exit codes, validation evidence, surprises or new risks, decisions made inside approved scope, and decisions needing parent approval.
|
|
144
|
+
6. Review after implementation. After the builder completes, launch parallel async fresh-context `commentator` agents for correctness/regressions, tests/validation, and simplicity/maintainability. Add security, performance, docs/API, domain-specific, or user-flow validators for complex work, risky changes, broad refactors, or many changed lines. Use `output: false` unless review artifacts are explicitly needed.
|
|
145
|
+
7. Synthesize, then run the fix builder. Separate blockers, fixes worth doing now, optional improvements, and feedback to ignore/defer, then launch an async forked `builder` to apply fixes worth doing now when the workflow is implementation-authorized. If commentators found scope/product/architecture choices that were not approved, ask the user first instead of applying them.
|
|
146
|
+
8. Review again when warranted. If the fix builder made substantial changes or addressed non-trivial findings, run another focused parallel review round before final validation.
|
|
147
|
+
9. Validate and complete. After the fix builder and any follow-up review return, inspect the final diff yourself, run or confirm focused validation, update docs/changelog when relevant, and summarize what changed and why.
|
|
148
|
+
|
|
149
|
+
Example implementation handoff after clarification and optional planning:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
subagent({
|
|
153
|
+
agent: "builder",
|
|
154
|
+
task: "Implement the approved feature.\n\nClarified requirements:\n- ...\n\nPlan: see ~/Documents/docs/...-plan.md\n\nValidation contract:\n- ...\n\nReturn a handoff with changed files, what was implemented, what was left undone, commands run with exit codes, validation evidence, surprises/new risks, and decisions needing parent approval.",
|
|
155
|
+
acceptance: {
|
|
156
|
+
level: "checked",
|
|
157
|
+
evidence: ["changed-files", "tests-added", "commands-run", "residual-risks", "no-staged-files"]
|
|
158
|
+
},
|
|
159
|
+
async: true
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Example review pass after implementation:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
subagent({
|
|
167
|
+
tasks: [
|
|
168
|
+
{ agent: "commentator", task: "Review the current diff for correctness and regressions. Inspect changed files directly; do not rely on the builder's reasoning.", output: false },
|
|
169
|
+
{ agent: "commentator", task: "Review the current diff for tests and validation quality against the validation contract. Inspect changed files directly.", output: false },
|
|
170
|
+
{ agent: "commentator", task: "Review the current diff for simplicity and maintainability. Inspect changed files directly.", output: false }
|
|
171
|
+
],
|
|
172
|
+
concurrency: 3,
|
|
173
|
+
context: "fresh",
|
|
174
|
+
async: true
|
|
175
|
+
})
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Example fix builder after parallel reviews:
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
subagent({
|
|
182
|
+
agent: "builder",
|
|
183
|
+
task: "Apply the synthesized commentator feedback below. Only apply fixes worth doing now; preserve user-approved scope; ask before unapproved product or architecture changes. Run focused validation and summarize what changed.\n\nReviewer synthesis:\n...",
|
|
184
|
+
async: true
|
|
185
|
+
})
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Review loop
|
|
189
|
+
|
|
190
|
+
Do not treat review as the final step for implementation work. Run commentators and validators, synthesize their findings against user scope and the validation contract, then launch one `builder` for accepted fixes when implementation is authorized.
|
|
191
|
+
|
|
192
|
+
When an async implementation builder completes, treat the builder handoff as an intermediate state. The next parent action is review fanout, then synthesis, then a fix builder if commentators found fixes worth doing now. This can be planned as an initial async chain when the whole workflow is known, or continued as follow-up subagent runs when the parent only launched the first builder initially. Initial chains should pass `async: true` so the main chat is unblocked; `clarify: true` is the explicit foreground opt-in.
|
|
193
|
+
|
|
194
|
+
For explicit review-loop requests, repeat builder → fresh-commentator → synthesized-fix-builder cycles until commentators find no blockers or fixes worth doing now, remaining feedback is optional or intentionally deferred, an unapproved product/scope/architecture decision needs the user, or the max review-round cap is reached. Default to 3 review rounds unless the user sets a different cap. For complex work, many changed lines, or any fix pass that materially changes the diff, run another focused review round before the parent’s final look; otherwise stop instead of chasing optional polish.
|
|
195
|
+
|
|
196
|
+
### Parallel non-conflicting analysis
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
subagent({
|
|
200
|
+
tasks: [
|
|
201
|
+
{ agent: "explorer", task: "Audit frontend auth flow" },
|
|
202
|
+
{ agent: "researcher", task: "Research current retry/backoff best practices" }
|
|
203
|
+
]
|
|
204
|
+
})
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Saved chain
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
/run-chain review-chain -- review this branch
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Use saved `.chain.md` or `.chain.json` workflows when the user wants a repeatable multi-agent flow without rewriting the chain each time. Prefer `.chain.json` for dynamic fanout or inline `outputSchema` objects; `.chain.md` remains the simple sequential/static authoring format.
|
|
214
|
+
|
|
215
|
+
## Error Handling
|
|
216
|
+
|
|
217
|
+
**"Unknown agent"**
|
|
218
|
+
```typescript
|
|
219
|
+
subagent({ action: "list" })
|
|
220
|
+
// Check available agents and chains, then confirm scope/precedence.
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Setup, discovery, or intercom confusion**
|
|
224
|
+
```typescript
|
|
225
|
+
subagent({ action: "doctor" })
|
|
226
|
+
// Check runtime paths, async support, discovery counts, current session, and intercom bridge state.
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**"Max subagent depth exceeded"**
|
|
230
|
+
```typescript
|
|
231
|
+
// Flatten the workflow or raise maxSubagentDepth in config.
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**"Session manager did not return a session file"**
|
|
235
|
+
```typescript
|
|
236
|
+
// Persist the current session before using context: "fork".
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Intercom "Already waiting for a reply"**
|
|
240
|
+
```typescript
|
|
241
|
+
// Resolve the current outbound ask before starting another one.
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Parallel output-path conflict**
|
|
245
|
+
```typescript
|
|
246
|
+
// Give each parallel task a distinct output path, or disable output for tasks that do not need it.
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
**Worktree launch fails**
|
|
250
|
+
```typescript
|
|
251
|
+
// Ensure the git working tree is clean and task cwd overrides match the shared cwd.
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Child fails before starting**
|
|
255
|
+
```typescript
|
|
256
|
+
// Inspect `subagent({ action: "status", id: "..." })`, artifact metadata/output logs, and run doctor. Extension loader errors usually appear in child output logs.
|
|
257
|
+
```
|