Agent safety pattern

UI Review Gate

Review agent plans and diffs in the browser with Plannotator

Plannotator does not replace the coding agent. It adds a browser checkpoint before the agent continues, so you can inspect the plan, diff, or message visually and return exact feedback.

Plans Diffs Messages

A pattern, not just a tool

UI Review Gate is the checkpoint pattern; Plannotator is the tool that implements it.

Review in the browser

Plans, diffs, files, folders, URLs, and the latest agent message all open in a visual review UI.

Feedback goes back to the agent

Approve to continue, or send annotations so the agent fixes the plan or code first.

Why a visual gate

Long plans are hard to review in a terminal

The terminal is a poor surface for reviewing a long plan: there is nowhere to mark a specific spot, and reading a dense wall of text is exhausting. A visual UI fixes both — you read it like a document and annotate exactly where the change belongs.

In the terminal

  • Long plans scroll away

    A multi-step plan or large diff scrolls past in the terminal. You hold the whole thing in your head to keep track.

  • Reviewing a wall of text is tiring

    Reading a dense wall of text with no structure is mentally draining, so real issues slip through.

  • Feedback is retyped from memory

    There is no place to mark a specific line, so you describe the change from memory and hope the agent maps it back.

In Plannotator

  • Annotate right where the fix belongs

    Comment inline, on the exact line or block that needs the change. The note stays anchored to that spot.

  • Long plans become scannable

    The plan or diff opens as a structured, navigable document, so a long review is far easier on the brain.

  • Precise feedback, straight to the agent

    Each annotation carries its location and context, so the agent gets exact feedback instead of a vague summary.

What the gate covers

One pattern, several review surfaces

The same loop applies whether the artifact is a plan, a code diff, a rendered HTML page, a docs folder, or the agent response you just received.

The agent is paused the whole time the review is open. Nothing proceeds until you approve, so the gate is blocking by design — not a notification you can miss.

Plan review gate

Claude Code uses an ExitPlanMode PermissionRequest hook. Codex uses a Stop hook that reads the latest plan from the rollout transcript.

Code and diff review

The review command opens a diff review UI for current changes or a PR/MR URL, then returns feedback to the agent session.

Annotate artifacts

The annotate command covers Markdown, HTML, URLs, and folders; the last command targets the latest assistant message.

Remote-friendly port

Remote mode and a fixed port make the server reachable through forwarded ports, devcontainers, or tunnels.

Revisions and sessions

Plan re-submissions can show diffs. Sessions can be listed, reopened by number, or cleaned when stale.

Share links when appropriate

Small reviews can be shared through URL hash data. Large short links are opt-in and encrypted; sharing can be disabled for sensitive work.

Hook lifecycle

Where Plannotator enters the agent loop

The gate is not just a UI command. Each host wires it into a specific lifecycle point, then Plannotator turns approve/feedback into the native hook response for that host.

Default install favors plan review. File and response review hooks are opt-in recipes.

Claude Code

Before Claude leaves plan mode

PermissionRequest -> ExitPlanMode
Role
Blocks the plan handoff, reads tool_input.plan from stdin, opens the browser review gate, then lets Claude continue only after approval.
Enable
Install the Plannotator plugin from the Claude marketplace, or add a PermissionRequest hook matching ExitPlanMode in ~/.claude/settings.json.
Disable
Disable or uninstall the plugin, or remove that PermissionRequest hook entry. Restart Claude Code after changing hooks.

Codex

After a Codex turn stops with a plan

Stop
Role
Reads transcript_path, extracts the latest plan or <proposed_plan>, opens review, and returns continuation feedback when annotations are sent.
Enable
Installer auto-enables on macOS/Linux/WSL when ~/.codex exists. Manual setup uses [features] hooks = true plus a Stop hook in hooks.json.
Disable
Remove the Stop hook entry, or turn hooks off for that Codex config layer when you want all Codex hooks disabled there.

OpenCode

When the plan agent submits a plan

plan-agent submit_plan
Role
The npm plugin exposes submit_plan to the plan agent by default, so planning can be gated without giving build agents the same tool.
Enable
Add @plannotator/opencode to opencode.json and restart OpenCode. Run the installer too if you want the /plannotator-* commands.
Disable
Remove the plugin or switch workflow to manual for commands-only mode. Use all-agents only when broad tool access is intentional.

Opt-in hook recipes

PostToolUse -> Write

Review every file the agent writes. Useful for sensitive docs, generated HTML, or files where visual copy review matters.

Stop -> annotate-last

Review the agent response at turn end. Approve closes cleanly; annotations send feedback back into the agent loop.

--hook / --gate / --json

--hook makes the command gate and emit hook-native JSON. --gate adds the approval button. --json is for wrappers and logs.

Runtime switches

  • Use PLANNOTATOR_REMOTE=1 when the browser is on another device, VM, devcontainer, or Tailscale URL.
  • Pin PLANNOTATOR_PORT when mobile testing needs a stable QR/link.
  • Set PLANNOTATOR_BROWSER or BROWSER when the hook should open a specific browser.
  • Set PLANNOTATOR_SHARE=disabled when the gate must stay local-only.
  • Re-run the installer or remove hook config when switching between automatic gates and commands-only workflow.

Install and setup

Set it up in three steps

One installer covers every agent. Run it, finish the one step your agent needs, then try a command. No deep config required.

  1. 1

    Run the installer

    It adds the plannotator binary, auto-detects your installed agents, and wires up their hooks, skills, and slash commands.

    install
    # macOS / Linux / WSL
    curl -fsSL https://plannotator.ai/install.sh | bash
    
    # Windows PowerShell
    irm https://plannotator.ai/install.ps1 | iex
  2. 2

    Set up your agent

    Find your agent below and do its one step. Agents marked auto need nothing after the installer.

    Claude Code

    Add the marketplace plugin, then install plannotator@plannotator, and restart.

    Codex auto

    Nothing. Auto via the experimental Stop hook (macOS/Linux/WSL; off on Windows). $plannotator-* skills included.

    Gemini CLI auto

    Nothing — hook, policy, and slash commands are auto-configured. Requires Gemini CLI 0.36.0+.

    OpenCode

    Add @plannotator/opencode@latest to the plugin list in opencode.json, then restart.

    Copilot CLI

    Add the marketplace, install plannotator-copilot@plannotator. Plan review runs in plan mode (Shift+Tab).

    Amp

    Copy plannotator.ts into ~/.config/amp/plugins/ and reload. Workflows live in the command palette.

    Droid

    Add the marketplace, then install plannotator@plannotator. Commands only, no plan interception yet.

    Kiro CLI auto

    Nothing — skills and an example agent install automatically. Try kiro-cli chat --agent plannotator.

    Pi

    Skip the installer: pi install npm:@plannotator/pi-extension. Start with --plan or toggle /plannotator.

    Claude Code: manual hook (without the plugin system)
    ~/.claude/settings.json
    {
      "hooks": {
        "PermissionRequest": [
          {
            "matcher": "ExitPlanMode",
            "hooks": [
              { "type": "command", "command": "plannotator", "timeout": 345600 }
            ]
          }
        ]
      }
    }
  3. 3

    Try it

    Invoke a command yourself. Automatic plan review only fires when your host agent reaches a Plannotator-wired plan lifecycle hook; CK plan files are best opened manually with annotate.

    try it
    /plannotator-last                   # annotate the agent's last reply
    /plannotator-review                 # review your current diff, PR-style
    /plannotator-annotate plans/<plan>/plan.md # review a CK plan file
    /plannotator-annotate report.html   # annotate any file, folder, or URL

Mobile approval

Remote control and Plannotator UI are separate channels

Codex or Claude Code mobile can approve agent actions through their own remote-control path. Plannotator approval happens in a browser pointed at the Plannotator server, so the phone must be able to reach that server.

Same Wi-Fi

Open the host LAN URL from the phone. 127.0.0.1 will not work because it points to the phone itself.

Different network

Use Tailscale, VPN, or a tunnel. The link works only while that Plannotator session is running.

mobile remote access
export PLANNOTATOR_REMOTE=1
export PLANNOTATOR_PORT=9999

# Same Wi-Fi
open http://<host-lan-ip>:9999

# Tailscale Serve example
tailscale serve --bg --tcp=10000 9999
open http://<tailscale-ip>:10000/

Troubleshooting checklist

  • Port not listening: start a fresh Plannotator session and check the printed URL/port.
  • Phone cannot connect: confirm same Wi-Fi, firewall rules, or that Tailscale/VPN is connected on both devices.
  • MagicDNS fails: use the raw Tailscale IP first, then fix DNS later.
  • HTTP vs HTTPS: local Plannotator URLs are usually HTTP unless your tunnel adds TLS.
  • Stale sessions: run plannotator sessions --clean, then open a new review.

ClaudeKit fit

Yes — run it beside ClaudeKit

They do different jobs, so they pair cleanly. ClaudeKit drives the work — plan, cook, review, test. Plannotator is the human review gate: the browser surface where you inspect what CK produced and send precise feedback. Auto-blocking only happens when the host lifecycle hook fires.

Rule of thumb: Claude Code ExitPlanMode, Codex Stop, OpenCode submit_plan, and Pi plan mode can auto-open Plannotator. A normal ClaudeKit /ck:plan run is a plan-producing command, so treat Plannotator as an explicit review step.

How to use them together

  1. 1

    Plan with ClaudeKit, then gate the artifact

    /ck:plan → /plannotator-annotate plans/.../plan.md

    /ck:plan creates a CK plan artifact; it is not automatically the same as host plan mode. Open the generated plan.md file in Plannotator when you want a browser review gate.

  2. 2

    Implement, then review the diff

    /ck:cook → /plannotator-review

    Let /ck:cook handle the approved plan. Before you commit, open the diff with /plannotator-review and comment inline on the exact lines.

  3. 3

    Review docs and artifacts

    /plannotator-annotate ./docs

    Annotate Markdown, HTML, or folders such as ./docs with the same review surface, no extra setup.

Keep them as separate tools. Use Plannotator beside ClaudeKit, not merged into it — that keeps CK free of a UI server and browser state, and lets each update on its own schedule.

When not to use it

Use a gate only when the pause is worth it

  • Do not use a browser gate for tiny, reversible edits where the diff is easier to read inline.
  • Do not share sensitive plans unless sharing is disabled or your team accepts the URL/short-link privacy model.
  • Do not treat approval as a test result. Still run tests, builds, and source checks after the agent changes code.