Skip to content

What planx is

planx turns the plan your coding agent writes into a versioned artifact you can annotate line by line, lock in place, and hand back. Nothing blocks and nothing polls — and the agent cannot change a section you locked without asking you first.

Reviewing an agent's plan today means reading a wall of markdown in a chat window and answering it with more prose. Nothing is anchored, so the agent re-reads the whole plan to guess which paragraph you meant. And nothing you settle stays settled — the next revision quietly rewrites the section you already agreed on, and you only notice three versions later.

The review, here, now

This is the real thing: the same rows, the same keys, the same rules. Click it and use your keyboard, or tap the keys underneath. Nothing is written anywhere — s prints the hand-off it would have printed, and shows you the markdown your agent would receive.

A real review, mid-flight: v3 of a plan, one comment already on it, the context section folded away, the rollout section frozen. Press d for the diff against v2.

╭─ planx v0.3.0 guard-clock-a3f9 v3 ─────────────────────────────────────────╮
1 # Guard the clock regression
2
3 ## Context
⋯ 10 lines (space to expand)
14 ## Approach
15
16 Reject the write at the R2 path, where every snapshot
17 already passes through one function, rather than in the
18 poller that happens to have produced it.
├───────────────────────────────────────────────────────────────────╮
Say which function. There are two on that path and only one of
them sees the period key.
╰───────────────────────────────────────────────────────────────────╯
19
20 - Read the period key already on the object.
21 - Refuse a write whose period is older than the one stored.
22 - Count the refusal against the node that sent it, with
This version has 2 feedbacks.
←→ version · d show diff · e rewrite line · f feedback · j next feedback
l lock line · n note · s submit · space fold section · v select lines
x exit · esc back · ? help
╰─────────────────────────────────────────────── ★ github.com/thisisnsh/planx ─╯

click to use your keyboard, or tap the keys below

Every page on this site carries one of these beside the feature it explains.

What each key does

KeyWhat it doesWhere it is explained
Move a row at a time. A note box is one stop, on its first line.Review Loop
vStart a selection; extend it. Selection is always whole lines.Review Loop
fFeedback on the selection, anchored to those exact lines. f on a note edits it; empty it to delete it.Review Loop
eRewrite the line yourself, in place, as raw markdown.Review Loop
lLock the selection, or lift a lock. Applied the moment you press it.Locking
spaceFold the section, or the note, or expand a collapsed run.Review Loop
j hWalk the feedback; fold every note at once.Review Loop
d The diff against the previous version, and the history.Diffing
nOne note about the whole plan.Review Loop
sSubmit everything at once, and print the command to paste back.Review Loop
aApprove — seals the plan and locks every section.Executing
?Every key, in the same order the hint bar puts them.

The hint bar along the bottom of the frame only ever offers keys that work on the row you are pointing at. f disappears on a locked passage, d is missing on v1, and s submit and a approve are never on the bar at the same time.

The problem, concretely

An agent proposes a plan across forty lines. You disagree with two of them, you want the rollout section left exactly as written, and the rest is fine.

Chat gives you one move: type a paragraph and hope. The agent maps your prose back onto its own text, revises everything at once, and returns a new wall of markdown. To find out what actually changed you diff it in your head. Meanwhile the rollout section you were happy with has picked up a new sentence, because nothing was holding it.

The failure is not that agents write bad plans. It is that plan review has no artifact — no stable text to point at, no record of which version you saw, and no way to say "this part is finished" that survives the next generation.

What planx does instead

The plan becomes a file with versions. You open it in a second terminal tab and work on the text directly:

  • Point at lines. Press v, extend with the arrows, type feedback, select three more spots, submit once. Every comment reaches the agent quoted against the exact lines it refers to.
  • Rewrite what you can say yourself. e opens a line as its source and what you type is what the plan says — no round trip through an agent that has to guess which word you meant.
  • Lock what is settled. Select lines, press l. Locked blocks come back to the agent as [[planx:keep L1]] markers it must reproduce verbatim.
  • Approve when you are done. The plan seals and every section locks.

A note hangs off a rail that runs down the lines it is about, between the line number and the text, so it is never a comment floating near a passage — it is attached to one, and its words start on the same left edge as theirs.

A version with a predecessor opens as the diff against it: you opened v3 because v3 is new, and what is new about it is the diff. d shows the plan on its own instead, and and walk the history.

You press s. It prints a command to paste back to your agent, which picks the plan up with your annotations attached to the lines they came from, and it revises.

Why a lock is different from an instruction

Enforcement lives in the storage layer, not in the prompt. planx capture refuses to write a version that mutates a locked block — so the agent physically cannot land the change, and has one path forward, which is to ask you.

Walk it:

  1. 1 · the agent captures
  2. 2 · the write is refused
  3. 3 · it asks, or it keeps the block
$ planx capture --plan-id guard-clock-a3f9 --parent v3 --stdin < plan.md

The agent has rewritten the rollout section. Lock L1 covers it.

That distinction is the whole point. A prompt is advice, and an unattended agent in bypass-permissions mode will eventually ignore it. A rejected write is not advice, and the unlock you then agree to grants exactly one capture before the lock re-arms.

Locks are an integrity mechanism against agent drift, not a security boundary against a hostile agent. See Locking.

Every plan you have, in one list

Bare planx opens the picker rather than a plan: every plan in the store, newest first, into its versions, and d on the row in front of you to delete it.

Bare planx with no arguments. Type to filter, opens a plan's versions, d deletes the row you are pointing at.

╭─ planx v0.3.0 ───────────────────────────────────────────────────────────────╮
planx
every plan in ~/.planx, newest first 3/3
❯ guard-clock-a3f9 Guard the clock regression · 3
rate-limit-uploads-77c2 Rate limit the upload endpoint
retry-webhooks-1b40 Retry failed webhooks with back
→ versions · ↑↓ choose · d delete · enter open · esc cancel
╰─────────────────────────────────────────────── ★ github.com/thisisnsh/planx ─╯

click to use your keyboard, or tap the keys below

Files are the protocol

Everything is ~/.planx and a CLI. No server, no daemon, no MCP, no lifecycle to manage:

~/.planx/plans/guard-clock-a3f9/
  meta.json  versions.json  locks.json
  v1.md  v2.md  v3.md
  feedback/

Which means any agent that can spawn a process is a first-class citizen. Claude Code and Codex both work today through the same skill files, and neither is privileged over the other.

Start here

bash
npm install -g @thisisnsh/planx
planx add-skills

Then type /planx in Claude Code or Codex.

  • Install — what the installer touches, channels, rollback
  • Review Loop — capture, review, revise, approve
  • Locking — how locks are enforced and lifted
  • CLI reference — every command and flag

MIT licensed.