@msdavid/pi-distro 0.2.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/CHANGELOG.md +54 -0
- package/LICENSE +21 -0
- package/README.md +394 -0
- package/docs/authoring.md +238 -0
- package/docs/preview.png +0 -0
- package/docs/preview.svg +58 -0
- package/extensions/catalogue.ts +221 -0
- package/extensions/deploy.ts +141 -0
- package/extensions/frontmatter.ts +158 -0
- package/extensions/github.ts +110 -0
- package/extensions/index.ts +86 -0
- package/extensions/info.ts +133 -0
- package/extensions/pick.ts +132 -0
- package/extensions/resolve.ts +70 -0
- package/extensions/save.ts +217 -0
- package/extensions/show.ts +96 -0
- package/extensions/undeploy.ts +124 -0
- package/extensions/update.ts +109 -0
- package/extensions/util.ts +44 -0
- package/harnesses/minimal/README.md +21 -0
- package/harnesses/minimal/files/AGENTS.md +20 -0
- package/harnesses/minimal/files/settings.json +4 -0
- package/harnesses/minimal/harness.md +24 -0
- package/harnesses/pi-distro-one/README.md +50 -0
- package/harnesses/pi-distro-one/files/.pi/extensions/claude-statusline.ts +220 -0
- package/harnesses/pi-distro-one/files/AGENTS.md +166 -0
- package/harnesses/pi-distro-one/files/settings.json +9 -0
- package/harnesses/pi-distro-one/harness.md +79 -0
- package/harnesses/web-fullstack/README.md +25 -0
- package/harnesses/web-fullstack/files/.pi/prompts/review.md +12 -0
- package/harnesses/web-fullstack/files/AGENTS.md +37 -0
- package/harnesses/web-fullstack/files/settings.json +11 -0
- package/harnesses/web-fullstack/harness.md +40 -0
- package/package.json +65 -0
- package/skills/pi-distro/SKILL.md +359 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# pi-distro-one
|
|
2
|
+
|
|
3
|
+
A complete Claude Code–style coding agent configuration for pi. The primary capability is
|
|
4
|
+
spawning and coordinating autonomous sub-agents; everything else — web research, browser
|
|
5
|
+
automation, live shell, model routing, task management — is integrated in support of that.
|
|
6
|
+
|
|
7
|
+
This is a personal draft shot at using the most popular pi coding packages to closely
|
|
8
|
+
resemble the capabilities of Claude Code. It's opinionated and not for everyone — but it
|
|
9
|
+
makes a great starting point to fork and make your own.
|
|
10
|
+
|
|
11
|
+
## What it sets up
|
|
12
|
+
|
|
13
|
+
- **`AGENTS.md`** — an explore-before-acting working methodology: investigate before
|
|
14
|
+
implementing, surface interpretations and tradeoffs, make surgical changes, keep
|
|
15
|
+
solutions simple, execute against verifiable goals, and treat documentation as part of
|
|
16
|
+
the implementation.
|
|
17
|
+
- **`.pi/settings.json`** — high thinking level, one-at-a-time steering, hidden thinking
|
|
18
|
+
blocks, and hardware cursor.
|
|
19
|
+
- **`.pi/extensions/claude-statusline.ts`** — a Claude-style status-line footer
|
|
20
|
+
(model | dir | thinking level | context-window bar gauge + cache % | git branch status).
|
|
21
|
+
Auto-enables on session start and **auto-expands tool outputs** (the Ctrl+O effect) so
|
|
22
|
+
full output is visible by default. Toggle with the `/claude-statusline` command.
|
|
23
|
+
|
|
24
|
+
## Packages installed (all project-local)
|
|
25
|
+
|
|
26
|
+
| Package | What it does |
|
|
27
|
+
|---------|-------------|
|
|
28
|
+
| `npm:@tintinweb/pi-subagents` | Claude Code–style autonomous sub-agents — spawn specialized agents in isolated sessions with own tools/prompt/model/thinking; parallel execution, live widget, mid-run steering, resumption (**primary capability**) |
|
|
29
|
+
| `npm:pi-web-access` | Web search, URL fetching, GitHub cloning, PDF/video extraction |
|
|
30
|
+
| `npm:pi-agent-browser-native` | Real browser automation and web interaction |
|
|
31
|
+
| `npm:pi-bash-live-view` | Live terminal rendering for shell commands |
|
|
32
|
+
| `npm:@yeliu84/pi-model-router` | Model routing / fallback across providers |
|
|
33
|
+
| `npm:@robhowley/pi-openrouter` | OpenRouter provider integration |
|
|
34
|
+
| `npm:@juicesharp/rpiv-todo` | Task list management |
|
|
35
|
+
| `npm:pi-goal` | Persistent autonomous goals — `/goal` loops until complete, paused, or budget-limited |
|
|
36
|
+
| `npm:@trevonistrevon/pi-loop` | Cron/event-based agent re-wake loops + background process monitoring — schedule agents to re-wake on time/events |
|
|
37
|
+
| `npm:@juicesharp/rpiv-ask-user-question` | Structured questionnaire the model puts to the user (typed options instead of guessing) |
|
|
38
|
+
|
|
39
|
+
## Prerequisites
|
|
40
|
+
|
|
41
|
+
- **Auth and model routing** are not part of this distro — configure those independently
|
|
42
|
+
(e.g. set `defaultProvider` and `defaultModel` in your global `~/.pi/settings.json`,
|
|
43
|
+
or use OpenRouter via the `@robhowley/pi-openrouter` package installed above).
|
|
44
|
+
- **Restart pi** after deploying — packages and extensions load at startup.
|
|
45
|
+
|
|
46
|
+
## When to use
|
|
47
|
+
|
|
48
|
+
- You want a Claude Code–like experience in pi.
|
|
49
|
+
- You work on complex tasks that benefit from multi-agent coordination.
|
|
50
|
+
- You want an opinionated, batteries-included setup to fork and customize.
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude-style status line for pi.
|
|
3
|
+
*
|
|
4
|
+
* Clones the Claude Code footer format:
|
|
5
|
+
* <model> | <dir> | <style> | [████████░░] 80% | 45% cached | <branch (status)>
|
|
6
|
+
*
|
|
7
|
+
* - model : active model name/id
|
|
8
|
+
* - dir : basename of ctx.cwd
|
|
9
|
+
* - style : current thinking level (pi's analog of Claude's "output style")
|
|
10
|
+
* - context : UTF-8 bar gauge of context-window usage (eighths resolution),
|
|
11
|
+
* colored by level (accent → warning → error), plus usage % and
|
|
12
|
+
* cache-read % (same token math as the Claude Code statusLine
|
|
13
|
+
* command in ~/.claude/settings.json)
|
|
14
|
+
* - git : branch from footerData + dirty(!)/untracked(?) markers, refreshed
|
|
15
|
+
* in the background so render() never spawns a process
|
|
16
|
+
*
|
|
17
|
+
* Auto-enables on session start. Also auto-expands tool outputs on session start
|
|
18
|
+
* (the Ctrl+O effect) so full output is visible by default. Toggle the status line
|
|
19
|
+
* with the /claude-statusline command.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { execSync } from "node:child_process";
|
|
23
|
+
import { basename } from "node:path";
|
|
24
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
25
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
26
|
+
import { truncateToWidth } from "@earendil-works/pi-tui";
|
|
27
|
+
|
|
28
|
+
const REFRESH_MS = 2000;
|
|
29
|
+
|
|
30
|
+
/** Eighth-block characters for sub-cell bar precision (index = eighths, 0 = empty). */
|
|
31
|
+
const EIGHTHS = ["", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"];
|
|
32
|
+
const BAR_WIDTH = 10;
|
|
33
|
+
|
|
34
|
+
interface GitCache {
|
|
35
|
+
branch: string | null;
|
|
36
|
+
dirty: boolean;
|
|
37
|
+
untracked: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default function (pi: ExtensionAPI) {
|
|
41
|
+
let enabled = false;
|
|
42
|
+
let timer: ReturnType<typeof setInterval> | undefined;
|
|
43
|
+
let gitCache: GitCache = { branch: null, dirty: false, untracked: false };
|
|
44
|
+
|
|
45
|
+
function refreshGit(cwd: string): void {
|
|
46
|
+
try {
|
|
47
|
+
// One porcelain call gives us both dirty (staged/modified) and untracked flags.
|
|
48
|
+
const out = execSync("git status --porcelain=v1 -z", {
|
|
49
|
+
cwd,
|
|
50
|
+
encoding: "utf8",
|
|
51
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
52
|
+
timeout: 1500,
|
|
53
|
+
});
|
|
54
|
+
let dirty = false;
|
|
55
|
+
let untracked = false;
|
|
56
|
+
// -z separates records with NUL. Each record: <XY><space><path>\0...
|
|
57
|
+
const records = out.split("\0").filter((r) => r.length > 0);
|
|
58
|
+
for (const rec of records) {
|
|
59
|
+
const xy = rec.slice(0, 2);
|
|
60
|
+
if (xy === "??") {
|
|
61
|
+
untracked = true;
|
|
62
|
+
} else {
|
|
63
|
+
dirty = true;
|
|
64
|
+
}
|
|
65
|
+
if (dirty && untracked) break;
|
|
66
|
+
}
|
|
67
|
+
gitCache = { ...gitCache, dirty, untracked };
|
|
68
|
+
} catch {
|
|
69
|
+
// Not a git repo, or git unavailable — clear flags.
|
|
70
|
+
gitCache = { ...gitCache, dirty: false, untracked: false };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function startTimer(ctx: ExtensionContext): void {
|
|
75
|
+
stopTimer();
|
|
76
|
+
refreshGit(ctx.cwd);
|
|
77
|
+
timer = setInterval(() => refreshGit(ctx.cwd), REFRESH_MS);
|
|
78
|
+
// Don't keep the event loop alive solely for footer refreshes.
|
|
79
|
+
if (timer && typeof timer.unref === "function") timer.unref();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function stopTimer(): void {
|
|
83
|
+
if (timer) {
|
|
84
|
+
clearInterval(timer);
|
|
85
|
+
timer = undefined;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Render a fixed-width UTF-8 bar gauge for a fraction in [0,1].
|
|
91
|
+
* Filled cells use full blocks; the boundary cell uses an eighth-block for
|
|
92
|
+
* sub-cell precision. Returns [filled, empty] strings for separate coloring.
|
|
93
|
+
*/
|
|
94
|
+
function barGauge(fraction: number): { filled: string; empty: string } {
|
|
95
|
+
const clamped = Math.max(0, Math.min(1, fraction));
|
|
96
|
+
const totalEighths = Math.round(clamped * BAR_WIDTH * 8);
|
|
97
|
+
const fullCells = Math.floor(totalEighths / 8);
|
|
98
|
+
const remainder = totalEighths % 8;
|
|
99
|
+
const filled = "█".repeat(fullCells) + (remainder > 0 ? EIGHTHS[remainder] : "");
|
|
100
|
+
const filledWidth = fullCells + (remainder > 0 ? 1 : 0);
|
|
101
|
+
const empty = "░".repeat(Math.max(0, BAR_WIDTH - filledWidth));
|
|
102
|
+
return { filled, empty };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function enable(ctx: ExtensionContext): void {
|
|
106
|
+
enabled = true;
|
|
107
|
+
startTimer(ctx);
|
|
108
|
+
|
|
109
|
+
ctx.ui.setFooter((tui, theme, footerData) => {
|
|
110
|
+
const unsub = footerData.onBranchChange(() => {
|
|
111
|
+
gitCache = { ...gitCache, branch: footerData.getGitBranch() };
|
|
112
|
+
tui.requestRender();
|
|
113
|
+
});
|
|
114
|
+
gitCache = { ...gitCache, branch: footerData.getGitBranch() };
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
dispose: () => {
|
|
118
|
+
unsub();
|
|
119
|
+
stopTimer();
|
|
120
|
+
},
|
|
121
|
+
invalidate() {},
|
|
122
|
+
render(width: number): string[] {
|
|
123
|
+
const segments: string[] = [];
|
|
124
|
+
|
|
125
|
+
// 1. Model
|
|
126
|
+
const model = ctx.model;
|
|
127
|
+
segments.push(theme.fg("accent", model?.name ?? model?.id ?? "no-model"));
|
|
128
|
+
|
|
129
|
+
// 2. Cwd basename
|
|
130
|
+
segments.push(theme.fg("dim", basename(ctx.cwd) || ctx.cwd));
|
|
131
|
+
|
|
132
|
+
// 3. Style -> thinking level (pi's analog of output style).
|
|
133
|
+
// getThinkingLevel() lives on the ExtensionAPI (pi), not on ctx.
|
|
134
|
+
segments.push(theme.fg("dim", pi.getThinkingLevel()));
|
|
135
|
+
|
|
136
|
+
// 4. Context: bar gauge + usage % + cache %.
|
|
137
|
+
// Use pi's own context estimate (ctx.getContextUsage) — it represents the
|
|
138
|
+
// current context size of the most recent request, matching Claude Code's
|
|
139
|
+
// `context_window.current_usage`. Summing per-message usage would double-
|
|
140
|
+
// count, since each request's input already includes prior context.
|
|
141
|
+
const usage = ctx.getContextUsage();
|
|
142
|
+
const usedPct = usage?.percent ?? 0;
|
|
143
|
+
|
|
144
|
+
// Cache-read % comes from the last assistant message's usage (the most
|
|
145
|
+
// recent request): cacheRead / (input + cacheWrite + cacheRead).
|
|
146
|
+
let cachePct = 0;
|
|
147
|
+
const branch = ctx.sessionManager.getBranch();
|
|
148
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
149
|
+
const e = branch[i];
|
|
150
|
+
if (e.type === "message" && e.message.role === "assistant") {
|
|
151
|
+
const u = (e.message as AssistantMessage).usage;
|
|
152
|
+
const totalInput = u.input + u.cacheWrite + u.cacheRead;
|
|
153
|
+
cachePct = totalInput > 0 ? Math.floor((u.cacheRead * 100) / totalInput) : 0;
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const { filled, empty } = barGauge(usedPct / 100);
|
|
159
|
+
const barColor = usedPct >= 95 ? "error" : usedPct >= 80 ? "warning" : "accent";
|
|
160
|
+
const bar = theme.fg(barColor, filled) + theme.fg("dim", empty);
|
|
161
|
+
const pctLabel = theme.fg("dim", `${Math.floor(usedPct)}%`);
|
|
162
|
+
|
|
163
|
+
let ctxInfo = `${bar} ${pctLabel}`;
|
|
164
|
+
if (cachePct > 0) ctxInfo += theme.fg("dim", ` | ${cachePct}% cached`);
|
|
165
|
+
segments.push(ctxInfo);
|
|
166
|
+
|
|
167
|
+
// 5. Git: branch (!dirty ?untracked)
|
|
168
|
+
if (gitCache.branch) {
|
|
169
|
+
let status = "";
|
|
170
|
+
if (gitCache.dirty) status += "!";
|
|
171
|
+
if (gitCache.untracked) status += "?";
|
|
172
|
+
const gitInfo = status ? `${gitCache.branch} (${status})` : gitCache.branch;
|
|
173
|
+
segments.push(theme.fg("dim", gitInfo));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Join with dim separators.
|
|
177
|
+
const sep = theme.fg("muted", " | ");
|
|
178
|
+
const line = segments.join(sep);
|
|
179
|
+
|
|
180
|
+
return [truncateToWidth(line, width)];
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function disable(ctx: ExtensionContext): void {
|
|
187
|
+
enabled = false;
|
|
188
|
+
stopTimer();
|
|
189
|
+
ctx.ui.setFooter(undefined);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Auto-enable on every (re)start, and auto-expand tool outputs (the Ctrl+O effect).
|
|
193
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
194
|
+
enable(ctx);
|
|
195
|
+
ctx.ui.setToolsExpanded(true);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
pi.on("session_shutdown", async (_event, _ctx) => {
|
|
199
|
+
stopTimer();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Refresh git right after a turn settles (catches file writes from the agent).
|
|
203
|
+
pi.on("turn_end", async (_event, ctx) => {
|
|
204
|
+
if (enabled) refreshGit(ctx.cwd);
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// Manual toggle.
|
|
208
|
+
pi.registerCommand("claude-statusline", {
|
|
209
|
+
description: "Toggle the Claude-style status line footer",
|
|
210
|
+
handler: async (_args, ctx) => {
|
|
211
|
+
if (enabled) {
|
|
212
|
+
disable(ctx);
|
|
213
|
+
ctx.ui.notify("Claude status line: off", "info");
|
|
214
|
+
} else {
|
|
215
|
+
enable(ctx);
|
|
216
|
+
ctx.ui.notify("Claude status line: on", "info");
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Quick Rules
|
|
2
|
+
|
|
3
|
+
- Never commit or push until I explicitly ask
|
|
4
|
+
- **Always update documentation** when planning, implementing, or refactoring
|
|
5
|
+
- Update README, docs/, inline comments, docstrings, and any related docs
|
|
6
|
+
- Include documentation updates as explicit steps in plans
|
|
7
|
+
- **EYU** = Explain Your Understanding of the request and wait for approval
|
|
8
|
+
- Example: User says "EYU" → Summarize what you understood, then stop and wait
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Approach to Changes
|
|
13
|
+
|
|
14
|
+
Before planning or implementing any changes, adopt a "deep researcher" mindset.
|
|
15
|
+
|
|
16
|
+
## Core Principle
|
|
17
|
+
|
|
18
|
+
**Understand before you act.** Don't jump to implementation. Your first instinct should be to explore the codebase, not to write code.
|
|
19
|
+
|
|
20
|
+
## Surface, Don't Hide
|
|
21
|
+
|
|
22
|
+
- **Present interpretations, don't pick silently.** If a request has more than one reasonable reading, lay them out and let me choose.
|
|
23
|
+
- **Surface tradeoffs and push back.** If a simpler approach exists, say so. If the request seems wrong or overcomplicated, challenge it before building it.
|
|
24
|
+
- **Name confusion instead of papering over it.** If something is still unclear after investigating, stop and say exactly what's confusing.
|
|
25
|
+
- Investigate what the code can answer (see "When uncertain, investigate more"); *ask* only about genuine intent or scope ambiguity the code can't resolve.
|
|
26
|
+
|
|
27
|
+
## When to Explore vs Plan
|
|
28
|
+
|
|
29
|
+
- **Always explore first** before any plan or implementation
|
|
30
|
+
- **Default behavior**: Explore → Implement
|
|
31
|
+
- **When user says "EYU"**: Explain understanding → Wait for approval → Explore → Plan/Implement
|
|
32
|
+
|
|
33
|
+
## Before Any Task
|
|
34
|
+
|
|
35
|
+
1. **Find existing examples first.** Use grep, glob, or read files to locate similar features. Study at least 2-3 examples of how comparable things are implemented before proposing changes.
|
|
36
|
+
|
|
37
|
+
2. **Map the full surface area.** For any change, actively investigate:
|
|
38
|
+
- How are similar things structured and named? (conventions, patterns)
|
|
39
|
+
- What's the full lifecycle? (creation, registration, configuration, persistence, cleanup)
|
|
40
|
+
- What are all integration points? (UI, menus, context menus, commands, keybindings, APIs)
|
|
41
|
+
- What files document this? (README, docs/, inline comments, docstrings)
|
|
42
|
+
- What tests exist for similar features? How do they test this kind of thing?
|
|
43
|
+
- What registries, configs, or manifests need updating?
|
|
44
|
+
|
|
45
|
+
3. **Learn the local conventions.** Every codebase has its own patterns. Discover them before writing new code. Match the existing style exactly.
|
|
46
|
+
|
|
47
|
+
4. **Think in systems.** A request to "add X" means "integrate X into the existing system." Understand the system's architecture first.
|
|
48
|
+
|
|
49
|
+
5. **When uncertain, investigate more.** Read more files. Run the code. Check tests. Don't guess—know.
|
|
50
|
+
|
|
51
|
+
6. **Update all documentation.** Treat documentation as part of the implementation, not an afterthought. Update README, docs/, docstrings, inline comments, and any related documentation files. If the change affects public APIs, update their documentation first.
|
|
52
|
+
|
|
53
|
+
## In Practice
|
|
54
|
+
|
|
55
|
+
When given a task:
|
|
56
|
+
- Start by exploring, not planning (unless SYP is requested)
|
|
57
|
+
- Use tools to read related code before proposing changes
|
|
58
|
+
- List all affected files/areas before making edits
|
|
59
|
+
- Identify all documentation that needs updating (README, docs/, docstrings, comments)
|
|
60
|
+
- Ask clarifying questions if the scope seems larger than implied
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
# Implementation Principles
|
|
65
|
+
|
|
66
|
+
Once you understand the task, these govern how you write the code.
|
|
67
|
+
|
|
68
|
+
## Simplicity First
|
|
69
|
+
|
|
70
|
+
Write the minimum code that solves the problem. Nothing speculative.
|
|
71
|
+
|
|
72
|
+
- No features beyond what was asked.
|
|
73
|
+
- No abstractions for single-use code.
|
|
74
|
+
- No "flexibility" or "configurability" I didn't request.
|
|
75
|
+
- No error handling for scenarios that can't actually happen.
|
|
76
|
+
- If you wrote 200 lines and it could be 50, rewrite it.
|
|
77
|
+
- Gut check: *"Would a senior engineer call this overcomplicated?"* If yes, simplify.
|
|
78
|
+
|
|
79
|
+
(This is about not writing unnecessary code; the File Size Limits below are about splitting code that has already grown too large — a different problem.)
|
|
80
|
+
|
|
81
|
+
## Surgical Changes
|
|
82
|
+
|
|
83
|
+
Touch only what you must. Clean up only your own mess.
|
|
84
|
+
|
|
85
|
+
When editing existing code:
|
|
86
|
+
- Don't "improve" adjacent code, comments, or formatting.
|
|
87
|
+
- Don't refactor things that aren't broken.
|
|
88
|
+
- If you notice unrelated dead code, *mention* it — don't delete it.
|
|
89
|
+
- (Matching existing style is already required under "Learn the local conventions" — it holds here too, even when you'd do it differently.)
|
|
90
|
+
|
|
91
|
+
When your changes create orphans:
|
|
92
|
+
- Remove imports/variables/functions that *your* changes made unused.
|
|
93
|
+
- Don't remove pre-existing dead code unless I ask.
|
|
94
|
+
|
|
95
|
+
**The test:** every changed line should trace directly to my request.
|
|
96
|
+
|
|
97
|
+
## Goal-Driven Execution
|
|
98
|
+
|
|
99
|
+
Define success criteria up front, then loop until they're verified.
|
|
100
|
+
|
|
101
|
+
Turn vague tasks into verifiable goals:
|
|
102
|
+
- "Add validation" → write tests for invalid inputs, then make them pass.
|
|
103
|
+
- "Fix the bug" → write a test that reproduces it, then make it pass.
|
|
104
|
+
- "Refactor X" → confirm tests pass before and after.
|
|
105
|
+
|
|
106
|
+
For multi-step work, state a brief plan with a check per step:
|
|
107
|
+
1. [Step] → verify: [check]
|
|
108
|
+
2. [Step] → verify: [check]
|
|
109
|
+
|
|
110
|
+
Strong success criteria let you loop independently; weak ones ("make it work") force constant clarification — so define them precisely. (those gate *whether* you start; success criteria define *when you're done*.)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
# Code Quality Guidelines
|
|
115
|
+
|
|
116
|
+
## File Size Limits
|
|
117
|
+
|
|
118
|
+
| Type | Warning | Consider Split | Must Split |
|
|
119
|
+
|------|---------|----------------|------------|
|
|
120
|
+
| Python | 500 | 600 | 700 |
|
|
121
|
+
| TypeScript (general) | 400 | 500 | 600 |
|
|
122
|
+
| React components | 200 | 300 | 400 |
|
|
123
|
+
| Next.js pages/routes | 300 | 400 | 500 |
|
|
124
|
+
| Custom hooks | 100 | 150 | 200 |
|
|
125
|
+
| Utility/service files | 400 | 500 | 600 |
|
|
126
|
+
|
|
127
|
+
## Test File Size Limits
|
|
128
|
+
| Type | Warning | Consider Split | Must Split |
|
|
129
|
+
|------|---------|----------------|------------|
|
|
130
|
+
| Python tests | 800 | 1000 | 1200 |
|
|
131
|
+
| TypeScript tests | 600 | 800 | 1000 |
|
|
132
|
+
| React component tests | 400 | 500 | 600 |
|
|
133
|
+
| Hook tests | 200 | 300 | 400 |
|
|
134
|
+
| E2E/integration tests | 800 | 1000 | 1200 |
|
|
135
|
+
|
|
136
|
+
When a test file approaches these limits, first consider whether the module under test should be split before splitting the test file.
|
|
137
|
+
|
|
138
|
+
## Verify, don't guess
|
|
139
|
+
|
|
140
|
+
- If you find yourself reconstructing an API, function signature, config key, or
|
|
141
|
+
command flag from memory, stop and confirm it before writing it. Memory of these
|
|
142
|
+
is the single biggest source of confident-but-wrong code.
|
|
143
|
+
- Check the right source for the kind of doubt:
|
|
144
|
+
- Project conventions, types, helpers, existing patterns → search the codebase.
|
|
145
|
+
- External library/framework behavior, versions, deprecations → search online,
|
|
146
|
+
preferring official docs and the library's changelog over blog posts or older
|
|
147
|
+
Stack Overflow answers.
|
|
148
|
+
- A search is cheap; a wrong assumption is expensive to debug. When unsure whether
|
|
149
|
+
it's worth checking, check.
|
|
150
|
+
- When a non-obvious choice rests on something you looked up, note the source in one
|
|
151
|
+
line (e.g. "per React 19 docs") so it can be verified.
|
|
152
|
+
- Treat anything that may have changed since your training cutoff — latest versions,
|
|
153
|
+
new APIs, deprecations — as something to look up, not recall.
|
|
154
|
+
|
|
155
|
+
## When debugging
|
|
156
|
+
|
|
157
|
+
- State your current hypothesis for the cause before each fix attempt. If it's the
|
|
158
|
+
same hypothesis as the last failed attempt, do not try another variation — the
|
|
159
|
+
diagnosis is suspect, not just the fix. Gather new information instead.
|
|
160
|
+
- After 2 failed attempts, stop iterating and treat your understanding of the problem
|
|
161
|
+
as the thing that's wrong. Re-examine the premise.
|
|
162
|
+
- Get fresh ground truth instead of reasoning from memory: read the actual error
|
|
163
|
+
message in full, read the actual source of the function involved, and search the
|
|
164
|
+
literal error text online — others have usually hit it.
|
|
165
|
+
- Never repeat a fix that already failed.
|
|
166
|
+
- If you're stuck after re-examining, surface the competing hypotheses to me rather than continuing to guess.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-distro-one
|
|
3
|
+
title: pi-distro-one
|
|
4
|
+
description: "A Claude Code–style coding agent distribution built around autonomous sub-agent spawning and coordination, with web research, browser automation, live shell, model routing, and task management in support. Includes a Claude-style status line and an explore-before-acting approach."
|
|
5
|
+
version: 0.3.0
|
|
6
|
+
tags: [full-config, claude-code-style]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# pi-distro-one
|
|
10
|
+
|
|
11
|
+
A complete interactive coding agent configuration that attempts to mimic as closely as
|
|
12
|
+
possible the functionality of today's Claude Code. The primary capability is spawning and
|
|
13
|
+
coordinating autonomous sub-agents; the remaining functionality is integrated in support
|
|
14
|
+
of that.
|
|
15
|
+
|
|
16
|
+
## Bundled files
|
|
17
|
+
The following bundled files are provided under `files/` and should be placed into the
|
|
18
|
+
target project. For any path that already exists, do NOT overwrite — show the user a diff
|
|
19
|
+
and ask whether to overwrite, keep theirs, or merge. Merge JSON settings field-by-field.
|
|
20
|
+
Append AGENTS.md content under a delimited section if one exists.
|
|
21
|
+
|
|
22
|
+
- `files/AGENTS.md` → `./AGENTS.md`
|
|
23
|
+
- `files/settings.json` → `./.pi/settings.json` (merge with existing settings)
|
|
24
|
+
- `files/.pi/extensions/claude-statusline.ts` → `./.pi/extensions/claude-statusline.ts`
|
|
25
|
+
|
|
26
|
+
## pi packages to install
|
|
27
|
+
Use `pi install -l` to install the following **project-locally** (writes to
|
|
28
|
+
`./.pi/settings.json` on success, leaves settings untouched on failure). Confirm with the
|
|
29
|
+
user before each install. Do NOT pre-add these to the bundled `settings.json` `packages`
|
|
30
|
+
array — `pi install -l` is the single registration mechanism.
|
|
31
|
+
|
|
32
|
+
- `npm:@tintinweb/pi-subagents` — Claude Code–style autonomous sub-agents: spawn
|
|
33
|
+
specialized agents in isolated sessions, each with its own tools, system prompt, model,
|
|
34
|
+
and thinking level; parallel execution, a live monitoring widget, mid-run steering, and
|
|
35
|
+
session resumption (the primary capability of this distribution)
|
|
36
|
+
- `npm:pi-web-access` — web search, URL fetching, GitHub cloning, PDF/video extraction
|
|
37
|
+
- `npm:pi-agent-browser-native` — real browser automation and web interaction
|
|
38
|
+
- `npm:pi-bash-live-view` — live terminal rendering for shell commands
|
|
39
|
+
- `npm:@yeliu84/pi-model-router` — model routing / fallback across providers
|
|
40
|
+
- `npm:@robhowley/pi-openrouter` — OpenRouter provider integration
|
|
41
|
+
- `npm:@juicesharp/rpiv-todo` — task list management
|
|
42
|
+
- `npm:pi-goal` — persistent autonomous goals: `/goal` loops until complete, paused, or
|
|
43
|
+
budget-limited, so long-running objectives survive across turns without manual babysitting
|
|
44
|
+
- `npm:@trevonistrevon/pi-loop` — cron/event-based agent re-wake loops and background
|
|
45
|
+
process monitoring: schedule agents to re-wake on time or events and keep long-running
|
|
46
|
+
or background work alive without manual babysitting
|
|
47
|
+
- `npm:@juicesharp/rpiv-ask-user-question` — structured questionnaire the model can put to
|
|
48
|
+
the user when it would otherwise guess, with typed options instead of free-form replies
|
|
49
|
+
(reduces ambiguous decisions and keeps the user in the loop on judgment calls)
|
|
50
|
+
|
|
51
|
+
**Tool-name conflict check:** before installing, cross-check each package's purpose
|
|
52
|
+
against the already-active tools in the target project (run `pi list`). If a package
|
|
53
|
+
overlaps an existing tool — either an exact name collision or semantic redundancy
|
|
54
|
+
(different names, similar function) — offer **skip / replace / keep both / cancel** instead
|
|
55
|
+
of installing blindly. (Exact name collisions are non-fatal in pi — project-local tools
|
|
56
|
+
shadow global ones — but redundancy leaves a confusing duplicate tool set.)
|
|
57
|
+
|
|
58
|
+
## Custom extension (bundled)
|
|
59
|
+
`files/.pi/extensions/claude-statusline.ts` is a Claude-style status-line footer
|
|
60
|
+
(model | dir | thinking level | context-window bar gauge + cache % | git branch status).
|
|
61
|
+
It auto-enables on session start and is toggleable via the `/claude-statusline` command.
|
|
62
|
+
It also **auto-expands tool outputs** on session start (the Ctrl+O effect) so full output
|
|
63
|
+
is visible by default, while keeping thinking blocks hidden for a clean working view.
|
|
64
|
+
Deploy it to `./.pi/extensions/claude-statusline.ts`; pi loads it via jiti on next start
|
|
65
|
+
(no build step). It depends only on pi core (`@earendil-works/pi-coding-agent`,
|
|
66
|
+
`@earendil-works/pi-ai`, `@earendil-works/pi-tui`) — all provided as peer deps.
|
|
67
|
+
|
|
68
|
+
## Settings (bundled)
|
|
69
|
+
`files/settings.json` provides the agent's defaults: high thinking level, one-at-a-time
|
|
70
|
+
steering, hidden thinking blocks, and hardware cursor. Tool outputs are auto-expanded on
|
|
71
|
+
start (via the status-line extension). Merge with any existing `.pi/settings.json`
|
|
72
|
+
field-by-field. Auth and model/provider configuration are not part of this distribution —
|
|
73
|
+
configure those independently.
|
|
74
|
+
|
|
75
|
+
## Context
|
|
76
|
+
The bundled `AGENTS.md` is an explore-before-acting working methodology: investigate
|
|
77
|
+
before implementing, surface interpretations and tradeoffs, make surgical changes, keep
|
|
78
|
+
solutions simple, execute against verifiable goals, and treat documentation as part of the
|
|
79
|
+
implementation. Deploy it to `./AGENTS.md` so the agent follows these conventions.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# web-fullstack
|
|
2
|
+
|
|
3
|
+
A full-stack React/Node project configuration with web research, code review, and a
|
|
4
|
+
restricted tool set.
|
|
5
|
+
|
|
6
|
+
## What it sets up
|
|
7
|
+
|
|
8
|
+
- **`AGENTS.md`** — frontend and backend conventions, testing guidance, and a code
|
|
9
|
+
review process tailored to React/Node projects.
|
|
10
|
+
- **`.pi/settings.json`** — sensible defaults with a restricted tools allowlist (only
|
|
11
|
+
the essential tools, keeping the agent focused).
|
|
12
|
+
- **`.pi/prompts/review.md`** — a review prompt template for on-demand structured code
|
|
13
|
+
reviews.
|
|
14
|
+
|
|
15
|
+
## Packages installed
|
|
16
|
+
|
|
17
|
+
- **`npm:pi-browse`** — web search (Brave / DuckDuckGo / Exa / Gemini) and content
|
|
18
|
+
extraction. Used for documentation lookup, API verification, and research.
|
|
19
|
+
|
|
20
|
+
## When to use
|
|
21
|
+
|
|
22
|
+
- You're building a React/Node full-stack application.
|
|
23
|
+
- You want web research built in for looking up docs and APIs.
|
|
24
|
+
- You want a structured code review workflow.
|
|
25
|
+
- You prefer a restricted tool set over the full default set.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Code Review
|
|
2
|
+
|
|
3
|
+
Review the changes for: correctness, security, performance, accessibility, and test coverage.
|
|
4
|
+
Provide specific, actionable feedback referencing line numbers or code blocks.
|
|
5
|
+
|
|
6
|
+
## Checklist
|
|
7
|
+
|
|
8
|
+
- **Correctness**: Does the code do what it claims? Are edge cases handled?
|
|
9
|
+
- **Security**: Are inputs validated? Are secrets handled safely? Any injection risks?
|
|
10
|
+
- **Performance**: Are there unnecessary re-renders, N+1 queries, or blocking operations?
|
|
11
|
+
- **Accessibility**: Are semantic HTML elements used? Are interactive elements keyboard-accessible?
|
|
12
|
+
- **Test coverage**: Are the new behaviors tested? Do existing tests still pass?
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Project Instructions — Full-Stack Web
|
|
2
|
+
|
|
3
|
+
Guidance for working in this React/Node full-stack project.
|
|
4
|
+
|
|
5
|
+
## Frontend Conventions (React/Next.js)
|
|
6
|
+
|
|
7
|
+
- Use TypeScript for all frontend code.
|
|
8
|
+
- Prefer function components with hooks over class components.
|
|
9
|
+
- Use named exports for components; default export only for page components.
|
|
10
|
+
- Co-locate component styles using CSS Modules or Tailwind utility classes.
|
|
11
|
+
- Keep components small and composable — extract reusable logic into custom hooks.
|
|
12
|
+
- Use `next/navigation` (App Router) for routing in Next.js projects.
|
|
13
|
+
|
|
14
|
+
## Backend Conventions (Node/Express)
|
|
15
|
+
|
|
16
|
+
- Use TypeScript for all backend code.
|
|
17
|
+
- Structure API routes with clear separation: controller → service → data layer.
|
|
18
|
+
- Validate all request inputs with a schema validation library (e.g. zod, typebox).
|
|
19
|
+
- Return consistent error response shapes: `{ error: { code, message, details? } }`.
|
|
20
|
+
- Use environment variables for configuration; never hardcode secrets.
|
|
21
|
+
- Prefer async/await over callback chains.
|
|
22
|
+
|
|
23
|
+
## Testing
|
|
24
|
+
|
|
25
|
+
- Write tests alongside the code they verify (co-located `*.test.ts` or `__tests__/`).
|
|
26
|
+
- Use Vitest or Jest for unit/integration tests.
|
|
27
|
+
- Use Playwright or Cypress for end-to-end tests.
|
|
28
|
+
- Aim for meaningful coverage of business logic, not 100% line coverage.
|
|
29
|
+
- Run tests in CI on every pull request.
|
|
30
|
+
|
|
31
|
+
## Code Review Process
|
|
32
|
+
|
|
33
|
+
- All changes require at least one approving review before merge.
|
|
34
|
+
- Use the review prompt template at `.pi/prompts/review.md` for structured reviews.
|
|
35
|
+
- Focus reviews on: correctness, security, performance, accessibility, and test coverage.
|
|
36
|
+
- Provide specific, actionable feedback. Reference line numbers or code blocks.
|
|
37
|
+
- Approve only when all blocking comments are resolved.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-fullstack
|
|
3
|
+
title: Full-Stack Web
|
|
4
|
+
description: "React/Node project with web-research + review skills, review-oriented context, and a sensible tools allowlist."
|
|
5
|
+
version: 0.1.0
|
|
6
|
+
tags: [web, react, node]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Full-Stack Web
|
|
10
|
+
|
|
11
|
+
## Bundled files
|
|
12
|
+
The following bundled files are provided under `files/` and should be placed into the
|
|
13
|
+
target project. For any path that already exists, do NOT overwrite — show the user a diff
|
|
14
|
+
and ask whether to overwrite, keep theirs, or merge. Merge JSON settings objects field by
|
|
15
|
+
field. Append (not replace) `AGENTS.md` content under a clearly-delimited section.
|
|
16
|
+
|
|
17
|
+
- `files/AGENTS.md` → `./AGENTS.md`
|
|
18
|
+
- `files/settings.json` → `./.pi/settings.json` (merge with existing settings)
|
|
19
|
+
- `files/.pi/prompts/review.md` → `./.pi/prompts/review.md`
|
|
20
|
+
|
|
21
|
+
## pi packages to install
|
|
22
|
+
Use `pi install -l` to install the following **project-locally** (writes to `./.pi/settings.json`
|
|
23
|
+
on success, and does nothing on failure). Confirm with the user before each install. Do NOT
|
|
24
|
+
pre-add these packages to the bundled `settings.json` — `pi install -l` is the single source
|
|
25
|
+
of truth that registers a package, so that a failed install never leaves a dangling entry
|
|
26
|
+
in settings.
|
|
27
|
+
|
|
28
|
+
- `npm:pi-browse` — web search (Brave/DuckDuckGo/Exa/Gemini) and content extraction for
|
|
29
|
+
documentation lookup and API verification
|
|
30
|
+
|
|
31
|
+
## Context
|
|
32
|
+
This harness sets up a full-stack web project with React/Node conventions. The bundled
|
|
33
|
+
`AGENTS.md` contains frontend and backend conventions, testing guidance, and a code review
|
|
34
|
+
process. The `settings.json` restricts the tools allowlist to the essential set. A review
|
|
35
|
+
prompt template is included under `.pi/prompts/` for on-demand code reviews.
|
|
36
|
+
|
|
37
|
+
## Skills / prompts
|
|
38
|
+
- The `pi-browse` package (installed above) provides web research capabilities.
|
|
39
|
+
- A review prompt template is bundled at `files/.pi/prompts/review.md` and deployed to
|
|
40
|
+
`./.pi/prompts/review.md`. Use it to run structured code reviews on changes.
|