@dreki-gg/pi-subagent 0.6.0 → 0.8.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/.fallowrc.json +6 -0
- package/CHANGELOG.md +37 -0
- package/README.md +82 -70
- package/docs/orchestration-principles.md +132 -0
- package/docs/plans/01_structured-handoffs-and-synthesis.plan.md +376 -0
- package/docs/plans/02_clean-context-review-loop.plan.md +240 -0
- package/docs/plans/03_parallel-recon-single-writer-docs.plan.md +199 -0
- package/docs/plans/04_manager-workflow.plan.md +248 -0
- package/docs/plans/05_advisor-routing.plan.md +244 -0
- package/extensions/subagent/agent-result-utils.ts +12 -0
- package/extensions/subagent/agent-runner-types.ts +23 -0
- package/extensions/subagent/agent-runner.ts +90 -0
- package/extensions/subagent/agents.ts +31 -77
- package/extensions/subagent/handoffs.ts +273 -0
- package/extensions/subagent/index.ts +359 -581
- package/extensions/subagent/run-agent-args.ts +90 -0
- package/extensions/subagent/{delegate-executor.ts → spawn-utils.ts} +64 -87
- package/extensions/subagent/synthesis.ts +1 -51
- package/package.json +7 -10
- package/prompts/advisor.md +37 -0
- package/prompts/bug-prover.md +42 -0
- package/{agents → prompts}/docs-scout.md +2 -2
- package/prompts/manager.md +52 -0
- package/{agents → prompts}/planner.md +16 -1
- package/prompts/reviewer.md +93 -0
- package/{agents → prompts}/scout.md +5 -1
- package/prompts/validator.md +42 -0
- package/prompts/worker.md +61 -0
- package/skills/spawn-subagents/SKILL.md +80 -8
- package/skills/write-an-agent/SKILL.md +5 -5
- package/agents/reviewer.md +0 -37
- package/agents/worker.md +0 -26
- package/extensions/subagent/delegate-args.ts +0 -145
- package/extensions/subagent/delegate-types.ts +0 -62
- package/extensions/subagent/delegate-ui.ts +0 -132
- package/extensions/subagent/workflows.ts +0 -150
- package/prompts/implement-and-review.md +0 -10
- package/prompts/implement.md +0 -10
- package/prompts/scout-and-plan.md +0 -9
- /package/{agents → prompts}/ux-designer.md +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { AgentScope } from './agents';
|
|
2
|
+
|
|
3
|
+
export interface RunAgentCommandOptions {
|
|
4
|
+
agentScope: AgentScope;
|
|
5
|
+
confirmProjectAgents: boolean;
|
|
6
|
+
model?: string;
|
|
7
|
+
thinking?: string;
|
|
8
|
+
agentName?: string;
|
|
9
|
+
explicitTask?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function tokenize(input: string): string[] {
|
|
13
|
+
return input.match(/"[^"]*"|'[^']*'|\S+/g)?.map((token) => token.replace(/^['"]|['"]$/g, '')) ?? [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function formatRunAgentUsage(): string {
|
|
17
|
+
return 'Usage: /run-agent [--scope user|project|both] [--model <id>] [--thinking <level>] [--yes-project-agents] <agent> [task]';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function parseRunAgentArgs(rawArgs?: string):
|
|
21
|
+
| { ok: true; options: RunAgentCommandOptions }
|
|
22
|
+
| { ok: false; error: string } {
|
|
23
|
+
const tokens = tokenize(rawArgs?.trim() ?? '');
|
|
24
|
+
const taskTokens: string[] = [];
|
|
25
|
+
|
|
26
|
+
let agentScope: AgentScope = 'user';
|
|
27
|
+
let confirmProjectAgents = true;
|
|
28
|
+
let model: string | undefined;
|
|
29
|
+
let thinking: string | undefined;
|
|
30
|
+
let agentName: string | undefined;
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
33
|
+
const token = tokens[i];
|
|
34
|
+
|
|
35
|
+
if (token === '--scope') {
|
|
36
|
+
const value = tokens[++i];
|
|
37
|
+
if (!value || !['user', 'project', 'both'].includes(value)) {
|
|
38
|
+
return { ok: false, error: `Invalid --scope value.\n\n${formatRunAgentUsage()}` };
|
|
39
|
+
}
|
|
40
|
+
agentScope = value as AgentScope;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (token === '--model') {
|
|
45
|
+
const value = tokens[++i];
|
|
46
|
+
if (!value) {
|
|
47
|
+
return { ok: false, error: `Missing --model value.\n\n${formatRunAgentUsage()}` };
|
|
48
|
+
}
|
|
49
|
+
model = value;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (token === '--thinking' || token === '--reasoning-level') {
|
|
54
|
+
const value = tokens[++i];
|
|
55
|
+
if (!value) {
|
|
56
|
+
return { ok: false, error: `Missing ${token} value.\n\n${formatRunAgentUsage()}` };
|
|
57
|
+
}
|
|
58
|
+
thinking = value;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (token === '--yes-project-agents') {
|
|
63
|
+
confirmProjectAgents = false;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (token.startsWith('--')) {
|
|
68
|
+
return { ok: false, error: `Unknown option: ${token}\n\n${formatRunAgentUsage()}` };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!agentName) {
|
|
72
|
+
agentName = token;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
taskTokens.push(token);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
ok: true,
|
|
81
|
+
options: {
|
|
82
|
+
agentScope,
|
|
83
|
+
confirmProjectAgents,
|
|
84
|
+
model,
|
|
85
|
+
thinking,
|
|
86
|
+
agentName,
|
|
87
|
+
explicitTask: taskTokens.join(' ').trim() || undefined,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -1,26 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for spawning pi subagent processes.
|
|
3
|
+
* Used by both the `subagent` tool (index.ts) and the `/run-agent` command (agent-runner.ts).
|
|
4
|
+
*/
|
|
5
|
+
|
|
1
6
|
import { spawn } from 'node:child_process';
|
|
2
7
|
import * as fs from 'node:fs';
|
|
3
8
|
import * as os from 'node:os';
|
|
4
9
|
import * as path from 'node:path';
|
|
5
|
-
import { withFileMutationQueue } from '@
|
|
6
|
-
import type {
|
|
7
|
-
import type {
|
|
8
|
-
import { discoverAgentsWithPackages, type AgentScope } from './agents';
|
|
9
|
-
import type { AgentResult, UsageStats } from './delegate-types';
|
|
10
|
+
import { withFileMutationQueue } from '@earendil-works/pi-coding-agent';
|
|
11
|
+
import type { Message } from '@earendil-works/pi-ai';
|
|
12
|
+
import type { UsageStats } from './agent-runner-types.js';
|
|
10
13
|
|
|
11
|
-
function emptyUsage(): UsageStats {
|
|
14
|
+
export function emptyUsage(): UsageStats {
|
|
12
15
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 };
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
function getPiInvocation(args: string[]): { command: string; args: string[] } {
|
|
16
19
|
const currentScript = process.argv[1];
|
|
17
|
-
|
|
20
|
+
|
|
21
|
+
// Bun standalone binaries set argv[1] to a virtual FS path (e.g. /$bunfs/root/pi)
|
|
22
|
+
// that only resolves inside the running Bun process. Skip it — the binary IS the entry point.
|
|
23
|
+
const isBunVirtualPath = currentScript?.startsWith('/$bunfs/');
|
|
24
|
+
|
|
25
|
+
if (currentScript && !isBunVirtualPath && fs.existsSync(currentScript)) {
|
|
18
26
|
return { command: process.execPath, args: [currentScript, ...args] };
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
const execName = path.basename(process.execPath).toLowerCase();
|
|
22
30
|
const isGenericRuntime = /^(node|bun)(\.exe)?$/.test(execName);
|
|
23
|
-
if (!isGenericRuntime)
|
|
31
|
+
if (!isGenericRuntime) {
|
|
32
|
+
// Standalone binary (e.g. pi compiled with Bun) — invoke directly
|
|
33
|
+
return { command: process.execPath, args };
|
|
34
|
+
}
|
|
24
35
|
|
|
25
36
|
return { command: 'pi', args };
|
|
26
37
|
}
|
|
@@ -38,74 +49,76 @@ async function writePromptToTempFile(
|
|
|
38
49
|
return { dir: tmpDir, filePath };
|
|
39
50
|
}
|
|
40
51
|
|
|
41
|
-
|
|
52
|
+
function cleanupTempFiles(
|
|
53
|
+
tmpPromptPath: string | null,
|
|
54
|
+
tmpPromptDir: string | null,
|
|
55
|
+
): void {
|
|
56
|
+
if (tmpPromptPath) try { fs.unlinkSync(tmpPromptPath); } catch { /* ignore */ }
|
|
57
|
+
if (tmpPromptDir) try { fs.rmdirSync(tmpPromptDir); } catch { /* ignore */ }
|
|
58
|
+
}
|
|
42
59
|
|
|
43
|
-
export interface
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
60
|
+
export interface SpawnPiAgentOptions {
|
|
61
|
+
cwd: string;
|
|
62
|
+
agentName: string;
|
|
63
|
+
task: string;
|
|
64
|
+
systemPrompt?: string;
|
|
65
|
+
model?: string;
|
|
66
|
+
thinking?: string;
|
|
67
|
+
tools?: string[];
|
|
48
68
|
signal?: AbortSignal;
|
|
49
|
-
|
|
69
|
+
onMessage?: (msg: Message) => void;
|
|
70
|
+
onToolResult?: (msg: Message) => void;
|
|
50
71
|
}
|
|
51
72
|
|
|
52
|
-
export
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const available = agents.map((a) => a.name).join(', ') || 'none';
|
|
63
|
-
return {
|
|
64
|
-
agent: agentName,
|
|
65
|
-
task,
|
|
66
|
-
exitCode: 1,
|
|
67
|
-
messages: [],
|
|
68
|
-
stderr: `Unknown agent: "${agentName}". Available: ${available}.`,
|
|
69
|
-
usage: emptyUsage(),
|
|
70
|
-
};
|
|
71
|
-
}
|
|
73
|
+
export interface SpawnPiAgentResult {
|
|
74
|
+
exitCode: number;
|
|
75
|
+
messages: Message[];
|
|
76
|
+
stderr: string;
|
|
77
|
+
wasAborted: boolean;
|
|
78
|
+
usage: UsageStats;
|
|
79
|
+
model?: string;
|
|
80
|
+
stopReason?: string;
|
|
81
|
+
errorMessage?: string;
|
|
82
|
+
}
|
|
72
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Spawn a pi process for a subagent and collect results.
|
|
86
|
+
* This is the shared core that both the tool and the /run-agent command use.
|
|
87
|
+
*/
|
|
88
|
+
export async function spawnPiAgent(options: SpawnPiAgentOptions): Promise<SpawnPiAgentResult> {
|
|
73
89
|
const args: string[] = ['--mode', 'json', '-p', '--no-session'];
|
|
74
|
-
if (
|
|
75
|
-
if (
|
|
76
|
-
if (
|
|
90
|
+
if (options.model) args.push('--model', options.model);
|
|
91
|
+
if (options.thinking) args.push('--thinking', options.thinking);
|
|
92
|
+
if (options.tools && options.tools.length > 0) args.push('--tools', options.tools.join(','));
|
|
77
93
|
|
|
78
94
|
let tmpPromptDir: string | null = null;
|
|
79
95
|
let tmpPromptPath: string | null = null;
|
|
80
96
|
|
|
81
|
-
const result:
|
|
82
|
-
agent: agentName,
|
|
83
|
-
task,
|
|
97
|
+
const result: SpawnPiAgentResult = {
|
|
84
98
|
exitCode: 0,
|
|
85
99
|
messages: [],
|
|
86
100
|
stderr: '',
|
|
101
|
+
wasAborted: false,
|
|
87
102
|
usage: emptyUsage(),
|
|
88
|
-
model: agent.model,
|
|
89
103
|
};
|
|
90
104
|
|
|
91
105
|
try {
|
|
92
|
-
if (
|
|
93
|
-
const tmp = await writePromptToTempFile(
|
|
106
|
+
if (options.systemPrompt?.trim()) {
|
|
107
|
+
const tmp = await writePromptToTempFile(options.agentName, options.systemPrompt);
|
|
94
108
|
tmpPromptDir = tmp.dir;
|
|
95
109
|
tmpPromptPath = tmp.filePath;
|
|
96
110
|
args.push('--append-system-prompt', tmpPromptPath);
|
|
97
111
|
}
|
|
98
112
|
|
|
99
|
-
args.push(`Task: ${task}`);
|
|
113
|
+
args.push(`Task: ${options.task}`);
|
|
100
114
|
|
|
101
115
|
const exitCode = await new Promise<number>((resolve) => {
|
|
102
116
|
const invocation = getPiInvocation(args);
|
|
103
117
|
const proc = spawn(invocation.command, invocation.args, {
|
|
104
|
-
cwd: options.cwd
|
|
118
|
+
cwd: options.cwd,
|
|
105
119
|
shell: false,
|
|
106
120
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
107
121
|
});
|
|
108
|
-
|
|
109
122
|
let buffer = '';
|
|
110
123
|
|
|
111
124
|
const processLine = (line: string) => {
|
|
@@ -137,14 +150,12 @@ export async function runAgent(
|
|
|
137
150
|
if (msg.errorMessage) result.errorMessage = msg.errorMessage;
|
|
138
151
|
}
|
|
139
152
|
|
|
140
|
-
|
|
141
|
-
options.onUpdate(options.phaseName ?? 'unknown', agentName, { ...result });
|
|
153
|
+
options.onMessage?.(msg);
|
|
142
154
|
}
|
|
143
155
|
|
|
144
156
|
if (event.type === 'tool_result_end' && event.message) {
|
|
145
157
|
result.messages.push(event.message as Message);
|
|
146
|
-
|
|
147
|
-
options.onUpdate(options.phaseName ?? 'unknown', agentName, { ...result });
|
|
158
|
+
options.onToolResult?.(event.message as Message);
|
|
148
159
|
}
|
|
149
160
|
};
|
|
150
161
|
|
|
@@ -168,6 +179,7 @@ export async function runAgent(
|
|
|
168
179
|
|
|
169
180
|
if (options.signal) {
|
|
170
181
|
const killProc = () => {
|
|
182
|
+
result.wasAborted = true;
|
|
171
183
|
proc.kill('SIGTERM');
|
|
172
184
|
setTimeout(() => {
|
|
173
185
|
if (!proc.killed) proc.kill('SIGKILL');
|
|
@@ -181,41 +193,6 @@ export async function runAgent(
|
|
|
181
193
|
result.exitCode = exitCode;
|
|
182
194
|
return result;
|
|
183
195
|
} finally {
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
fs.unlinkSync(tmpPromptPath);
|
|
187
|
-
} catch {
|
|
188
|
-
/* ignore */
|
|
189
|
-
}
|
|
190
|
-
if (tmpPromptDir)
|
|
191
|
-
try {
|
|
192
|
-
fs.rmdirSync(tmpPromptDir);
|
|
193
|
-
} catch {
|
|
194
|
-
/* ignore */
|
|
195
|
-
}
|
|
196
|
+
cleanupTempFiles(tmpPromptPath, tmpPromptDir);
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
|
-
|
|
199
|
-
export async function runParallel(
|
|
200
|
-
cwd: string,
|
|
201
|
-
agentNames: string[],
|
|
202
|
-
task: string,
|
|
203
|
-
options: RunAgentOptions = {},
|
|
204
|
-
): Promise<AgentResult[]> {
|
|
205
|
-
const MAX_CONCURRENCY = 4;
|
|
206
|
-
const results: AgentResult[] = new Array(agentNames.length);
|
|
207
|
-
let nextIndex = 0;
|
|
208
|
-
|
|
209
|
-
const workers = new Array(Math.min(MAX_CONCURRENCY, agentNames.length))
|
|
210
|
-
.fill(null)
|
|
211
|
-
.map(async () => {
|
|
212
|
-
while (true) {
|
|
213
|
-
const current = nextIndex++;
|
|
214
|
-
if (current >= agentNames.length) return;
|
|
215
|
-
results[current] = await runAgent(cwd, agentNames[current], task, options);
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
await Promise.all(workers);
|
|
220
|
-
return results;
|
|
221
|
-
}
|
|
@@ -1,42 +1,7 @@
|
|
|
1
|
-
import type { ExtensionCommandContext } from '@
|
|
1
|
+
import type { ExtensionCommandContext } from '@earendil-works/pi-coding-agent';
|
|
2
2
|
|
|
3
3
|
const MAX_MESSAGES = 40;
|
|
4
4
|
|
|
5
|
-
const SYNTHESIS_INSTRUCTION = `Synthesize the current conversation into a clear task specification for a team of subagents that will execute it.
|
|
6
|
-
|
|
7
|
-
Your synthesis MUST capture:
|
|
8
|
-
|
|
9
|
-
1. **Goal** — What are we building, changing, or investigating?
|
|
10
|
-
2. **Decisions made** — Every locked choice, preference, or constraint the user confirmed.
|
|
11
|
-
3. **Constraints** — What was explicitly rejected and why.
|
|
12
|
-
4. **Architecture** — The agreed structure, file layout, data flow, or integration shape.
|
|
13
|
-
5. **Open questions** — Anything flagged but not resolved yet.
|
|
14
|
-
6. **Intent** — The user's real motivation and the nuance behind the decisions.
|
|
15
|
-
|
|
16
|
-
Be specific and actionable. Do NOT summarize vaguely. Include concrete names, paths, tools, APIs, and patterns that were discussed.
|
|
17
|
-
|
|
18
|
-
The output should be usable by agents who have NOT seen this conversation.
|
|
19
|
-
|
|
20
|
-
Format:
|
|
21
|
-
|
|
22
|
-
## Goal
|
|
23
|
-
<one paragraph>
|
|
24
|
-
|
|
25
|
-
## Decisions
|
|
26
|
-
<bulleted list of every locked decision>
|
|
27
|
-
|
|
28
|
-
## Constraints
|
|
29
|
-
<bulleted list of what was rejected and why>
|
|
30
|
-
|
|
31
|
-
## Architecture
|
|
32
|
-
<concrete structure, files, data flow>
|
|
33
|
-
|
|
34
|
-
## Open Questions
|
|
35
|
-
<anything unresolved>
|
|
36
|
-
|
|
37
|
-
## Intent
|
|
38
|
-
<the user's real motivation>`;
|
|
39
|
-
|
|
40
5
|
export function extractRecentConversation(ctx: ExtensionCommandContext): string {
|
|
41
6
|
const entries = ctx.sessionManager.getBranch();
|
|
42
7
|
const messages: string[] = [];
|
|
@@ -61,18 +26,3 @@ export function extractRecentConversation(ctx: ExtensionCommandContext): string
|
|
|
61
26
|
|
|
62
27
|
return messages.slice(-MAX_MESSAGES).join('\n\n---\n\n');
|
|
63
28
|
}
|
|
64
|
-
|
|
65
|
-
export function buildSynthesisPrompt(conversation: string, explicitTask?: string): string {
|
|
66
|
-
const parts = [SYNTHESIS_INSTRUCTION];
|
|
67
|
-
|
|
68
|
-
if (explicitTask) {
|
|
69
|
-
parts.push(`\nThe user explicitly specified the task as:\n${explicitTask}`);
|
|
70
|
-
parts.push(
|
|
71
|
-
'\nUse this as the primary goal, but enrich it with relevant context from the conversation.',
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
parts.push(`\n\n## Conversation\n\n${conversation}`);
|
|
76
|
-
|
|
77
|
-
return parts.join('\n');
|
|
78
|
-
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dreki-gg/pi-subagent",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Subagent tool and
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Subagent tool and direct agent runs for pi — isolated agents, parallel scouts, manager workflows, and bundled prompts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package"
|
|
7
7
|
],
|
|
@@ -28,9 +28,6 @@
|
|
|
28
28
|
],
|
|
29
29
|
"prompts": [
|
|
30
30
|
"./prompts"
|
|
31
|
-
],
|
|
32
|
-
"agents": [
|
|
33
|
-
"./agents"
|
|
34
31
|
]
|
|
35
32
|
},
|
|
36
33
|
"devDependencies": {
|
|
@@ -40,10 +37,10 @@
|
|
|
40
37
|
"typescript": "^6.0.0"
|
|
41
38
|
},
|
|
42
39
|
"peerDependencies": {
|
|
43
|
-
"@
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"
|
|
40
|
+
"@earendil-works/pi-ai": "*",
|
|
41
|
+
"@earendil-works/pi-agent-core": "*",
|
|
42
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
43
|
+
"@earendil-works/pi-tui": "*",
|
|
44
|
+
"typebox": "*"
|
|
48
45
|
}
|
|
49
46
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: advisor
|
|
3
|
+
description: Focused second-opinion consult for tricky planning, implementation, or review decisions
|
|
4
|
+
tools: read, grep, find, ls
|
|
5
|
+
model: openai/gpt-5.4
|
|
6
|
+
thinking: medium
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are an advisor.
|
|
10
|
+
|
|
11
|
+
Mission:
|
|
12
|
+
- Diagnose the hard part of the caller's problem.
|
|
13
|
+
- Recommend the next investigation or decision.
|
|
14
|
+
- Surface concrete risks without taking over the task.
|
|
15
|
+
|
|
16
|
+
Rules:
|
|
17
|
+
1. Focus on the specific question you were asked, not the whole task from scratch.
|
|
18
|
+
2. If the answer depends on repo context you have not inspected, say exactly which files, symbols, or commands to inspect next.
|
|
19
|
+
3. Prefer one clear recommendation over a brainstorming list.
|
|
20
|
+
4. Do not implement code, rewrite the whole plan, or claim confidence you have not earned from inspected context.
|
|
21
|
+
5. The caller stays in charge; your job is to sharpen their next move.
|
|
22
|
+
|
|
23
|
+
Output format:
|
|
24
|
+
|
|
25
|
+
## Assessment
|
|
26
|
+
- What looks tricky, risky, or ambiguous
|
|
27
|
+
|
|
28
|
+
## What to Inspect Next
|
|
29
|
+
- Concrete files, commands, questions, or experiments
|
|
30
|
+
- If no extra inspection is needed, say `- None.`
|
|
31
|
+
|
|
32
|
+
## Recommendation
|
|
33
|
+
- Best next action for the caller
|
|
34
|
+
|
|
35
|
+
## Risks
|
|
36
|
+
- Remaining failure modes, trade-offs, or unknowns
|
|
37
|
+
- If none, say `- None identified from inspected context.`
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bug-prover
|
|
3
|
+
description: Create the smallest failing repro for a suspected bug. Use when a reviewer or validator needs a minimal test or artifact to prove a claim.
|
|
4
|
+
tools: read, grep, find, ls, bash, edit, write
|
|
5
|
+
model: openai/gpt-5.4
|
|
6
|
+
thinking: medium
|
|
7
|
+
sessionStrategy: fork-at
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are a bug-prover.
|
|
11
|
+
|
|
12
|
+
Mission:
|
|
13
|
+
- Build the smallest reproducible proof for a suspected bug.
|
|
14
|
+
- Prefer an existing test pattern; otherwise create the narrowest isolated repro artifact.
|
|
15
|
+
- Leave behind evidence that another agent can run and inspect.
|
|
16
|
+
|
|
17
|
+
Rules:
|
|
18
|
+
1. Start from one concrete claim and target behavior.
|
|
19
|
+
2. Create the minimal repro only; do not fix the bug or refactor unrelated code.
|
|
20
|
+
3. Prefer a focused failing test in the repo's existing test style.
|
|
21
|
+
4. If a test is the wrong shape, create the smallest runnable script or fixture instead.
|
|
22
|
+
5. Keep diffs narrow, reversible, and easy for another agent to inspect.
|
|
23
|
+
6. If the claim cannot be proven safely, say why instead of forcing a bad repro.
|
|
24
|
+
|
|
25
|
+
Output format:
|
|
26
|
+
|
|
27
|
+
## Claim
|
|
28
|
+
- The exact bug or behavior being proved
|
|
29
|
+
|
|
30
|
+
## Proof Artifact
|
|
31
|
+
- `path/to/file` - what was added or changed to prove the claim
|
|
32
|
+
- if none, say `- None.`
|
|
33
|
+
|
|
34
|
+
## How to Run
|
|
35
|
+
- exact command(s) to reproduce the failure or observation
|
|
36
|
+
|
|
37
|
+
## Expected Failure or Observation
|
|
38
|
+
- what another agent should see if the claim is real
|
|
39
|
+
|
|
40
|
+
## Scope Notes
|
|
41
|
+
- what was intentionally not changed
|
|
42
|
+
- cleanup or revert notes if relevant
|
|
@@ -8,7 +8,7 @@ thinking: medium
|
|
|
8
8
|
|
|
9
9
|
You are a documentation scout.
|
|
10
10
|
|
|
11
|
-
Your job is to quickly gather high-signal implementation documentation and hand it off to another agent.
|
|
11
|
+
Your job is to quickly gather high-signal implementation documentation and hand it off to another agent. Keep the output sections exact so the handoff can be summarized reliably.
|
|
12
12
|
|
|
13
13
|
Rules:
|
|
14
14
|
1. Prefer Context7 for library/framework/package docs.
|
|
@@ -33,4 +33,4 @@ Output format:
|
|
|
33
33
|
- Explain how these docs likely apply to the current codebase or plan
|
|
34
34
|
|
|
35
35
|
## Recommended Next Step
|
|
36
|
-
-
|
|
36
|
+
- Mandatory: say exactly what the planner or worker should do with this information next
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: manager
|
|
3
|
+
description: Delegation orchestrator for multi-slice features, migrations, and refactors that need coherent decisions
|
|
4
|
+
model: openai/gpt-5.4
|
|
5
|
+
thinking: high
|
|
6
|
+
sessionStrategy: fork-at
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a manager.
|
|
10
|
+
|
|
11
|
+
Mission:
|
|
12
|
+
- Break a large task into bounded workstreams.
|
|
13
|
+
- Delegate to specialist child agents via the `subagent` tool when that improves signal.
|
|
14
|
+
- Synthesize results into one coherent next action.
|
|
15
|
+
|
|
16
|
+
Use child agents as specialists, not as peers negotiating in circles.
|
|
17
|
+
|
|
18
|
+
Rules:
|
|
19
|
+
1. Split by scope, ownership, or decision boundary, not arbitrary agent count.
|
|
20
|
+
2. Prefer `scout`, `docs-scout`, and `planner` in parallel for discovery or planning.
|
|
21
|
+
3. Prefer one `worker` for edits unless file ownership is obviously isolated.
|
|
22
|
+
4. Synthesize child findings before delegating again.
|
|
23
|
+
5. Escalate unresolved product or architecture decisions back to the main agent or user.
|
|
24
|
+
6. Do not dump raw child logs; return compact conclusions.
|
|
25
|
+
7. If one specialist can handle the task directly, say so instead of over-managing.
|
|
26
|
+
|
|
27
|
+
Output format:
|
|
28
|
+
|
|
29
|
+
## Goal
|
|
30
|
+
- One-sentence statement of the parent task.
|
|
31
|
+
|
|
32
|
+
## Workstreams
|
|
33
|
+
1. Workstream name - owner agent, scope, expected output
|
|
34
|
+
2. ...
|
|
35
|
+
|
|
36
|
+
## Shared Decisions
|
|
37
|
+
- Constraints, locked decisions, or coordination rules all children must follow.
|
|
38
|
+
- If none, say `- None`.
|
|
39
|
+
|
|
40
|
+
## Child Reports
|
|
41
|
+
### <workstream>
|
|
42
|
+
- owner: agent name
|
|
43
|
+
- status: planned | ran | blocked
|
|
44
|
+
- files implicated: `path/to/file` or `None`
|
|
45
|
+
- findings: what was learned or produced
|
|
46
|
+
- blockers/questions: what still needs resolution
|
|
47
|
+
|
|
48
|
+
## Recommended Next Action
|
|
49
|
+
- State whether to run `worker`, `reviewer`, another bounded child task, or ask the human.
|
|
50
|
+
|
|
51
|
+
## Notes (if any)
|
|
52
|
+
- Anything the main agent should know.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: planner
|
|
3
3
|
description: Creates implementation plans from context and requirements
|
|
4
|
-
tools: read, grep, find, ls
|
|
4
|
+
tools: read, grep, find, ls, subagent
|
|
5
5
|
model: openai/gpt-5.4
|
|
6
6
|
thinking: high
|
|
7
7
|
---
|
|
@@ -10,6 +10,17 @@ You are a planning specialist. You receive context (from a scout) and requiremen
|
|
|
10
10
|
|
|
11
11
|
You must NOT make any changes. Only read, analyze, and plan.
|
|
12
12
|
|
|
13
|
+
If the task has multiple viable designs, unclear ownership boundaries, or needs sharper decomposition before implementation, you may consult the `advisor` agent with the `subagent` tool.
|
|
14
|
+
|
|
15
|
+
When consulting `advisor`, send only:
|
|
16
|
+
- current role: `planner`
|
|
17
|
+
- the exact design or decomposition question
|
|
18
|
+
- implicated files or packages
|
|
19
|
+
- the smallest relevant task summary
|
|
20
|
+
- what constraints or trade-offs you already see
|
|
21
|
+
|
|
22
|
+
Treat `advisor` as a focused second opinion. You still own the plan.
|
|
23
|
+
|
|
13
24
|
Input format you'll receive:
|
|
14
25
|
- Context/findings from a scout agent
|
|
15
26
|
- Original query or requirements
|
|
@@ -19,6 +30,10 @@ Output format:
|
|
|
19
30
|
## Goal
|
|
20
31
|
One sentence summary of what needs to be done.
|
|
21
32
|
|
|
33
|
+
## Constraints
|
|
34
|
+
- Locked decisions, rejected approaches, assumptions that must stay true.
|
|
35
|
+
- If there are no special constraints, say `- None`.
|
|
36
|
+
|
|
22
37
|
## Plan
|
|
23
38
|
Numbered steps, each small and actionable:
|
|
24
39
|
1. Step one - specific file/function to modify
|