# v0.2.0 implementation plan

> **Goal:** Skills MVP — user runs `/review` locally and gets a Claude-shaped pipeline report.  
> **Baseline:** v0.1.0 (core libs + tests; no `index.ts`, no E2E).  
> **Design refs:** [pi-review-roadmap.md](./pi-review-roadmap.md), [claude-code-review.md](./claude-code-review.md)

Target release: `@georgedong32/pi-review@0.2.0`

---

## Goals

- [x] Extension loads via `pi -e .` and registers `/review`, `/review-config`, `/review-agents`
- [x] `/review` runs full pipeline: **eligibility → prep → reviewers → gate → report**
- [x] Five default content reviewers with bundled prompts wired as system prompts
- [~] Subagent spawn + structured JSON capture works on real `pi` child processes (unit + args tests pass; live spawn E2E pending API key)
- [x] Default confidence threshold **8/10** (Claude 80/100 equivalent)
- [ ] Publish to npm

## Non-goals (v0.2)

- GitHub / `gh` integration (`pr-context` reviewer)
- Per-issue Haiku scorers (`--score-per-issue`)
- `registerTool` / agent auto-invoke
- Worktree isolation, auto-fix, retry loops
- Custom TUI message renderer (collapsible sections)

---

## Task list

Status key: `[ ]` todo · `[~]` in progress · `[x]` done

### Track A — Extension entry (P0)

| ID | Task | Depends | Status |
|----|------|---------|--------|
| A1 | Create `index.ts` — default export `ExtensionAPI` factory | — | [x] |
| A2 | Register `/review` command with arg string passthrough | A1 | [x] |
| A3 | Register `/review-config` — ensure config dir, open editor, re-validate on save | A1 | [x] |
| A4 | Register `/review-agents` — list reviewers with resolved model/thinking/tools | A1 | [x] |
| A5 | Implement `src/cli-args.ts` — parse flags + path/`@file` from `/review` args | A1 | [x] |
| A6 | Wire orchestration in `index.ts`: load config → eligibility → diff → prep → review → gate → output | A2, A5, B*, C*, D* | [x] |
| A7 | Output: `renderReport` via `pi.sendMessage` (assistant-visible markdown) | A6 | [x] |
| A8 | Output: `pi.appendEntry("pi-review", report)` machine-readable payload | A6 | [x] |
| A9 | Long-run UX: `ctx.ui.setStatus("pi-review", …)` during spawn phases | A6 | [x] |
| A10 | Add `index.ts` to `package.json` `files`; verify `tsc` includes it | A1 | [x] |

**A3 notes:** Prefer `ctx.ui.editor()` with JSON text for in-TUI edit; fall back to `pi.exec($EDITOR, [configPath])` when `ctx.hasUI` and editor env set.

**A5 flags to parse:**

```text
--threshold N
--reviewer <id>       (repeatable)
--no-gate
--gate-model <id>
--no-spawn
[path | @path]
```

---

### Track B — Structured output / spawn (P0)

| ID | Task | Depends | Status |
|----|------|---------|--------|
| B1 | Add `src/structured-output-capture.ts` — minimal pi extension: register `structured_output` tool; read schema from env; write capture file; `terminate: true` | — | [x] |
| B2 | Document env contract in `reference/structured-output.md` (or inline in spawn.ts header) | B1 | [x] |
| B3 | Update `src/args.ts` — append `-e <capture-ext>` to child args (resolve path via `import.meta.url`) | B1 | [x] |
| B4 | Verify child still uses `--no-session --no-extensions --no-skills` **except** capture extension | B3 | [x] |
| B5 | Manual E2E: one reviewer spawn writes valid `output.json` | B3, C2 | [ ] |
| B6 | Integration test with fake spawn (existing pattern) updated for `-e` arg | B3 | [x] |

**B1 contract (unchanged env vars):**

- `PI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA` → JSON Schema file path
- `PI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE` → output JSON path

---

### Track C — Pipeline phases (P0–P1)

| ID | Task | Depends | Status |
|----|------|---------|--------|
| C1 | Add `src/eligibility.ts` — `checkEligibility(input): { ok, reason? }` | — | [x] |
| C2 | Eligibility rules: empty diff → skip; non-git without path → skip; optional trivial diff heuristic | C1 | [x] |
| C3 | Add `tests/eligibility.test.ts` | C1 | [x] |
| C4 | Add `src/prep.ts` — `prepareContext(cwd, diff): { rulePaths, summary }` | — | [x] |
| C5 | Rule discovery: `AGENTS.md`, `CLAUDE.md`, `.pi/rules`, `.pi/conventions.md` (paths only, like Claude step 2) | C4 | [x] |
| C6 | Diff summary: first N lines / hunk count / files touched (sync, no LLM required for v0.2) | C4 | [x] |
| C7 | Inject prep block into reviewer task preamble in `review.ts` | C4, D6 | [x] |
| C8 | Add `tests/prep.test.ts` | C4 | [x] |
| C9 | Light re-check before render: diff still non-empty (Claude phase 6 lite) | C1, A6 | [x] |

**Trivial diff heuristic (v0.2):** only lockfile / only formatting-only / &lt; 3 lines — configurable `skipTrivial: true` in config later; hardcode simple rules OK for v0.2.

---

### Track D — Reviewers & prompts (P1)

| ID | Task | Depends | Status |
|----|------|---------|--------|
| D1 | Add `src/paths.ts` — `packageRoot()` via `import.meta.url` | — | [x] |
| D2 | `resolveAgentPrompt(id)` → `agents/<id>.md` (strip YAML frontmatter body for system prompt) | D1 | [x] |
| D3 | `resolveGatePrompt()` → `prompts/gate.md` | D1 | [x] |
| D4 | Refactor `review.ts`: use bundled agent md as `--system-prompt`; task = prep + diff | D2, C7 | [x] |
| D5 | Refactor `gate.ts`: use `prompts/gate.md` as gate system prompt | D3 | [x] |
| D6 | Rename `agents/bug-detector.md` → `agents/bugbot.md`; update id in config defaults | — | [x] |
| D7 | Tighten `bugbot.md` prompt per [cursor-review-skills.md](./cursor-review-skills.md) | D6 | [x] |
| D8 | Add `agents/security-review.md` | — | [x] |
| D9 | Add `agents/code-comments.md` (Claude agent #5) | — | [x] |
| D10 | Update `src/config.ts` `DEFAULT_CONFIG.reviewers` roster (5 enabled, conventions disabled) | D6–D9 | [x] |
| D11 | Update `prompts/gate.md` — embed Claude 0–100 rubric mapped to 1–10; re-score not just filter | D5 | [x] |
| D12 | Change default `gate.threshold` from 3 → **8** in config + README | D10 | [x] |
| D13 | Keep `agents/conventions.md`; `enabled: false` in defaults | D10 | [x] |

**Default enabled reviewers (v0.2):**

1. `claude-md-compliance`
2. `bugbot`
3. `history-context`
4. `security-review`
5. `code-comments`

---

### Track E — Types, schema, report (P1)

| ID | Task | Depends | Status |
|----|------|---------|--------|
| E1 | Extend `ResolvedInput` / report if needed for prep metadata (`rulePaths`, `summary`) | C4 | [x] |
| E2 | `buildReport` — handle eligibility skip / no high-confidence issues messaging | A6 | [x] |
| E3 | `renderReport` — “No high-confidence issues” path (Claude: no comment posted) | E2 | [x] |
| E4 | Update `tests/report.test.ts` for new messages | E3 | [x] |
| E5 | Update `tests/config.test.ts` for new defaults + bugbot id | D10 | [x] |

---

### Track F — Tests & docs (P1)

| ID | Task | Depends | Status |
|----|------|---------|--------|
| F1 | Add `tests/cli-args.test.ts` | A5 | [x] |
| F2 | Update `tests/args.test.ts` if child argv shape changes (`-e`) | B3 | [x] |
| F3 | Update `tests/review.test.ts` for bundled prompt resolution (mock fs or inject paths) | D4 | [x] |
| F4 | Update README — pipeline diagram, 5 reviewers, threshold 8, reference links | * | [x] |
| F5 | CHANGELOG `[0.2.0]` section | * | [x] |
| F6 | Bump `package.json` version → `0.2.0` | * | [x] |
| F7 | `bun test` + `bun run check` green | * | [x] |

---

### Track G — Release (P1)

| ID | Task | Depends | Status |
|----|------|---------|--------|
| G1 | Manual smoke: `pi -e .` → `/review` on dirty repo | A6, B5 | [ ] |
| G2 | Manual smoke: `/review --no-gate`, `--reviewer bugbot`, `--no-spawn` | A5, A6 | [ ] |
| G3 | Manual smoke: `/review-config` round-trip | A3 | [ ] |
| G4 | `npm publish` (user-triggered) | G1–G3, F7 | [ ] |

---

## Suggested implementation order

```text
Week 1 — unblock E2E
  D1 → B1 → B3 → D2/D3 → D4/D5 → A1 → A5 → C1/C4 → A6 (no-gate path first)

Week 2 — full pipeline
  D6–D13 → C7 → D11/D12 → A7/A8/A9 → A3/A4 → tests (F*) → docs (F4/F5)

Week 3 — polish & release
  C2/C9 trivial + re-check → G* smoke → version bump → publish
```

**Critical path:** `B1 → B3 → D4 → A6 → G1`

---

## Acceptance criteria (release gate)

1. **Load:** `pi -e /path/to/pi-review` lists `/review` in commands.
2. **Happy path:** Dirty git repo → `/review` → markdown report with verdict + per-reviewer sections + gate section.
3. **Empty:** Clean repo, no commits ahead → eligibility message, no spawn storm.
4. **Filter:** Reviewer returns low-confidence issue → gate drops it; report says no high-confidence issues if all dropped.
5. **Flags:** `--no-gate` shows raw reviewer JSON sections; `--no-spawn` prints resolved plan; `--reviewer bugbot` runs one agent.
6. **Config:** `/review-config` edit + save → `/review-agents` reflects changes.
7. **CI:** `bun test` (≥ current count, new tests for eligibility/cli-args/prep) + `tsc --noEmit` pass.

---

## File manifest (expected diff)

### New files

```text
index.ts
src/cli-args.ts
src/eligibility.ts
src/prep.ts
src/paths.ts
src/structured-output-capture.ts
agents/bugbot.md              (from bug-detector)
agents/security-review.md
agents/code-comments.md
tests/cli-args.test.ts
tests/eligibility.test.ts
tests/prep.test.ts
reference/v0.2-plan.md        (this file)
```

### Modified files

```text
src/review.ts
src/gate.ts
src/args.ts
src/config.ts
src/report.ts
src/types.ts                  (if prep metadata)
prompts/gate.md
README.md
CHANGELOG.md
package.json
reference/README.md
tests/args.test.ts
tests/config.test.ts
tests/report.test.ts
tests/review.test.ts
```

### Removed / renamed

```text
agents/bug-detector.md  →  agents/bugbot.md
```

---

## Risk register

| Risk | Mitigation |
|------|------------|
| Stock `pi` rejects `-e` with `--no-extensions` | B4: confirm CLI allows single extension override; else use minimal inline prompt + `--tools` only |
| Long diff exceeds argv limits | Pass `@file` temp path for task text (already noted in args.ts) |
| 5 reviewers × spawn cost | Document expected latency; `--reviewer` subset; concurrency cap 4 |
| Gate re-score drift vs per-issue scorers | Document in reference; v0.3 adds `--score-per-issue` |

---

## Progress summary

| Track | Tasks | Done |
|-------|-------|------|
| A Extension | 10 | 10 |
| B Spawn | 6 | 5 |
| C Pipeline | 9 | 9 |
| D Reviewers | 13 | 13 |
| E Types/report | 5 | 5 |
| F Tests/docs | 7 | 7 |
| G Release | 4 | 0 |
| **Total** | **54** | **49** |

**Remaining:** B5 live spawn E2E; G1–G3 manual `pi` smoke; G4 `npm publish` (user-triggered).

Update the **Progress summary** table as tasks complete.
