# pi-annotations

Review long pi responses the way you review a PR: mark the exact lines you have opinions about, attach a note to each, and send them all as one batch.
Each note arrives with the verbatim passage it refers to, so the agent never has to guess what "that part" means.

## Why

Agents in planning and discovery phases emit long, structured output.
Replying to five different parts of it today means writing one giant synthesized message or five serial round trips.
This extension adds a third option: an annotation overlay where you mark spans and jot notes as you read, then deliver everything at once.

![pi-annotations demo](assets/annotate-demo.gif)

![Annotation overlay with two marked spans and a note being written](assets/annotate-overlay.png)

## Install

```bash
pi install npm:pi-annotations
# or straight from git:
pi install git:github.com/patelparth3/pi-annotations@v1.0.0
```

Try it without installing:

```bash
pi -e npm:pi-annotations
```

## Usage

Run `/annotate` (or press `ctrl+shift+a`) any time after the agent replies.
The last assistant message opens in a review overlay.

| Mode | Keys |
| --- | --- |
| Navigate | `j`/`k`/arrows, `PgUp`/`PgDn`, `g`/`G` |
| Mark | `v` start/extend a span, `s`/`enter` confirm it |
| Note | `i`/`a`/`enter` on a line: add a note, or edit the existing one |
| Note input | `enter` save, `esc` discard; saving an emptied note deletes the annotation |
| Batch | `x`/`d` delete under cursor, `C` clear all, `shift+enter`/`S` send, `esc` close |

Closing the overlay without sending keeps your work as a draft: reopening on the same message restores every annotation and the cursor position.
Sending clears the draft.

The batch arrives as a single user message with each note anchored to its quoted passage:

```
2 comment(s) on your last message - each quote anchors the comment below it. Address each by number and flag any conflicts.

[1]
> Store sessions in Redis with a 24h TTL and refresh the expiry on every request.
Note: refreshing on read means idle users never time out - is that intended?

[2]
> Delete the legacy /v1/auth endpoint once the migration ships.
Note: keep it behind a flag for one release instead of deleting outright
```

![The delivered batch in the transcript](assets/annotate-batch.png)

If the agent is still running when you send, the batch is queued as a follow-up automatically.

## Terminal notes

`ctrl+shift+a` and `shift+enter` rely on the Kitty keyboard protocol, which pi negotiates automatically on terminals that support it (Ghostty, kitty, WezTerm).
On other terminals the trigger chord degrades harmlessly to plain `ctrl+a`, and `S` remains as the always-working send key.
`/annotate` works everywhere regardless.

## Configuration

`PI_ANNOTATE_SHORTCUT` overrides the trigger chord:

```bash
PI_ANNOTATE_SHORTCUT=f2 pi
```

## Design

Annotations anchor to content, not position: what gets quoted is the exact source text of the lines you marked, never line numbers.
Rendered wrapping is display-only and cannot corrupt the anchor text.
The whole batch is delivered as one message so the agent sees every note while addressing each one - and one review round costs a single turn, not five.
Quotes are anchors rather than payloads: spans longer than a few lines are truncated to their edges, since the agent already has the full text in context.

## Development

```bash
npm install
npm test
```

The test suite drives the overlay headlessly through jiti - no terminal required.
