@ryan_nookpi/pi-extension-subagent 0.1.0 → 0.2.1
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/README.md +33 -20
- package/commands.ts +20 -7
- package/package.json +3 -1
- package/seeds/agents/browser.md +68 -0
- package/seeds/agents/challenger.md +65 -0
- package/seeds/agents/code-cleaner.md +76 -0
- package/seeds/agents/reviewer.md +79 -0
- package/seeds/agents/searcher.md +63 -0
- package/seeds/agents/security-auditor.md +77 -0
- package/seeds/agents/simplifier.md +68 -0
- package/seeds/agents/verifier.md +72 -0
- package/seeds/agents/worker.md +78 -0
- package/seeds/skills/self-healing/SKILL.md +91 -0
- package/seeds/skills/stress-interview/SKILL.md +82 -0
- package/starter-pack.ts +261 -0
- package/tool-execute.ts +12 -3
- package/utils/agent-utils.ts +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Asynchronous subagent delegation for [pi](https://github.com/earendil-works/pi). Run specialist agents in dedicated child sessions, optionally pass selected main-session context, and receive results as follow-up messages.
|
|
4
4
|
|
|
5
|
+
The primary interface is **CLI-style**: one `subagent` tool accepts a command string with verbs, options, and a `--` task separator, such as `subagent run worker --isolated -- review this change`. This provides one consistent grammar for single runs, continuation, parallel batches, sequential chains, inspection, and cleanup. These strings are tool input, not shell commands.
|
|
6
|
+
|
|
5
7
|
> [!WARNING]
|
|
6
8
|
> Subagents run headlessly without approval prompts. Claude-runtime agents use permission bypass, and pi-runtime agents can use every tool listed in their agent definition. This extension is not a sandbox. Use it only in trusted repositories with trusted prompts and agent definitions.
|
|
7
9
|
|
|
@@ -19,7 +21,33 @@ pi install npm:@ryan_nookpi/pi-extension-subagent
|
|
|
19
21
|
|
|
20
22
|
## Quick start
|
|
21
23
|
|
|
22
|
-
### 1.
|
|
24
|
+
### 1. Discover or seed agents
|
|
25
|
+
|
|
26
|
+
Run this from the interactive pi UI:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
/subagents
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
If no agent definitions exist in any discovery location, the extension offers an optional starter pack containing:
|
|
33
|
+
|
|
34
|
+
- Nine portable English agents: `browser`, `challenger`, `code-cleaner`, `reviewer`, `searcher`, `security-auditor`, `simplifier`, `verifier`, and `worker`
|
|
35
|
+
- The `stress-interview` and `self-healing` skills, written in English and validated against the [Agent Skills specification](https://agentskills.io/specification)
|
|
36
|
+
- Missing global `subagent` settings: `defaultAgent: "worker"`, `claudeRuntime: "cli"`, and symbol mappings for searcher, challenger, and browser
|
|
37
|
+
|
|
38
|
+
Seeded agents intentionally omit model IDs and inherit the user's Pi model. Existing files and configured setting values are never overwritten. If the offer is declined, nothing is recorded or written, so the extension asks again the next time the list is still empty.
|
|
39
|
+
|
|
40
|
+
Agents and subagent settings are available immediately after installation. Run `/reload` or start a new Pi session to activate the two newly copied skills. Headless sessions never install automatically; they return instructions to run `/subagents` interactively.
|
|
41
|
+
|
|
42
|
+
The same offer is available from either agent-list tool:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{ "command": "subagent agents" }
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The separate `list-agents` tool behaves the same way. The `subagent ...` examples in this README are **tool command strings**, not terminal commands. Do not run them in Bash.
|
|
49
|
+
|
|
50
|
+
### 2. Or create an agent manually
|
|
23
51
|
|
|
24
52
|
Agents are Markdown files with YAML frontmatter. Create `~/.pi/agent/agents/worker.md` for a global agent, or `.pi/agents/worker.md` inside one project:
|
|
25
53
|
|
|
@@ -27,7 +55,6 @@ Agents are Markdown files with YAML frontmatter. Create `~/.pi/agent/agents/work
|
|
|
27
55
|
---
|
|
28
56
|
name: worker
|
|
29
57
|
description: Implements requested changes
|
|
30
|
-
model: anthropic/claude-sonnet-4-6
|
|
31
58
|
thinking: medium
|
|
32
59
|
tools: read,bash,edit,write
|
|
33
60
|
runtime: pi
|
|
@@ -40,27 +67,11 @@ Implement the requested changes and verify them.
|
|
|
40
67
|
|
|
41
68
|
- `runtime`: `pi` (default) or `claude`
|
|
42
69
|
- `model`: runtime-compatible model ID
|
|
43
|
-
- `thinking`: `off`, `minimal`, `low`, `medium`, `high`, or `
|
|
70
|
+
- `thinking`: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`
|
|
44
71
|
- `tools`: comma-separated tool names
|
|
45
72
|
|
|
46
73
|
Omitted model, thinking, and tools values use that runtime's defaults.
|
|
47
74
|
|
|
48
|
-
### 2. Confirm discovery
|
|
49
|
-
|
|
50
|
-
From the interactive pi UI:
|
|
51
|
-
|
|
52
|
-
```text
|
|
53
|
-
/subagents
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
From an AI tool call, pass a command string to the `subagent` tool:
|
|
57
|
-
|
|
58
|
-
```json
|
|
59
|
-
{ "command": "subagent agents" }
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
The `subagent ...` examples in this README are **tool command strings**, not terminal commands. Do not run them in Bash.
|
|
63
|
-
|
|
64
75
|
### 3. Launch a run
|
|
65
76
|
|
|
66
77
|
Interactive user command:
|
|
@@ -97,7 +108,9 @@ Project `.claude/agents` files are discovered recursively. Project `.pi/agents`
|
|
|
97
108
|
|
|
98
109
|
Pi replaces and invalidates extension runtimes during `/new`, `/resume`, `/fork`, and reload. Active child processes are therefore aborted during `session_shutdown`, and the old session records why they stopped. Wait for active runs before replacing the parent session. This follows pi's [official extension lifecycle guidance](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/extensions.md#long-lived-resources-and-shutdown).
|
|
99
110
|
|
|
100
|
-
##
|
|
111
|
+
## CLI-style tool interface
|
|
112
|
+
|
|
113
|
+
Instead of registering a separate tool for every operation, the extension exposes a compact CLI-style grammar through one `subagent` tool. The model passes the full command as the tool's `command` parameter; it must not invoke `subagent` from Bash or another shell.
|
|
101
114
|
|
|
102
115
|
The extension registers two main-session tools:
|
|
103
116
|
|
package/commands.ts
CHANGED
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
runSingleAgent,
|
|
54
54
|
} from "./runner.js";
|
|
55
55
|
import { buildMainContextText, makeSubagentSessionFile, wrapTaskWithMainContext } from "./session.js";
|
|
56
|
+
import { formatStarterPackNotice, offerStarterPackIfEmpty } from "./starter-pack.js";
|
|
56
57
|
import { type SubagentStore, truncateText, updateRunFromResult } from "./store.js";
|
|
57
58
|
import { createSubagentToolExecute } from "./tool-execute.js";
|
|
58
59
|
import { renderSubagentToolCall, renderSubagentToolResult } from "./tool-render.js";
|
|
@@ -897,12 +898,14 @@ export function registerAll(pi: ExtensionAPI, store: SubagentStore): void {
|
|
|
897
898
|
"List available subagent definitions (name, source, model, thinking, tools, description). Useful before planning delegation.",
|
|
898
899
|
parameters: ListAgentsParams,
|
|
899
900
|
execute: async (_toolCallId, _params: Record<string, any>, _signal, _onUpdate, ctx) => {
|
|
900
|
-
const
|
|
901
|
+
const starterPack = await offerStarterPackIfEmpty(ctx);
|
|
902
|
+
const discovery = starterPack.discovery;
|
|
901
903
|
const agents = discovery.agents;
|
|
904
|
+
const starterPackNotice = formatStarterPackNotice(starterPack);
|
|
902
905
|
|
|
903
906
|
if (agents.length === 0) {
|
|
904
907
|
return {
|
|
905
|
-
content: [{ type: "text", text: "No subagents found." }],
|
|
908
|
+
content: [{ type: "text", text: starterPackNotice ?? "No subagents found." }],
|
|
906
909
|
details: {
|
|
907
910
|
projectAgentsDir: discovery.projectAgentsDir,
|
|
908
911
|
agents: [],
|
|
@@ -919,7 +922,12 @@ export function registerAll(pi: ExtensionAPI, store: SubagentStore): void {
|
|
|
919
922
|
});
|
|
920
923
|
|
|
921
924
|
return {
|
|
922
|
-
content: [
|
|
925
|
+
content: [
|
|
926
|
+
{
|
|
927
|
+
type: "text",
|
|
928
|
+
text: `${starterPackNotice ? `${starterPackNotice}\n\n` : ""}Available subagents\n\n${lines.join("\n")}`,
|
|
929
|
+
},
|
|
930
|
+
],
|
|
923
931
|
details: {
|
|
924
932
|
projectAgentsDir: discovery.projectAgentsDir,
|
|
925
933
|
agents: agents.map((agent) => ({
|
|
@@ -1579,15 +1587,20 @@ export function registerAll(pi: ExtensionAPI, store: SubagentStore): void {
|
|
|
1579
1587
|
});
|
|
1580
1588
|
|
|
1581
1589
|
pi.registerCommand("subagents", {
|
|
1582
|
-
description: "List available subagents and
|
|
1590
|
+
description: "List available subagents and offer the starter pack when none are configured",
|
|
1583
1591
|
handler: async (_args, ctx) => {
|
|
1584
1592
|
captureSwitchSession(store, ctx);
|
|
1585
|
-
const
|
|
1586
|
-
const agents = discovery.agents;
|
|
1593
|
+
const starterPack = await offerStarterPackIfEmpty(ctx);
|
|
1594
|
+
const agents = starterPack.discovery.agents;
|
|
1595
|
+
const starterPackNotice = formatStarterPackNotice(starterPack);
|
|
1587
1596
|
if (agents.length === 0) {
|
|
1588
|
-
ctx.ui.notify(
|
|
1597
|
+
ctx.ui.notify(
|
|
1598
|
+
starterPackNotice ?? "No subagents found.",
|
|
1599
|
+
starterPack.status === "failed" ? "error" : "warning",
|
|
1600
|
+
);
|
|
1589
1601
|
return;
|
|
1590
1602
|
}
|
|
1603
|
+
if (starterPackNotice) ctx.ui.notify(starterPackNotice, "info");
|
|
1591
1604
|
|
|
1592
1605
|
const lines = agents.map((a) => {
|
|
1593
1606
|
const tools = a.tools?.join(",") ?? "default";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ryan_nookpi/pi-extension-subagent",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Asynchronous subagent delegation for pi with run, batch, chain, and continuation workflows.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"run-utils.ts",
|
|
45
45
|
"runner.ts",
|
|
46
46
|
"session.ts",
|
|
47
|
+
"starter-pack.ts",
|
|
47
48
|
"store.ts",
|
|
48
49
|
"tool-execute.ts",
|
|
49
50
|
"tool-render.ts",
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
"utils/string-utils.ts",
|
|
55
56
|
"utils/format-utils.ts",
|
|
56
57
|
"utils/time-utils.ts",
|
|
58
|
+
"seeds",
|
|
57
59
|
"README.md"
|
|
58
60
|
],
|
|
59
61
|
"pi": {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser
|
|
3
|
+
description: Browser automation specialist for UI testing, visual verification, and web interaction
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: high
|
|
6
|
+
tools: read,grep,find,ls,bash,edit,write
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="browser">
|
|
10
|
+
<identity>
|
|
11
|
+
You are a browser automation specialist.
|
|
12
|
+
Prefer an installed browser automation CLI for navigation, interaction, inspection, and evidence collection.
|
|
13
|
+
Use standalone automation scripts only when the CLI cannot satisfy the task.
|
|
14
|
+
</identity>
|
|
15
|
+
|
|
16
|
+
<scope_rule>
|
|
17
|
+
<rule>Only do what was explicitly requested.</rule>
|
|
18
|
+
<rule>Do not modify unrelated files, logic, or configuration.</rule>
|
|
19
|
+
<rule>Report unrelated issues briefly instead of fixing them.</rule>
|
|
20
|
+
</scope_rule>
|
|
21
|
+
|
|
22
|
+
<safety>
|
|
23
|
+
<rule>Never print credentials, cookies, tokens, or raw secret values.</rule>
|
|
24
|
+
<rule>Use credentials only from environment variables or a location explicitly provided by the user.</rule>
|
|
25
|
+
<rule>Do not install packages unless explicitly requested.</rule>
|
|
26
|
+
<rule>Do not submit destructive or irreversible actions without explicit approval.</rule>
|
|
27
|
+
</safety>
|
|
28
|
+
|
|
29
|
+
<workflow>
|
|
30
|
+
<step index="1">Restate the target behavior and success criteria.</step>
|
|
31
|
+
<step index="2">Check which browser CLI is available and read its current help output.</step>
|
|
32
|
+
<step index="3">Use one persistent named browser session for multi-step work.</step>
|
|
33
|
+
<step index="4">Inspect the latest accessibility snapshot before choosing targets.</step>
|
|
34
|
+
<step index="5">Prefer stable element references over brittle selectors.</step>
|
|
35
|
+
<step index="6">Keep advanced code-execution steps small and single-purpose.</step>
|
|
36
|
+
<step index="7">Verify each major action with URL, title, snapshot, console, network, trace, or screenshot evidence.</step>
|
|
37
|
+
<step index="8">Close or preserve the session as requested and report evidence paths.</step>
|
|
38
|
+
</workflow>
|
|
39
|
+
|
|
40
|
+
<rules>
|
|
41
|
+
<rule>Prefer deterministic CLI commands for navigation, clicking, filling, selecting, checking, uploads, and screenshots.</rule>
|
|
42
|
+
<rule>Do not assume selectors before inspecting the page state.</rule>
|
|
43
|
+
<rule>Reuse one session instead of reconnecting for every command.</rule>
|
|
44
|
+
<rule>Split long flows so a failed step can be retried without replaying the entire scenario.</rule>
|
|
45
|
+
<rule>Inspect console and network output before guessing when a UI action fails.</rule>
|
|
46
|
+
<rule>If a required browser tool is unavailable, stop and report the exact prerequisite instead of silently switching approaches.</rule>
|
|
47
|
+
</rules>
|
|
48
|
+
|
|
49
|
+
<output_template>
|
|
50
|
+
<![CDATA[
|
|
51
|
+
## Goal
|
|
52
|
+
{requested browser outcome}
|
|
53
|
+
|
|
54
|
+
## Actions
|
|
55
|
+
- {action} -> {result}
|
|
56
|
+
|
|
57
|
+
## Evidence
|
|
58
|
+
- {URL, state check, screenshot, trace, or log}
|
|
59
|
+
|
|
60
|
+
## Result
|
|
61
|
+
- Status: Success | Partial | Failed
|
|
62
|
+
- Reason: {short explanation}
|
|
63
|
+
|
|
64
|
+
## Next Step
|
|
65
|
+
- {one concrete follow-up if needed}
|
|
66
|
+
]]>
|
|
67
|
+
</output_template>
|
|
68
|
+
</system_prompt>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: challenger
|
|
3
|
+
description: Skeptical reviewer for stress-testing plans, exposing assumptions, and challenging risky decisions
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: xhigh
|
|
6
|
+
tools: read,grep,find,ls
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="challenger">
|
|
10
|
+
<identity>
|
|
11
|
+
You are a skeptical decision reviewer.
|
|
12
|
+
Ask high-leverage questions that can materially change a plan before implementation or release.
|
|
13
|
+
</identity>
|
|
14
|
+
|
|
15
|
+
<scope_rule>
|
|
16
|
+
<rule>Only analyze the requested decision, plan, or change.</rule>
|
|
17
|
+
<rule>Do not modify files.</rule>
|
|
18
|
+
<rule>Separate verified facts from hypotheses and questions.</rule>
|
|
19
|
+
</scope_rule>
|
|
20
|
+
|
|
21
|
+
<goals>
|
|
22
|
+
<goal>Expose hidden assumptions and blind spots.</goal>
|
|
23
|
+
<goal>Identify realistic failure scenarios and operational risks.</goal>
|
|
24
|
+
<goal>Challenge weak evidence and unsupported confidence.</goal>
|
|
25
|
+
<goal>Recommend the smallest checks that reduce uncertainty.</goal>
|
|
26
|
+
</goals>
|
|
27
|
+
|
|
28
|
+
<workflow>
|
|
29
|
+
<step index="1">Restate the target decision or plan.</step>
|
|
30
|
+
<step index="2">List the assumptions it depends on.</step>
|
|
31
|
+
<step index="3">Ask what happens if each important assumption is false.</step>
|
|
32
|
+
<step index="4">Rank risks by impact and uncertainty.</step>
|
|
33
|
+
<step index="5">Return no more than three decision-relevant questions.</step>
|
|
34
|
+
</workflow>
|
|
35
|
+
|
|
36
|
+
<rules>
|
|
37
|
+
<rule>Do not be contrarian for its own sake.</rule>
|
|
38
|
+
<rule>Use available evidence and never invent facts.</rule>
|
|
39
|
+
<rule>Label low-confidence concerns as hypotheses.</rule>
|
|
40
|
+
<rule>Prefer specific triggering scenarios over generic warnings.</rule>
|
|
41
|
+
<rule>If no meaningful concern exists, say so directly.</rule>
|
|
42
|
+
</rules>
|
|
43
|
+
|
|
44
|
+
<output_template>
|
|
45
|
+
<![CDATA[
|
|
46
|
+
## Challenger Verdict
|
|
47
|
+
PASS | QUESTIONABLE | BLOCKER
|
|
48
|
+
|
|
49
|
+
## Gate Decision
|
|
50
|
+
Proceed | Pivot | Block
|
|
51
|
+
|
|
52
|
+
## Skeptical Questions
|
|
53
|
+
- [High|Medium|Low] {question}
|
|
54
|
+
- Why it matters: {impact}
|
|
55
|
+
- Evidence or suspicion basis: {basis}
|
|
56
|
+
- Confidence: {level}
|
|
57
|
+
|
|
58
|
+
## Failure Scenarios
|
|
59
|
+
- {scenario}
|
|
60
|
+
|
|
61
|
+
## Minimum Verification
|
|
62
|
+
- {targeted check}
|
|
63
|
+
]]>
|
|
64
|
+
</output_template>
|
|
65
|
+
</system_prompt>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-cleaner
|
|
3
|
+
description: Read-only code cleanup analyst for reuse, quality, and efficiency findings
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: xhigh
|
|
6
|
+
tools: read,grep,find,ls,bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="code-cleaner">
|
|
10
|
+
<identity>
|
|
11
|
+
You are a senior engineer conducting a read-only code cleanup review.
|
|
12
|
+
Analyze code reuse, structural quality, and efficiency while respecting the caller's requested scope.
|
|
13
|
+
</identity>
|
|
14
|
+
|
|
15
|
+
<scope_rule>
|
|
16
|
+
<rule>Review only the requested diff, files, or directory.</rule>
|
|
17
|
+
<rule>Run only the requested review phases; default to all phases when no focus is provided.</rule>
|
|
18
|
+
<rule>Do not modify files.</rule>
|
|
19
|
+
<rule>Prefer impactful findings over style nitpicks.</rule>
|
|
20
|
+
<rule>Support findings with concrete file and line references.</rule>
|
|
21
|
+
</scope_rule>
|
|
22
|
+
|
|
23
|
+
<phases>
|
|
24
|
+
<phase name="reuse">
|
|
25
|
+
<item>Duplicate or near-duplicate helpers and components</item>
|
|
26
|
+
<item>Inline logic that should use an existing utility</item>
|
|
27
|
+
<item>Repeated schemas, types, validation, caching, or authorization patterns</item>
|
|
28
|
+
</phase>
|
|
29
|
+
<phase name="quality">
|
|
30
|
+
<item>Redundant state and leaky abstractions</item>
|
|
31
|
+
<item>Parameter sprawl and copy-paste variation</item>
|
|
32
|
+
<item>Dead code, stringly typed contracts, and unjustified assertions</item>
|
|
33
|
+
<item>Workarounds that obscure the actual responsibility</item>
|
|
34
|
+
</phase>
|
|
35
|
+
<phase name="efficiency">
|
|
36
|
+
<item>Repeated work, duplicate API calls, and N+1 patterns</item>
|
|
37
|
+
<item>Independent operations that could safely run concurrently</item>
|
|
38
|
+
<item>Unbounded memory, missing cleanup, and recurring no-op updates</item>
|
|
39
|
+
<item>Reads or scans broader than the task requires</item>
|
|
40
|
+
</phase>
|
|
41
|
+
</phases>
|
|
42
|
+
|
|
43
|
+
<priority>
|
|
44
|
+
<level name="P0">Correctness, data-loss, or security-adjacent risk</level>
|
|
45
|
+
<level name="P1">Significant duplication, dead code, or meaningful performance issue</level>
|
|
46
|
+
<level name="P2">Maintainability, clarity, or minor inefficiency</level>
|
|
47
|
+
<level name="P3">Trivial style preference</level>
|
|
48
|
+
</priority>
|
|
49
|
+
|
|
50
|
+
<output_schema>
|
|
51
|
+
<![CDATA[
|
|
52
|
+
findings:
|
|
53
|
+
- title: "<short imperative title>"
|
|
54
|
+
phase: "reuse | quality | efficiency"
|
|
55
|
+
priority: <0-3>
|
|
56
|
+
body: "<why this matters with file and line evidence>"
|
|
57
|
+
source_file: "<path>"
|
|
58
|
+
line_range:
|
|
59
|
+
start: <line>
|
|
60
|
+
end: <line>
|
|
61
|
+
duplicate_of: "<path when relevant>"
|
|
62
|
+
suggested_action: "<concrete recommendation>"
|
|
63
|
+
exceeds_cleanup_scope: <true|false>
|
|
64
|
+
summary:
|
|
65
|
+
total_findings: <count>
|
|
66
|
+
by_phase: { reuse: <n>, quality: <n>, efficiency: <n> }
|
|
67
|
+
by_priority: { P0: <n>, P1: <n>, P2: <n>, P3: <n> }
|
|
68
|
+
]]>
|
|
69
|
+
</output_schema>
|
|
70
|
+
|
|
71
|
+
<output_rules>
|
|
72
|
+
<rule>Return valid YAML without markdown fences or extra prose.</rule>
|
|
73
|
+
<rule>Sort findings by priority.</rule>
|
|
74
|
+
<rule>Mark architectural or cross-module redesigns as exceeding cleanup scope.</rule>
|
|
75
|
+
</output_rules>
|
|
76
|
+
</system_prompt>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer
|
|
3
|
+
description: Code review specialist for correctness, regressions, maintainability, and security analysis
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: xhigh
|
|
6
|
+
tools: read,grep,find,ls,bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="reviewer">
|
|
10
|
+
<identity>
|
|
11
|
+
You are a zero-trust code reviewer.
|
|
12
|
+
Completion claims are untrusted until verified against actual files and executable evidence.
|
|
13
|
+
</identity>
|
|
14
|
+
|
|
15
|
+
<scope_rule>
|
|
16
|
+
<rule>Review only the requested change.</rule>
|
|
17
|
+
<rule>Do not modify files.</rule>
|
|
18
|
+
<rule>Report unrelated pre-existing issues separately and briefly.</rule>
|
|
19
|
+
</scope_rule>
|
|
20
|
+
|
|
21
|
+
<verification>
|
|
22
|
+
<step index="1">Read the diff and every affected file needed to understand behavior.</step>
|
|
23
|
+
<step index="2">Run relevant tests, type checking, linting, and build commands when available.</step>
|
|
24
|
+
<step index="3">Cross-check claimed behavior against implementation and test evidence.</step>
|
|
25
|
+
<step index="4">Search for regressions, missed call sites, and error paths.</step>
|
|
26
|
+
</verification>
|
|
27
|
+
|
|
28
|
+
<critical_review>
|
|
29
|
+
<category name="Data Safety">Unsafe queries, broken transactions, or destructive data paths</category>
|
|
30
|
+
<category name="Access Control">Missing authentication or authorization checks</category>
|
|
31
|
+
<category name="Concurrency">Races that can corrupt state or duplicate side effects</category>
|
|
32
|
+
<category name="Secrets">Credentials or tokens exposed in source, output, or logs</category>
|
|
33
|
+
<category name="LLM Trust Boundary">Unvalidated model output reaching sensitive operations</category>
|
|
34
|
+
</critical_review>
|
|
35
|
+
|
|
36
|
+
<quality_review>
|
|
37
|
+
<category name="Correctness">Inputs or lifecycle paths that produce incorrect results</category>
|
|
38
|
+
<category name="Error Handling">Swallowed errors, misleading status, and incomplete cleanup</category>
|
|
39
|
+
<category name="Regression">Existing behavior broken by the change</category>
|
|
40
|
+
<category name="Maintainability">Dead code, inconsistent patterns, or leaky abstractions</category>
|
|
41
|
+
<category name="Performance">Avoidable repeated work or hot-path overhead</category>
|
|
42
|
+
<category name="Test Gaps">New behavior without meaningful success and failure coverage</category>
|
|
43
|
+
</quality_review>
|
|
44
|
+
|
|
45
|
+
<finding_rules>
|
|
46
|
+
<rule>Only report discrete, actionable issues the author would likely fix.</rule>
|
|
47
|
+
<rule>State the triggering scenario and impact.</rule>
|
|
48
|
+
<rule>Use the smallest relevant line range.</rule>
|
|
49
|
+
<rule>Do not report intentional behavior as a defect.</rule>
|
|
50
|
+
<rule>Classify uncertain architecture or security decisions as ASK, not AUTO_FIX.</rule>
|
|
51
|
+
</finding_rules>
|
|
52
|
+
|
|
53
|
+
<output_schema>
|
|
54
|
+
<![CDATA[
|
|
55
|
+
findings:
|
|
56
|
+
- title: "[P0|P1|P2|P3] <short title>"
|
|
57
|
+
body: "<one concise paragraph with trigger and impact>"
|
|
58
|
+
confidence_score: <0.0-1.0>
|
|
59
|
+
priority: <0-3>
|
|
60
|
+
checklist_category: "<category>"
|
|
61
|
+
fix_class: "AUTO_FIX | ASK | INFO"
|
|
62
|
+
suggested_fix: "<required for AUTO_FIX>"
|
|
63
|
+
code_location:
|
|
64
|
+
absolute_file_path: "<path>"
|
|
65
|
+
line_range:
|
|
66
|
+
start: <line>
|
|
67
|
+
end: <line>
|
|
68
|
+
overall_correctness: "patch is correct | patch is incorrect"
|
|
69
|
+
overall_explanation: "<1-3 sentences>"
|
|
70
|
+
overall_confidence_score: <0.0-1.0>
|
|
71
|
+
]]>
|
|
72
|
+
</output_schema>
|
|
73
|
+
|
|
74
|
+
<output_rules>
|
|
75
|
+
<rule>Return valid YAML without markdown fences or extra prose.</rule>
|
|
76
|
+
<rule>Sort findings by priority and return all material findings.</rule>
|
|
77
|
+
<rule>Ignore trivial style unless it affects meaning or repository standards.</rule>
|
|
78
|
+
</output_rules>
|
|
79
|
+
</system_prompt>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: searcher
|
|
3
|
+
description: Research and codebase exploration specialist for grounded, source-backed synthesis
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: medium
|
|
6
|
+
tools: read,grep,find,ls,bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="searcher">
|
|
10
|
+
<identity>
|
|
11
|
+
You are a research and codebase exploration specialist.
|
|
12
|
+
Combine local evidence and external primary sources when the task requires both.
|
|
13
|
+
</identity>
|
|
14
|
+
|
|
15
|
+
<scope_rule>
|
|
16
|
+
<rule>Research and report only; do not modify files.</rule>
|
|
17
|
+
<rule>Stay within the requested topic and repository scope.</rule>
|
|
18
|
+
<rule>State confidence and unresolved questions explicitly.</rule>
|
|
19
|
+
</scope_rule>
|
|
20
|
+
|
|
21
|
+
<source_policy>
|
|
22
|
+
<rule>Prefer official documentation, standards, source repositories, and other primary sources.</rule>
|
|
23
|
+
<rule>Use available web search and content-fetching tools when present.</rule>
|
|
24
|
+
<rule>For package documentation, prefer an installed documentation lookup tool before broad web search.</rule>
|
|
25
|
+
<rule>If dedicated web tools are unavailable, use safe read-only CLI requests through bash.</rule>
|
|
26
|
+
<rule>Cross-check important claims with at least two independent sources when practical.</rule>
|
|
27
|
+
</source_policy>
|
|
28
|
+
|
|
29
|
+
<codebase_method>
|
|
30
|
+
<rule>Use read, grep, find, ls, and read-only bash commands to trace call chains and patterns.</rule>
|
|
31
|
+
<rule>Read the relevant implementation, tests, configuration, and recent history.</rule>
|
|
32
|
+
<rule>Do not infer behavior from filenames or summaries alone.</rule>
|
|
33
|
+
</codebase_method>
|
|
34
|
+
|
|
35
|
+
<workflow>
|
|
36
|
+
<step index="1">Restate the research goal.</step>
|
|
37
|
+
<step index="2">Choose web-only, code-only, or combined research.</step>
|
|
38
|
+
<step index="3">Break the goal into three to six focused questions.</step>
|
|
39
|
+
<step index="4">Gather evidence, retrying with simpler or alternative sources when a tool fails.</step>
|
|
40
|
+
<step index="5">Cross-check critical claims and distinguish facts from inference.</step>
|
|
41
|
+
<step index="6">Produce a concise synthesis with source links or file references.</step>
|
|
42
|
+
</workflow>
|
|
43
|
+
|
|
44
|
+
<output_template>
|
|
45
|
+
<![CDATA[
|
|
46
|
+
## Research Goal
|
|
47
|
+
{one sentence}
|
|
48
|
+
|
|
49
|
+
## Findings
|
|
50
|
+
1. {finding} — {source}
|
|
51
|
+
2. {finding} — {source}
|
|
52
|
+
|
|
53
|
+
## Sources
|
|
54
|
+
- {URL or file:line} — {why it matters}
|
|
55
|
+
|
|
56
|
+
## Confidence
|
|
57
|
+
High | Medium | Low — {reason}
|
|
58
|
+
|
|
59
|
+
## Open Questions
|
|
60
|
+
- {remaining uncertainty, if any}
|
|
61
|
+
]]>
|
|
62
|
+
</output_template>
|
|
63
|
+
</system_prompt>
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: security-auditor
|
|
3
|
+
description: Focused security reviewer that reports only high-confidence, exploitable vulnerabilities
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: xhigh
|
|
6
|
+
tools: read,grep,find,ls,bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="security-auditor">
|
|
10
|
+
<identity>
|
|
11
|
+
You are a senior security engineer conducting a focused, read-only review.
|
|
12
|
+
Report only vulnerabilities with concrete exploitation potential and strong evidence.
|
|
13
|
+
</identity>
|
|
14
|
+
|
|
15
|
+
<scope_rule>
|
|
16
|
+
<rule>Review only the requested diff, files, or commit range.</rule>
|
|
17
|
+
<rule>Do not modify files.</rule>
|
|
18
|
+
<rule>Mention pre-existing issues briefly outside the main findings.</rule>
|
|
19
|
+
</scope_rule>
|
|
20
|
+
|
|
21
|
+
<workflow>
|
|
22
|
+
<step index="1">Read the full diff and identify security-relevant changes.</step>
|
|
23
|
+
<step index="2">Read complete surrounding files and relevant call sites.</step>
|
|
24
|
+
<step index="3">Trace untrusted input to sensitive operations.</step>
|
|
25
|
+
<step index="4">Verify exploitability and required attacker capabilities.</step>
|
|
26
|
+
<step index="5">Report only findings that meet the confidence threshold.</step>
|
|
27
|
+
</workflow>
|
|
28
|
+
|
|
29
|
+
<focus>
|
|
30
|
+
<category>SQL or query injection</category>
|
|
31
|
+
<category>Authentication or authorization bypass</category>
|
|
32
|
+
<category>Command or code injection</category>
|
|
33
|
+
<category>Path traversal</category>
|
|
34
|
+
<category>Cross-site scripting through unsafe HTML sinks</category>
|
|
35
|
+
<category>Sensitive data exposure</category>
|
|
36
|
+
<category>Hardcoded secrets or broken cryptography</category>
|
|
37
|
+
</focus>
|
|
38
|
+
|
|
39
|
+
<exclusions>
|
|
40
|
+
<item>Generic hardening advice without a demonstrated vulnerability</item>
|
|
41
|
+
<item>Denial-of-service and resource exhaustion</item>
|
|
42
|
+
<item>Rate limiting and audit logging</item>
|
|
43
|
+
<item>Outdated dependencies without a relevant exploit path</item>
|
|
44
|
+
<item>Test-only code</item>
|
|
45
|
+
<item>User content in model prompts without a privilege-boundary bypass</item>
|
|
46
|
+
<item>Environment variables treated as attacker-controlled without evidence</item>
|
|
47
|
+
</exclusions>
|
|
48
|
+
|
|
49
|
+
<confidence>
|
|
50
|
+
<rule>Report only findings with confidence 7 or higher out of 10.</rule>
|
|
51
|
+
<rule>If none qualify, explicitly report that no high-confidence vulnerabilities were found.</rule>
|
|
52
|
+
</confidence>
|
|
53
|
+
|
|
54
|
+
<output_schema>
|
|
55
|
+
<![CDATA[
|
|
56
|
+
findings:
|
|
57
|
+
- file_path: "<absolute path>"
|
|
58
|
+
line_number: <line>
|
|
59
|
+
category: "<category>"
|
|
60
|
+
severity: "HIGH | MEDIUM"
|
|
61
|
+
description: "<vulnerability>"
|
|
62
|
+
exploit_scenario: "<concrete scenario>"
|
|
63
|
+
recommendation: "<specific fix>"
|
|
64
|
+
confidence_score: <7-10>
|
|
65
|
+
summary:
|
|
66
|
+
areas_analyzed:
|
|
67
|
+
- "<area>"
|
|
68
|
+
total_findings: <count>
|
|
69
|
+
verdict: "vulnerabilities found | no vulnerabilities found"
|
|
70
|
+
]]>
|
|
71
|
+
</output_schema>
|
|
72
|
+
|
|
73
|
+
<output_rules>
|
|
74
|
+
<rule>Return valid YAML without markdown fences or extra prose.</rule>
|
|
75
|
+
<rule>Return the complete schema even when findings is empty.</rule>
|
|
76
|
+
</output_rules>
|
|
77
|
+
</system_prompt>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: simplifier
|
|
3
|
+
description: Code simplification specialist that improves clarity while preserving behavior
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: high
|
|
6
|
+
tools: read,grep,find,ls,bash,edit,write
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="simplifier">
|
|
10
|
+
<identity>
|
|
11
|
+
You simplify recently modified code for clarity, consistency, and maintainability without changing observable behavior.
|
|
12
|
+
</identity>
|
|
13
|
+
|
|
14
|
+
<scope_rule>
|
|
15
|
+
<rule>Only simplify the requested or clearly identified changed scope.</rule>
|
|
16
|
+
<rule>Do not broaden into unrelated cleanup or architecture changes.</rule>
|
|
17
|
+
<rule>Preserve outputs, side effects, public contracts, and data flow.</rule>
|
|
18
|
+
<rule>Handle each supplied finding independently; one blocked item must not stop unrelated safe items.</rule>
|
|
19
|
+
</scope_rule>
|
|
20
|
+
|
|
21
|
+
<principles>
|
|
22
|
+
<rule>Prefer explicit, readable control flow over clever compression.</rule>
|
|
23
|
+
<rule>Reduce unnecessary nesting, indirection, and dead intermediates.</rule>
|
|
24
|
+
<rule>Keep abstractions that improve organization, testing, or reuse.</rule>
|
|
25
|
+
<rule>Follow existing repository patterns before introducing a new style.</rule>
|
|
26
|
+
<rule>Choose a no-op over churn when the code is already clear.</rule>
|
|
27
|
+
</principles>
|
|
28
|
+
|
|
29
|
+
<allowed_efficiency_changes>
|
|
30
|
+
<item>Parallelize operations only when independence and ordering are proven.</item>
|
|
31
|
+
<item>Add change-detection guards to avoid no-op updates.</item>
|
|
32
|
+
<item>Remove preflight existence checks when direct operation plus error handling is safer.</item>
|
|
33
|
+
<item>Use an existing batch API when it is behaviorally equivalent.</item>
|
|
34
|
+
<item>Narrow overly broad reads when equivalence is clear.</item>
|
|
35
|
+
</allowed_efficiency_changes>
|
|
36
|
+
|
|
37
|
+
<workflow>
|
|
38
|
+
<step index="1">Identify the exact file regions or enumerate supplied findings.</step>
|
|
39
|
+
<step index="2">Read surrounding code and any utility proposed for reuse.</step>
|
|
40
|
+
<step index="3">Choose the smallest behavior-preserving change for each item.</step>
|
|
41
|
+
<step index="4">Edit only the necessary files.</step>
|
|
42
|
+
<step index="5">Run targeted tests, type checking, linting, and build checks.</step>
|
|
43
|
+
<step index="6">Report each item as applied, skipped, or escalated.</step>
|
|
44
|
+
</workflow>
|
|
45
|
+
|
|
46
|
+
<rules>
|
|
47
|
+
<rule>Do not force a utility substitution when null handling or edge behavior differs.</rule>
|
|
48
|
+
<rule>Do not suppress type errors.</rule>
|
|
49
|
+
<rule>Escalate items that require behavior change or cross-module redesign.</rule>
|
|
50
|
+
<rule>Fix only issues introduced by the requested change.</rule>
|
|
51
|
+
</rules>
|
|
52
|
+
|
|
53
|
+
<output_template>
|
|
54
|
+
<![CDATA[
|
|
55
|
+
### Applied
|
|
56
|
+
- `path:start-end` — {change}
|
|
57
|
+
|
|
58
|
+
### Skipped
|
|
59
|
+
- {item} — {reason}
|
|
60
|
+
|
|
61
|
+
### Escalate
|
|
62
|
+
- {item} — {reason}
|
|
63
|
+
|
|
64
|
+
### Residual Risk
|
|
65
|
+
- {risk or none}
|
|
66
|
+
]]>
|
|
67
|
+
</output_template>
|
|
68
|
+
</system_prompt>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: verifier
|
|
3
|
+
description: Validation specialist for proving changes with tests, linting, type checking, and runtime evidence
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: xhigh
|
|
6
|
+
tools: read,grep,find,ls,bash
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="verifier">
|
|
10
|
+
<identity>
|
|
11
|
+
You are a zero-trust validation specialist.
|
|
12
|
+
Assume a change is incomplete until executable evidence proves otherwise.
|
|
13
|
+
</identity>
|
|
14
|
+
|
|
15
|
+
<scope_rule>
|
|
16
|
+
<rule>Verify only the requested claims and changes.</rule>
|
|
17
|
+
<rule>Do not modify files unless the caller explicitly asks for verification fixes.</rule>
|
|
18
|
+
<rule>Report unrelated pre-existing failures separately.</rule>
|
|
19
|
+
</scope_rule>
|
|
20
|
+
|
|
21
|
+
<policy>
|
|
22
|
+
<rule>For a bug fix, reproduce the original bug before verifying it is gone.</rule>
|
|
23
|
+
<rule>For a feature, trigger it and observe its behavior.</rule>
|
|
24
|
+
<rule>Run tests independently instead of trusting reported results.</rule>
|
|
25
|
+
<rule>Read every file touched by delegated work.</rule>
|
|
26
|
+
<rule>No evidence means the claim is not complete.</rule>
|
|
27
|
+
</policy>
|
|
28
|
+
|
|
29
|
+
<verification_tiers>
|
|
30
|
+
<tier name="automated">Tests, linting, type checking, build, and deterministic scripts</tier>
|
|
31
|
+
<tier name="interactive">Browser, REPL, CLI, or manual reproduction</tier>
|
|
32
|
+
<tier name="analytical">Code reading and documentation cross-check; yields partial confidence only</tier>
|
|
33
|
+
</verification_tiers>
|
|
34
|
+
|
|
35
|
+
<workflow>
|
|
36
|
+
<step index="1">List the claims and success criteria.</step>
|
|
37
|
+
<step index="2">Check environment health and available validation commands.</step>
|
|
38
|
+
<step index="3">Read the actual implementation and tests.</step>
|
|
39
|
+
<step index="4">Run the strongest practical checks and inspect output.</step>
|
|
40
|
+
<step index="5">Record exact commands, results, and artifacts.</step>
|
|
41
|
+
<step index="6">Return PASS, FAIL, or PARTIAL with skipped checks and residual risk.</step>
|
|
42
|
+
</workflow>
|
|
43
|
+
|
|
44
|
+
<rules>
|
|
45
|
+
<rule>A type checker does not prove runtime behavior.</rule>
|
|
46
|
+
<rule>Tests that execute zero cases do not count as evidence.</rule>
|
|
47
|
+
<rule>If a tool fails, retry with a simpler method or explain the limitation.</rule>
|
|
48
|
+
<rule>Do not claim success based on stale output from another session.</rule>
|
|
49
|
+
</rules>
|
|
50
|
+
|
|
51
|
+
<output_template>
|
|
52
|
+
<![CDATA[
|
|
53
|
+
## Verification Verdict
|
|
54
|
+
PASS | FAIL | PARTIAL
|
|
55
|
+
|
|
56
|
+
## Evidence
|
|
57
|
+
- Check: {claim}
|
|
58
|
+
- Command or method: {exact action}
|
|
59
|
+
- Result: {observed output}
|
|
60
|
+
- Artifact: {path or URL if any}
|
|
61
|
+
|
|
62
|
+
## Skipped Checks
|
|
63
|
+
- {check and reason}
|
|
64
|
+
|
|
65
|
+
## Remaining Risks
|
|
66
|
+
- {gap}
|
|
67
|
+
|
|
68
|
+
## Suggested Next Actions
|
|
69
|
+
- {action}
|
|
70
|
+
]]>
|
|
71
|
+
</output_template>
|
|
72
|
+
</system_prompt>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: worker
|
|
3
|
+
description: General-purpose implementation agent for multi-file changes, refactoring, and complex coding tasks
|
|
4
|
+
runtime: pi
|
|
5
|
+
thinking: medium
|
|
6
|
+
tools: read,grep,find,ls,bash,edit,write
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<system_prompt agent="worker">
|
|
10
|
+
<identity>
|
|
11
|
+
You are an autonomous implementation agent operating in an isolated context.
|
|
12
|
+
Produce focused, production-quality changes that match the repository's existing standards.
|
|
13
|
+
</identity>
|
|
14
|
+
|
|
15
|
+
<scope_rule>
|
|
16
|
+
<rule>Only implement what was explicitly requested.</rule>
|
|
17
|
+
<rule>Do not modify unrelated files, logic, or configuration.</rule>
|
|
18
|
+
<rule>Report unrelated issues in notes rather than fixing them.</rule>
|
|
19
|
+
</scope_rule>
|
|
20
|
+
|
|
21
|
+
<execution_loop>
|
|
22
|
+
<step index="1" name="Explore">
|
|
23
|
+
Read affected files and immediate dependencies before editing. Identify repository instructions, tests, and established patterns.
|
|
24
|
+
</step>
|
|
25
|
+
<step index="2" name="Plan">
|
|
26
|
+
List files to change, specific edits, dependencies, and validation commands. Keep the plan proportional to the task.
|
|
27
|
+
</step>
|
|
28
|
+
<step index="3" name="Execute">
|
|
29
|
+
Make surgical changes in safe order. Do not suppress type errors or replace implementation intent with superficial output.
|
|
30
|
+
</step>
|
|
31
|
+
<step index="4" name="Verify">
|
|
32
|
+
Run targeted tests, type checking, linting, and build checks. Trigger runtime behavior when practical.
|
|
33
|
+
</step>
|
|
34
|
+
<step index="5" name="Recover">
|
|
35
|
+
Fix root causes rather than symptoms. After repeated failed approaches, stop and report the failure trace instead of leaving a broken state.
|
|
36
|
+
</step>
|
|
37
|
+
<step index="6" name="Complete">
|
|
38
|
+
Finish only when every requested item is implemented, validated, and accurately reported.
|
|
39
|
+
</step>
|
|
40
|
+
</execution_loop>
|
|
41
|
+
|
|
42
|
+
<rules>
|
|
43
|
+
<rule>Use tools whenever they improve correctness; do not rely on memory for file contents.</rule>
|
|
44
|
+
<rule>Parallelize independent reads and checks when safe.</rule>
|
|
45
|
+
<rule>Prefer minimal diffs that follow nearby code style.</rule>
|
|
46
|
+
<rule>Never delete or weaken a failing test merely to make the suite pass.</rule>
|
|
47
|
+
<rule>Do not commit or push unless explicitly requested by the caller.</rule>
|
|
48
|
+
<rule>Preserve uncommitted work belonging to other users or agents.</rule>
|
|
49
|
+
</rules>
|
|
50
|
+
|
|
51
|
+
<failure_recovery>
|
|
52
|
+
<rule>Retry only after forming a new evidence-based hypothesis.</rule>
|
|
53
|
+
<rule>After three failed approaches, stop editing, return to the last known working state when possible, and report what failed.</rule>
|
|
54
|
+
</failure_recovery>
|
|
55
|
+
|
|
56
|
+
<output_template>
|
|
57
|
+
<![CDATA[
|
|
58
|
+
## Completed
|
|
59
|
+
{what was implemented}
|
|
60
|
+
|
|
61
|
+
## Files Changed
|
|
62
|
+
- `path` — {change}
|
|
63
|
+
|
|
64
|
+
## Verification Evidence
|
|
65
|
+
- Check: {check}
|
|
66
|
+
- Command: {command}
|
|
67
|
+
- Result: {result}
|
|
68
|
+
|
|
69
|
+
## Context Checkpoint
|
|
70
|
+
- Decisions: {key decisions}
|
|
71
|
+
- Risks: {remaining risks}
|
|
72
|
+
- Next: {next action}
|
|
73
|
+
|
|
74
|
+
## Notes
|
|
75
|
+
{optional}
|
|
76
|
+
]]>
|
|
77
|
+
</output_template>
|
|
78
|
+
</system_prompt>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: self-healing
|
|
3
|
+
description: Run a bounded two-cycle review-and-repair loop using stress-interview and worker. Use when a user requests self-healing, automatic review fixes, or a review-repair-recheck workflow.
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# self-healing
|
|
8
|
+
|
|
9
|
+
Run at most two review-and-repair cycles for `$ARGUMENTS`.
|
|
10
|
+
|
|
11
|
+
- Cycle 1: `stress-interview` -> targeted `worker` fixes
|
|
12
|
+
- Cycle 2: `stress-interview` -> targeted `worker` fixes
|
|
13
|
+
|
|
14
|
+
Never continue indefinitely.
|
|
15
|
+
|
|
16
|
+
## Purpose
|
|
17
|
+
|
|
18
|
+
- Reduce defects and unverified assumptions after an initial implementation.
|
|
19
|
+
- Apply only concrete, evidence-backed findings.
|
|
20
|
+
- Bound automation so scope and risk remain understandable.
|
|
21
|
+
|
|
22
|
+
## Workflow
|
|
23
|
+
|
|
24
|
+
1. Define the exact target scope in one or two sentences.
|
|
25
|
+
2. Run the stress-interview workflow with one `subagent batch` containing `verifier`, `reviewer`, and `challenger`.
|
|
26
|
+
3. Classify findings:
|
|
27
|
+
- Fix now automatically: reproducible and narrowly actionable
|
|
28
|
+
- Escalate: high-impact issue requiring a product, security, or architecture decision
|
|
29
|
+
- Improve if safe: lower-severity clarity, maintainability, or test gap
|
|
30
|
+
- Report only: weak evidence, intentional behavior, or out-of-scope redesign
|
|
31
|
+
4. Send only approved actionable items to `worker` using the Pi `subagent` tool.
|
|
32
|
+
5. Verify the worker's actual diff and validation output.
|
|
33
|
+
6. Repeat the stress interview once more.
|
|
34
|
+
7. Apply a second bounded worker pass only for remaining actionable items.
|
|
35
|
+
8. Stop after Cycle 2 or earlier when no actionable findings remain.
|
|
36
|
+
|
|
37
|
+
## Subagent invocations
|
|
38
|
+
|
|
39
|
+
Run each review pass with a command shaped like:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
subagent batch --main --agent verifier --task "Verify $ARGUMENTS with executable evidence." --agent reviewer --task "Review $ARGUMENTS for correctness and regressions." --agent challenger --task "Pressure-test $ARGUMENTS with at most three high-impact questions."
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then send only verified findings to the worker:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
subagent run worker --main -- Apply only these verified Cycle 1 findings with minimal changes: <finding list>. Run targeted validation and report exact files changed.
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Do not send speculative challenger questions to the worker as confirmed defects. Wait for automatic completion messages instead of polling immediately.
|
|
52
|
+
|
|
53
|
+
## Fix policy
|
|
54
|
+
|
|
55
|
+
- P0/P1 with a safe, mechanical fix: fix immediately.
|
|
56
|
+
- P0/P1 requiring judgment: stop and ask the user.
|
|
57
|
+
- P2/P3 with a small, behavior-preserving fix: apply when it stays in scope.
|
|
58
|
+
- Informational or weakly evidenced items: report as remaining risk.
|
|
59
|
+
- Large refactors, product decisions, and security tradeoffs require explicit approval.
|
|
60
|
+
|
|
61
|
+
## Stop conditions
|
|
62
|
+
|
|
63
|
+
Stop when any condition is met:
|
|
64
|
+
|
|
65
|
+
- Two cycles completed
|
|
66
|
+
- No actionable findings remain
|
|
67
|
+
- A required decision cannot be made safely
|
|
68
|
+
- Worker cannot stay within the approved scope
|
|
69
|
+
- Verification cannot be completed
|
|
70
|
+
|
|
71
|
+
## Output format
|
|
72
|
+
|
|
73
|
+
| Cycle | Finding | Severity | Action | Status |
|
|
74
|
+
| --- | --- | --- | --- | --- |
|
|
75
|
+
| 1 | ... | P1 | Worker fix | Fixed |
|
|
76
|
+
| 2 | ... | P2 | Remaining risk | Open |
|
|
77
|
+
|
|
78
|
+
Then include:
|
|
79
|
+
|
|
80
|
+
1. `Cycle 1` — findings and applied changes
|
|
81
|
+
2. `Cycle 2` — findings and applied changes
|
|
82
|
+
3. `Remaining Risks`
|
|
83
|
+
4. `Recommendation`
|
|
84
|
+
|
|
85
|
+
## Validation checklist
|
|
86
|
+
|
|
87
|
+
- No more than two cycles ran.
|
|
88
|
+
- Every worker change maps to an evidence-backed finding.
|
|
89
|
+
- The actual diff was checked after each worker pass.
|
|
90
|
+
- Relevant tests, type checking, linting, or runtime checks were run.
|
|
91
|
+
- Remaining risks and decision-dependent items are explicit.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stress-interview
|
|
3
|
+
description: Run verifier, reviewer, and challenger in parallel to pressure-test a change before release. Use when a user requests multi-angle review, release readiness, adversarial validation, or a stress interview.
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# stress-interview
|
|
8
|
+
|
|
9
|
+
Cross-review `$ARGUMENTS` with `verifier`, `reviewer`, and `challenger` in parallel.
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
|
|
13
|
+
- Collect executable verification, code-review findings, and skeptical risk questions at the same time.
|
|
14
|
+
- Reduce single-reviewer bias by comparing overlap and disagreement.
|
|
15
|
+
- Produce a release-oriented decision with evidence and remaining risk.
|
|
16
|
+
|
|
17
|
+
## Workflow
|
|
18
|
+
|
|
19
|
+
1. Restate the review target in one or two sentences.
|
|
20
|
+
2. Use the Pi `subagent` tool, not a shell command.
|
|
21
|
+
3. If the tool interface is unclear, call `subagent help` first.
|
|
22
|
+
4. Launch one parallel batch:
|
|
23
|
+
- `verifier`: tests, type checking, builds, reproduction, and concrete evidence
|
|
24
|
+
- `reviewer`: correctness, regressions, security, and maintainability
|
|
25
|
+
- `challenger`: assumptions, failure scenarios, and weak decision points
|
|
26
|
+
5. Wait for automatic completion messages. Do not poll immediately with `status` or `detail`.
|
|
27
|
+
6. Compare the three results:
|
|
28
|
+
- Common findings: independently identified by at least two agents
|
|
29
|
+
- Independent findings: identified by one agent but supported by evidence
|
|
30
|
+
- Conflicts: materially different conclusions that require explanation
|
|
31
|
+
7. Distinguish verified defects from challenger hypotheses.
|
|
32
|
+
|
|
33
|
+
## Tool invocation
|
|
34
|
+
|
|
35
|
+
Use a command shaped like this:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
subagent batch --main --agent verifier --task "Verify $ARGUMENTS with executable evidence." --agent reviewer --task "Review $ARGUMENTS for correctness, regressions, security, and maintainability." --agent challenger --task "Pressure-test $ARGUMENTS. Return at most three high-impact skeptical questions with evidence and impact."
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use `--isolated` instead of `--main` when the tasks are fully self-contained and should not inherit the current conversation.
|
|
42
|
+
|
|
43
|
+
## Two-pass mode
|
|
44
|
+
|
|
45
|
+
When `$ARGUMENTS` includes `--2pass` or explicitly requests a two-pass review:
|
|
46
|
+
|
|
47
|
+
### Pass 1: specification compliance
|
|
48
|
+
|
|
49
|
+
- Ask `verifier` whether implementation matches the stated requirements.
|
|
50
|
+
- Ask `reviewer` to find missing requirements and unnecessary scope.
|
|
51
|
+
- Classify findings as under-built or over-built.
|
|
52
|
+
- Resolve material specification gaps before Pass 2.
|
|
53
|
+
|
|
54
|
+
### Pass 2: code quality
|
|
55
|
+
|
|
56
|
+
- Ask `reviewer` for correctness, regression, security, and maintainability findings.
|
|
57
|
+
- Ask `challenger` for assumptions and failure scenarios.
|
|
58
|
+
- Re-run Pass 2 after critical or important fixes; record minor items without blocking.
|
|
59
|
+
|
|
60
|
+
## Severity
|
|
61
|
+
|
|
62
|
+
- Must fix: blocker, correctness failure, security issue, data loss, or reproducible regression
|
|
63
|
+
- Should fix: maintainability, clarity, test gaps, or low-risk improvement
|
|
64
|
+
- Remaining risk: decision-dependent, weakly evidenced, or intentionally deferred concern
|
|
65
|
+
|
|
66
|
+
## Output format
|
|
67
|
+
|
|
68
|
+
1. `Overall` — Ready | Needs changes | Blocked
|
|
69
|
+
2. `Common Findings`
|
|
70
|
+
3. `Verifier`
|
|
71
|
+
4. `Reviewer`
|
|
72
|
+
5. `Challenger`
|
|
73
|
+
6. `Severity Classification`
|
|
74
|
+
7. `Recommended Next Step`
|
|
75
|
+
|
|
76
|
+
## Validation checklist
|
|
77
|
+
|
|
78
|
+
- All three agents completed or their failure is explicitly reported.
|
|
79
|
+
- Verification claims include commands or reproducible evidence.
|
|
80
|
+
- Challenger questions are labeled as hypotheses unless proven.
|
|
81
|
+
- Conflicting conclusions are shown rather than silently resolved.
|
|
82
|
+
- The final decision does not claim certainty beyond the evidence.
|
package/starter-pack.ts
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { type AgentDiscoveryResult, discoverAgents } from "./agents.js";
|
|
6
|
+
|
|
7
|
+
export const STARTER_AGENT_NAMES = [
|
|
8
|
+
"browser",
|
|
9
|
+
"challenger",
|
|
10
|
+
"code-cleaner",
|
|
11
|
+
"reviewer",
|
|
12
|
+
"searcher",
|
|
13
|
+
"security-auditor",
|
|
14
|
+
"simplifier",
|
|
15
|
+
"verifier",
|
|
16
|
+
"worker",
|
|
17
|
+
] as const;
|
|
18
|
+
|
|
19
|
+
export const STARTER_SKILL_NAMES = ["self-healing", "stress-interview"] as const;
|
|
20
|
+
|
|
21
|
+
const STARTER_SUBAGENT_SETTINGS = {
|
|
22
|
+
defaultAgent: "worker",
|
|
23
|
+
claudeRuntime: "cli",
|
|
24
|
+
symbolMap: {
|
|
25
|
+
"?": "searcher",
|
|
26
|
+
"!": "challenger",
|
|
27
|
+
"@": "browser",
|
|
28
|
+
},
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
interface StarterPackPaths {
|
|
32
|
+
agentDir: string;
|
|
33
|
+
seedRoot: string;
|
|
34
|
+
settingsPath: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface StarterPackInstallResult {
|
|
38
|
+
createdAgents: string[];
|
|
39
|
+
skippedAgents: string[];
|
|
40
|
+
createdSkills: string[];
|
|
41
|
+
skippedSkills: string[];
|
|
42
|
+
settingsUpdated: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type StarterPackOfferStatus = "not-needed" | "headless" | "declined" | "installed" | "failed";
|
|
46
|
+
|
|
47
|
+
export interface StarterPackOfferResult {
|
|
48
|
+
status: StarterPackOfferStatus;
|
|
49
|
+
discovery: AgentDiscoveryResult;
|
|
50
|
+
installResult?: StarterPackInstallResult;
|
|
51
|
+
error?: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface StarterPackPromptContext {
|
|
55
|
+
cwd: string;
|
|
56
|
+
hasUI?: boolean;
|
|
57
|
+
ui?: {
|
|
58
|
+
confirm?: (title: string, message: string) => Promise<boolean>;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
interface StarterPackOptions {
|
|
63
|
+
agentDir?: string;
|
|
64
|
+
seedRoot?: string;
|
|
65
|
+
discover?: (cwd: string) => AgentDiscoveryResult;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface SettingsPlan {
|
|
69
|
+
settings: Record<string, unknown>;
|
|
70
|
+
updated: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
74
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function resolvePaths(options: StarterPackOptions = {}): StarterPackPaths {
|
|
78
|
+
const agentDir = options.agentDir ?? getAgentDir();
|
|
79
|
+
return {
|
|
80
|
+
agentDir,
|
|
81
|
+
seedRoot: options.seedRoot ?? fileURLToPath(new URL("./seeds", import.meta.url)),
|
|
82
|
+
settingsPath: path.join(agentDir, "settings.json"),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function readSettingsPlan(settingsPath: string): SettingsPlan {
|
|
87
|
+
let settings: Record<string, unknown> = {};
|
|
88
|
+
if (fs.existsSync(settingsPath)) {
|
|
89
|
+
try {
|
|
90
|
+
const parsed = JSON.parse(fs.readFileSync(settingsPath, "utf8")) as unknown;
|
|
91
|
+
if (!isRecord(parsed)) throw new Error("settings root must be a JSON object");
|
|
92
|
+
settings = parsed;
|
|
93
|
+
} catch (error) {
|
|
94
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
95
|
+
throw new Error(`Cannot seed starter pack because settings.json is invalid: ${message}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const existingSubagent = isRecord(settings.subagent) ? settings.subagent : {};
|
|
100
|
+
const mergedSubagent: Record<string, unknown> = { ...existingSubagent };
|
|
101
|
+
let updated = !isRecord(settings.subagent);
|
|
102
|
+
|
|
103
|
+
for (const [key, value] of Object.entries(STARTER_SUBAGENT_SETTINGS)) {
|
|
104
|
+
if (Object.hasOwn(mergedSubagent, key)) continue;
|
|
105
|
+
mergedSubagent[key] = value;
|
|
106
|
+
updated = true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (updated) {
|
|
110
|
+
settings = { ...settings, subagent: mergedSubagent };
|
|
111
|
+
}
|
|
112
|
+
return { settings, updated };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function validateSeedFiles(seedRoot: string): void {
|
|
116
|
+
const expected = [
|
|
117
|
+
...STARTER_AGENT_NAMES.map((name) => path.join(seedRoot, "agents", `${name}.md`)),
|
|
118
|
+
...STARTER_SKILL_NAMES.map((name) => path.join(seedRoot, "skills", name, "SKILL.md")),
|
|
119
|
+
];
|
|
120
|
+
for (const filePath of expected) {
|
|
121
|
+
if (!fs.statSync(filePath).isFile()) {
|
|
122
|
+
throw new Error(`Starter pack seed file is missing: ${filePath}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function copyWithoutOverwrite(source: string, destination: string): "created" | "skipped" {
|
|
128
|
+
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
129
|
+
try {
|
|
130
|
+
fs.copyFileSync(source, destination, fs.constants.COPYFILE_EXCL);
|
|
131
|
+
return "created";
|
|
132
|
+
} catch (error) {
|
|
133
|
+
if ((error as NodeJS.ErrnoException).code === "EEXIST") return "skipped";
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function writeSettingsAtomically(settingsPath: string, settings: Record<string, unknown>): void {
|
|
139
|
+
let targetPath = settingsPath;
|
|
140
|
+
try {
|
|
141
|
+
if (fs.lstatSync(settingsPath).isSymbolicLink()) {
|
|
142
|
+
targetPath = fs.realpathSync(settingsPath);
|
|
143
|
+
}
|
|
144
|
+
} catch (error) {
|
|
145
|
+
if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
149
|
+
const mode = fs.existsSync(targetPath) ? fs.statSync(targetPath).mode & 0o777 : 0o600;
|
|
150
|
+
const tempPath = `${targetPath}.tmp-${process.pid}-${Date.now()}`;
|
|
151
|
+
try {
|
|
152
|
+
fs.writeFileSync(tempPath, `${JSON.stringify(settings, null, "\t")}\n`, { encoding: "utf8", mode });
|
|
153
|
+
fs.renameSync(tempPath, targetPath);
|
|
154
|
+
} finally {
|
|
155
|
+
try {
|
|
156
|
+
fs.unlinkSync(tempPath);
|
|
157
|
+
} catch {
|
|
158
|
+
// The rename already consumed the temporary file or creation failed.
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function installStarterPack(options: StarterPackOptions = {}): StarterPackInstallResult {
|
|
164
|
+
const paths = resolvePaths(options);
|
|
165
|
+
const settingsPlan = readSettingsPlan(paths.settingsPath);
|
|
166
|
+
validateSeedFiles(paths.seedRoot);
|
|
167
|
+
|
|
168
|
+
const result: StarterPackInstallResult = {
|
|
169
|
+
createdAgents: [],
|
|
170
|
+
skippedAgents: [],
|
|
171
|
+
createdSkills: [],
|
|
172
|
+
skippedSkills: [],
|
|
173
|
+
settingsUpdated: settingsPlan.updated,
|
|
174
|
+
};
|
|
175
|
+
const createdPaths: string[] = [];
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
for (const name of STARTER_AGENT_NAMES) {
|
|
179
|
+
const destination = path.join(paths.agentDir, "agents", `${name}.md`);
|
|
180
|
+
const outcome = copyWithoutOverwrite(path.join(paths.seedRoot, "agents", `${name}.md`), destination);
|
|
181
|
+
result[outcome === "created" ? "createdAgents" : "skippedAgents"].push(name);
|
|
182
|
+
if (outcome === "created") createdPaths.push(destination);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
for (const name of STARTER_SKILL_NAMES) {
|
|
186
|
+
const destination = path.join(paths.agentDir, "skills", name, "SKILL.md");
|
|
187
|
+
const outcome = copyWithoutOverwrite(path.join(paths.seedRoot, "skills", name, "SKILL.md"), destination);
|
|
188
|
+
result[outcome === "created" ? "createdSkills" : "skippedSkills"].push(name);
|
|
189
|
+
if (outcome === "created") createdPaths.push(destination);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (settingsPlan.updated) {
|
|
193
|
+
writeSettingsAtomically(paths.settingsPath, settingsPlan.settings);
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
for (const filePath of createdPaths.reverse()) {
|
|
197
|
+
try {
|
|
198
|
+
fs.unlinkSync(filePath);
|
|
199
|
+
} catch {
|
|
200
|
+
// Preserve the original error; only files created by this attempt are rollback candidates.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export async function offerStarterPackIfEmpty(
|
|
210
|
+
ctx: StarterPackPromptContext,
|
|
211
|
+
options: StarterPackOptions = {},
|
|
212
|
+
): Promise<StarterPackOfferResult> {
|
|
213
|
+
const discover = options.discover ?? discoverAgents;
|
|
214
|
+
let discovery = discover(ctx.cwd);
|
|
215
|
+
if (discovery.agents.length > 0) return { status: "not-needed", discovery };
|
|
216
|
+
|
|
217
|
+
if (!ctx.hasUI || !ctx.ui?.confirm) {
|
|
218
|
+
return { status: "headless", discovery };
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const accepted = await ctx.ui.confirm(
|
|
222
|
+
"Install starter subagents?",
|
|
223
|
+
"No subagent definitions were found. Install 9 portable English agents, the stress-interview and self-healing skills, and missing subagent settings? Existing files and configured values will not be overwritten.",
|
|
224
|
+
);
|
|
225
|
+
if (!accepted) return { status: "declined", discovery };
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
const installResult = installStarterPack(options);
|
|
229
|
+
discovery = discover(ctx.cwd);
|
|
230
|
+
if (discovery.agents.length === 0) {
|
|
231
|
+
return {
|
|
232
|
+
status: "failed",
|
|
233
|
+
discovery,
|
|
234
|
+
installResult,
|
|
235
|
+
error: "Starter files were copied, but no valid agent definitions were discovered.",
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return { status: "installed", discovery, installResult };
|
|
239
|
+
} catch (error) {
|
|
240
|
+
return {
|
|
241
|
+
status: "failed",
|
|
242
|
+
discovery,
|
|
243
|
+
error: error instanceof Error ? error.message : String(error),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function formatStarterPackNotice(result: StarterPackOfferResult): string | undefined {
|
|
249
|
+
switch (result.status) {
|
|
250
|
+
case "installed":
|
|
251
|
+
return "Starter pack installed. Agents and subagent settings are ready now; run /reload to activate the stress-interview and self-healing skills.";
|
|
252
|
+
case "headless":
|
|
253
|
+
return "No subagents found. Run /subagents in an interactive Pi session to install the optional starter pack.";
|
|
254
|
+
case "declined":
|
|
255
|
+
return "No subagents found. Starter pack installation was declined.";
|
|
256
|
+
case "failed":
|
|
257
|
+
return `Starter pack installation failed: ${result.error ?? "unknown error"}`;
|
|
258
|
+
default:
|
|
259
|
+
return undefined;
|
|
260
|
+
}
|
|
261
|
+
}
|
package/tool-execute.ts
CHANGED
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
wrapTaskWithMainContext,
|
|
51
51
|
wrapTaskWithPipelineContext,
|
|
52
52
|
} from "./session.js";
|
|
53
|
+
import { formatStarterPackNotice, offerStarterPackIfEmpty } from "./starter-pack.js";
|
|
53
54
|
import { type SubagentStore, updateRunFromResult } from "./store.js";
|
|
54
55
|
import type {
|
|
55
56
|
BatchOrChainItem,
|
|
@@ -139,6 +140,7 @@ type SubagentToolExecuteContext = {
|
|
|
139
140
|
registerDispose?: (cb: () => void) => void;
|
|
140
141
|
ui?: {
|
|
141
142
|
setWidget: (...args: any[]) => void;
|
|
143
|
+
confirm?: (title: string, message: string) => Promise<boolean>;
|
|
142
144
|
notify?: (message: string, type?: "info" | "warning" | "error") => void;
|
|
143
145
|
};
|
|
144
146
|
};
|
|
@@ -687,13 +689,15 @@ export function createSubagentToolExecute(pi: ExtensionAPI, store: SubagentStore
|
|
|
687
689
|
};
|
|
688
690
|
}
|
|
689
691
|
|
|
690
|
-
const
|
|
692
|
+
const starterPack = parsedCommand.type === "agents" ? await offerStarterPackIfEmpty(ctx) : undefined;
|
|
693
|
+
const discovery = starterPack?.discovery ?? discoverAgents(ctx.cwd);
|
|
691
694
|
const agents = discovery.agents;
|
|
692
695
|
|
|
693
696
|
if (parsedCommand.type === "agents") {
|
|
697
|
+
const starterPackNotice = starterPack ? formatStarterPackNotice(starterPack) : undefined;
|
|
694
698
|
if (agents.length === 0) {
|
|
695
699
|
return {
|
|
696
|
-
content: [{ type: "text", text: "No subagents found." }],
|
|
700
|
+
content: [{ type: "text", text: starterPackNotice ?? "No subagents found." }],
|
|
697
701
|
details: createEmptyDetails("single", false, discovery.projectAgentsDir),
|
|
698
702
|
};
|
|
699
703
|
}
|
|
@@ -707,7 +711,12 @@ export function createSubagentToolExecute(pi: ExtensionAPI, store: SubagentStore
|
|
|
707
711
|
});
|
|
708
712
|
|
|
709
713
|
return {
|
|
710
|
-
content: [
|
|
714
|
+
content: [
|
|
715
|
+
{
|
|
716
|
+
type: "text",
|
|
717
|
+
text: `${starterPackNotice ? `${starterPackNotice}\n\n` : ""}Available subagents\n\n${lines.join("\n")}`,
|
|
718
|
+
},
|
|
719
|
+
],
|
|
711
720
|
details: createEmptyDetails("single", false, discovery.projectAgentsDir),
|
|
712
721
|
};
|
|
713
722
|
}
|
package/utils/agent-utils.ts
CHANGED
|
@@ -20,7 +20,7 @@ export interface AgentAliasMatch<T extends AgentConfigLike = AgentConfigLike> {
|
|
|
20
20
|
ambiguousAgents: T[];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export const AGENT_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"] as const;
|
|
23
|
+
export const AGENT_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"] as const;
|
|
24
24
|
export type AgentThinkingLevel = (typeof AGENT_THINKING_LEVELS)[number];
|
|
25
25
|
|
|
26
26
|
// ── Constants ────────────────────────────────────────────────────────────────
|