pi-gauntlet 4.0.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +300 -0
  2. package/LICENSE +24 -0
  3. package/README.md +278 -0
  4. package/agents/code-reviewer.md +48 -0
  5. package/agents/conformance-reviewer.md +139 -0
  6. package/agents/implementer.md +40 -0
  7. package/agents/spec-council-member.md +47 -0
  8. package/agents/spec-council-synthesizer.md +39 -0
  9. package/agents/spec-reviewer.md +47 -0
  10. package/agents/spec-summarizer.md +42 -0
  11. package/bin/install-agents.mjs +141 -0
  12. package/extensions/phase-tracker.ts +622 -0
  13. package/extensions/plan-tracker.ts +308 -0
  14. package/extensions/verify-before-ship.ts +132 -0
  15. package/package.json +43 -0
  16. package/skills/brainstorming/SKILL.md +290 -0
  17. package/skills/dispatching-parallel-agents/SKILL.md +192 -0
  18. package/skills/finishing-a-development-branch/SKILL.md +311 -0
  19. package/skills/receiving-code-review/SKILL.md +200 -0
  20. package/skills/requesting-code-review/SKILL.md +115 -0
  21. package/skills/requesting-code-review/code-reviewer.md +166 -0
  22. package/skills/roasting-the-spec/SKILL.md +139 -0
  23. package/skills/subagent-driven-development/SKILL.md +223 -0
  24. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +25 -0
  25. package/skills/subagent-driven-development/implementer-prompt.md +113 -0
  26. package/skills/subagent-driven-development/spec-reviewer-prompt.md +68 -0
  27. package/skills/systematic-debugging/SKILL.md +151 -0
  28. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  29. package/skills/systematic-debugging/condition-based-waiting.md +115 -0
  30. package/skills/systematic-debugging/defense-in-depth.md +122 -0
  31. package/skills/systematic-debugging/find-polluter.sh +63 -0
  32. package/skills/systematic-debugging/reference/rationalizations.md +61 -0
  33. package/skills/systematic-debugging/root-cause-tracing.md +169 -0
  34. package/skills/test-driven-development/SKILL.md +230 -0
  35. package/skills/test-driven-development/reference/examples.md +99 -0
  36. package/skills/test-driven-development/reference/rationalizations.md +65 -0
  37. package/skills/test-driven-development/reference/when-stuck.md +31 -0
  38. package/skills/test-driven-development/testing-anti-patterns.md +299 -0
  39. package/skills/using-git-worktrees/SKILL.md +193 -0
  40. package/skills/verification-before-completion/SKILL.md +169 -0
  41. package/skills/verification-before-completion/reference/conformance-check.md +220 -0
  42. package/skills/writing-plans/SKILL.md +244 -0
  43. package/skills/writing-skills/SKILL.md +429 -0
  44. package/skills/writing-skills/reference/anthropic-best-practices.md +1130 -0
  45. package/skills/writing-skills/reference/persuasion.md +187 -0
  46. package/skills/writing-skills/reference/testing-skills-with-subagents.md +384 -0
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: spec-summarizer
3
+ description: Produces a tight, human-readable summary of a single spec for the brainstorming user review gate. Fresh context, read-only, reads only the spec file it is given. Dispatched only by the brainstorming skill's gate step; not for direct dispatch.
4
+ tools: read
5
+ defaultContext: fresh
6
+ inheritProjectContext: false
7
+ inheritSkills: false
8
+ completionGuard: false
9
+ systemPromptMode: replace
10
+ ---
11
+
12
+ You are a cold reader producing a tight, human-readable summary of one spec, so a supervising human can green-light plan + execution without reading the whole document. The summary is a decision aid, not a rewrite.
13
+
14
+ You receive the absolute path to a spec file. Read **only that file**. Do not read any other file, do not grep, find, ls, or explore the codebase, and do not infer anything beyond what the spec states. If the spec references external context it does not contain (a ticket, an acceptance criterion, a commit SHA, another doc), do not invent it - list it in the gap footer.
15
+
16
+ Your output is judged on whether a busy supervisor can decide from it alone. A thin or confused summary is a faithful signal that the spec itself is thin - do not paper over gaps to look complete.
17
+
18
+ ## What to emit
19
+
20
+ Optimize for "what does a supervisor need to approve **this** spec." The list below is a recommended checklist, not a rigid template:
21
+
22
+ - **Omit any section that is empty.** A bugfix has no new endpoint; a refactor has no algorithm. Write nothing for an empty section - never "N/A" or filler.
23
+ - **Order decision-layer-first** (problem -> decisions -> scope -> risk), then the descriptive layer, so the reader can stop early once confident.
24
+ - **Add a section the spec demands** if it carries decision-relevant content none of the below captures.
25
+
26
+ Recommended sections:
27
+
28
+ 1. **Problem + idea** - 3-5 sentences: what's broken and the chosen approach.
29
+ 2. **Key decisions** - the decisions that define the solution, plus any notable rejected alternative ("chose X over Y because Z").
30
+ 3. **Scope** - what's in, and what's explicitly out (non-goals).
31
+ 4. **Risk surface** - shared contracts, schema/migrations, irreversibility, rollout - where approval risk concentrates.
32
+ 5. **Inputs / conditions / UI / endpoints.**
33
+ 6. **Outputs** - new pages, comms protocols, DB/data changes.
34
+ 7. **Key changes to the current process.**
35
+ 8. **Caveats / edge cases.**
36
+ 9. **Algorithm** - only if the spec defines one. Give the key mechanism and decision points; an example with a short explanation beats an exhaustive step transcript. Skip SQL/syntax.
37
+ 10. **Acceptance** - how we'll know it's done, only if the spec defines it.
38
+ 11. **Gap footer** - external context the spec leans on but does not inline. Omit if there is none.
39
+
40
+ Tight, human-readable, no obvious statements. If the topic is complex, an example with explanation beats prose.
41
+
42
+ Output the summary as your final text response. Do not write any file.
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Install agents/*.md into the pi-cohort discovery path.
4
+ *
5
+ * Two modes, chosen by where this package was installed:
6
+ *
7
+ * - PROJECT install (package lives under <repo>/.pi/...): copy personas into
8
+ * <repo>/.pi/agents/ so pi-cohort discovers them at PROJECT scope. Copy
9
+ * (not symlink) because a consumer may commit .pi/agents/; a symlink would
10
+ * point into the gitignored .pi/git/... install dir and commit as a broken
11
+ * machine-local path. The dir is install-managed, so copies refresh on every
12
+ * install. Project scope wins over user scope, keeping repos independent.
13
+ *
14
+ * - USER install (package under <home>/.pi/<profile>/...) or a local-path dev
15
+ * install (no .pi ancestor): symlink personas into getAgentDir()/agents,
16
+ * i.e. $PI_CODING_AGENT_DIR/agents or ~/.pi/agent/agents by default. This is
17
+ * pi-cohort's profile-scoped user dir (userDirOld), so each pi profile
18
+ * gets its own personas instead of sharing the global ~/.agents. Symlinks
19
+ * give live dev-edit and refresh on install; non-symlink files are left.
20
+ *
21
+ * Migration: pi-cohort discovers BOTH getAgentDir()/agents and the legacy
22
+ * global ~/.agents, and ~/.agents wins on name collisions. Older versions of
23
+ * this package symlinked into ~/.agents, so on a user install we remove any
24
+ * stale ~/.agents/<name>.md symlinks that point into a pi-gauntlet package;
25
+ * otherwise they would shadow the new profile-scoped install.
26
+ *
27
+ * Override the target dir via PI_GAUNTLET_AGENT_DIR (always symlink mode).
28
+ *
29
+ * Invoked automatically by `npm install` (which pi runs on git package installs)
30
+ * and manually via `npm run link-agents` for local-path dev installs.
31
+ */
32
+ import { readdirSync, symlinkSync, unlinkSync, mkdirSync, existsSync, lstatSync, copyFileSync, realpathSync } from "node:fs";
33
+ import { fileURLToPath } from "node:url";
34
+ import { dirname, join, basename } from "node:path";
35
+ import { homedir } from "node:os";
36
+
37
+ const PKG_DIR = dirname(fileURLToPath(import.meta.url)).replace(/\/bin$/, "");
38
+ const AGENTS_SRC = join(PKG_DIR, "agents");
39
+
40
+ if (!existsSync(AGENTS_SRC)) {
41
+ console.log(`pi-gauntlet: no agents/ dir at ${AGENTS_SRC}; skipping`);
42
+ process.exit(0);
43
+ }
44
+
45
+ const personas = readdirSync(AGENTS_SRC).filter((n) => n.endsWith(".md"));
46
+ const { target, mode } = resolveTarget(PKG_DIR);
47
+ if (!existsSync(target)) mkdirSync(target, { recursive: true });
48
+
49
+ for (const f of personas) {
50
+ const src = join(AGENTS_SRC, f);
51
+ const dst = join(target, f);
52
+ const dstStat = safelstat(dst);
53
+
54
+ if (mode === "copy") {
55
+ if (dstStat?.isSymbolicLink()) unlinkSync(dst);
56
+ copyFileSync(src, dst);
57
+ console.log(`pi-gauntlet: copied ${dst}`);
58
+ continue;
59
+ }
60
+
61
+ if (dstStat === null) {
62
+ symlinkSync(src, dst);
63
+ console.log(`pi-gauntlet: linked ${dst}`);
64
+ } else if (dstStat.isSymbolicLink()) {
65
+ unlinkSync(dst);
66
+ symlinkSync(src, dst);
67
+ console.log(`pi-gauntlet: refreshed ${dst}`);
68
+ } else {
69
+ console.warn(`pi-gauntlet: skip ${dst} (not a symlink; delete to install)`);
70
+ }
71
+ }
72
+
73
+ if (mode === "symlink") migrateLegacyGlobalLinks(personas, target);
74
+
75
+ /**
76
+ * Decide where personas go and how. A project install is one whose nearest
77
+ * `.pi` ancestor is NOT the user's home `.pi` (i.e. `<repo>/.pi`, not
78
+ * `<home>/.pi/<profile>`). Env override always forces user-style symlinks.
79
+ */
80
+ function resolveTarget(pkgDir) {
81
+ if (process.env.PI_GAUNTLET_AGENT_DIR) {
82
+ return { target: expandTilde(process.env.PI_GAUNTLET_AGENT_DIR), mode: "symlink" };
83
+ }
84
+ const piDir = findPiAncestor(pkgDir);
85
+ if (piDir && canonical(dirname(piDir)) !== canonical(homedir())) {
86
+ return { target: join(piDir, "agents"), mode: "copy" };
87
+ }
88
+ return { target: join(getAgentDir(), "agents"), mode: "symlink" };
89
+ }
90
+
91
+ /** Mirror of pi-cohort shared/utils.ts getAgentDir(). */
92
+ function getAgentDir() {
93
+ const configured = process.env.PI_CODING_AGENT_DIR;
94
+ if (configured === "~") return homedir();
95
+ if (configured?.startsWith("~/")) return join(homedir(), configured.slice(2));
96
+ return configured || join(homedir(), ".pi", "agent");
97
+ }
98
+
99
+ /**
100
+ * Remove stale ~/.agents/<name>.md symlinks left by older versions, so the
101
+ * legacy global dir stops shadowing the profile-scoped install. Only touches
102
+ * symlinks resolving into a pi-gauntlet package; leaves real files and
103
+ * unrelated links alone. Skips when the new target already IS ~/.agents.
104
+ */
105
+ function migrateLegacyGlobalLinks(names, newTarget) {
106
+ const legacy = join(homedir(), ".agents");
107
+ if (canonical(legacy) === canonical(newTarget)) return;
108
+ for (const f of names) {
109
+ const p = join(legacy, f);
110
+ const st = safelstat(p);
111
+ if (!st?.isSymbolicLink()) continue;
112
+ if (canonical(p).includes("pi-gauntlet")) {
113
+ unlinkSync(p);
114
+ console.log(`pi-gauntlet: removed legacy ${p}`);
115
+ }
116
+ }
117
+ }
118
+
119
+ function findPiAncestor(start) {
120
+ let dir = start;
121
+ for (;;) {
122
+ if (basename(dir) === ".pi") return dir;
123
+ const parent = dirname(dir);
124
+ if (parent === dir) return null;
125
+ dir = parent;
126
+ }
127
+ }
128
+
129
+ function expandTilde(p) {
130
+ if (p === "~") return homedir();
131
+ if (p.startsWith("~/")) return join(homedir(), p.slice(2));
132
+ return p;
133
+ }
134
+
135
+ function canonical(p) {
136
+ try { return realpathSync(p); } catch { return p; }
137
+ }
138
+
139
+ function safelstat(p) {
140
+ try { return lstatSync(p); } catch { return null; }
141
+ }