@tduyng/pi-review

Review a change like a senior engineer: the git delta, the task, the code, and a markdown report with severity, locations, and suggested diffs.

Packages

Package details

extension

Install @tduyng/pi-review from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@tduyng/pi-review
Package
@tduyng/pi-review
Version
0.0.5
Published
Nov 10, 2026
Downloads
814/mo · 620/wk
Author
tienduy-nguyen
License
Apache-2.0
Types
extension
Size
102.2 KB
Dependencies
1 dependency · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./src/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@tduyng/pi-review

/review reads a change the way a colleague would: the diff, the task, and the code around it. The report lands in .pi/reviews/ with a table you can scan in ten seconds and one section per problem, and the chat gets the verdict and one line per serious finding.

The review runs in the session you typed it in. Every read and every command shows up as it happens, and once it is done you can ask about a finding and the model answers from what it read. Start a new session for a review, so the model reads the change cold instead of remembering why it wrote it.

How it works

A bare /review asks git what changed since the last checkpoint. With nothing there it takes what is uncommitted, and with nothing there either, this branch against its merge base.

The command writes its snapshot through a throwaway GIT_INDEX_FILE. That produces a dangling tree with no ref and no commit, so repository history stays untouched. The checkpoint is that same tree, and a review moves it. A --quick review does not, so the next full review still covers the same work.

The command posts the review request as one message, collapsed to a single line you can expand, and the model answers it with every tool, skill, and subagent the session has. It hands the review in through review_submit, a tool that is only active while a review is open. That call writes the report, the ledger, and the checkpoint, and returns the summary.

Until review_submit returns, edit and write are blocked, so a review never changes the code it reads. A model that stops without submitting is reminded once. Escape ends the review and lifts the block.

A diff over 40,000 characters is cut, and the request names the git diff command for the files past the cut, so the model reads them itself or hands them to a subagent.

In the background

/review --background runs the review in a separate session with read, bash, grep, outline, and fd only, and no extensions, skills, or transcript of yours. Its transcript is kept under .pi/reviews/sessions/ and named in the report. While it runs, a widget above the editor shows the elapsed time, the turn, the tool calls, the tokens, and what each part is reading now.

A background diff over 24,000 characters is split by file into parts, reviewed two at a time, and merged. Each part knows which files it holds, so a contract broken in a file another part owns is still reported. Nothing is truncated.

What a review covers

  • the task: the request, the commit messages, the acceptance criteria
  • what this change breaks: callers, signatures, schemas, generated clients, migrations
  • paths that fail: partial failure, retries, ordering, shared state, empty and maximum inputs
  • tests that pass without proving the thing the change exists for
  • the layer and the seam, when it will cost the next person real time
  • the house rules: AGENTS.md, CLAUDE.md, CONTRIBUTING.md and the lint configs, read before judging, and cited when broken
  • errors swallowed, casts and type guards that claim more than the code proves, input from outside, queries in loops, a helper the codebase already has

A finding needs a line of this change and a consequence, and the reviewer re-checks each one before reporting it. A doubt goes in the questions section instead.

Before the model reads anything, the command scans the added lines for leftovers: FIXME, TODO, a comment ending in ?, commented-out code, debug output, a focused or skipped test, a disabled lint or type check. The prompt lists each hit. One the review neither reports nor settles in checked by its file:line is added as a finding anyway, so it cannot slip through on a weak model. A focused test is P1, a skipped one P2, the rest P3.

Commands

/review                      what moved since the last review, else uncommitted, else the branch base
/review src/session.ts       a path, commit, or range to review
/review 84aeb507b8 the bug   a sha or a..b range anywhere in the text is the diff, the rest is the task
/review --task "..."         the task to review against, when the target has none
/review --quick              a fast read, findings in the chat, no report file
/review --staged             the index only
/review --base main          compare against another base
/review --out reviews/       where the report goes, relative to the repo root
/review --no-file            the chat summary only, the findings still go in the ledger
/review --model provider/id  switch this session to another model for the review
/review --background         review in a separate session, with a progress widget
/review --extra "..."        add an acceptance criterion
/review --lean               leave out the praise and coverage sections

--out takes a directory or a file path. A path ending in .md is the file, anything else is a directory. The default is .pi/reviews/<stamp>-<branch>.md at the repository root, and the directory is created when it does not exist.

The report

I would fix the points below before this merges.
1 P1
- [P1] src/lock.ts:41: The lock is released before the write. Two workers overwrite each other.
Report: .pi/reviews/2026-11-12T09-00-feat-lock.md

The file reads like a note from someone who read the change:

  • My take: one of three verdicts, in a sentence
  • Everything at a glance: a table of number, location, problem, level, so you can pick the one worth reading first
  • 1. <title>: what happens, why it matters, and the fix as code
  • I'd want your answer on: the questions the code cannot settle
  • Not verified: what the reviewer did not read or run, so you know where the risk is left
  • Fixed since the last review: findings on files in this diff that are gone
  • What looked good and What I checked: folded at the bottom, left out with --lean

Each finding is numbered and keeps its number between reviews where the title and file are unchanged, so "fix #2" means something in the next conversation. Nothing is written when the reviewer fails to answer.

The summary carries the P0 to P2 findings, up to eight. After a background review, it also tells your model to read the report before it explains a reason or a fix, since your session never saw what the reviewer read.

The ledger

Open findings are saved in .pi/reviews/ledger.json. The next review is told about them and asked to report one again only when it is still there, keeping the title, so a fixed issue stops appearing and a surviving one is marked (still open) instead of being rediscovered from scratch. Only entries on files this diff touches are sent to the reviewer or can be closed. The rest stay open in the ledger for the review that covers them.

The ledger is per repository, not per session, so it survives /new.

Install

pi install npm:@tduyng/pi-review

Local checkout: pi install /path/to/dotfiles/pi/agent/extensions/pi-review

It needs git on PATH and a git repository. Outside one, the command says so and stops.

Limits

  • A background reviewer gets 10 minutes per part. --model picks its model. The default is the model your session is on.
  • The review is one pass, not a debate. A second opinion means running /review again with another --model.
  • The checkpoint lives as a session entry, so a new session starts from the last one in the same repository. A fresh clone starts from nothing.
  • Snapshot trees are unreferenced by design, so git's pruning collects them after about two weeks. A checkpoint older than that resolves to a full review.
  • /review in print mode (pi -p '/review') has no turn to run in, and print mode drops notifications, so the command writes one line to stderr and returns. Interactive use and --mode rpc are the supported paths.