Interactive plan and diff review for AI coding agents. Visual browser UI for annotating agent plans — approve or request changes with structured feedback. Supports code review, image annotation, and auto-save to Obsidian/Bear Notes.
81
72%
Does it follow best practices?
Impact
100%
1.33xAverage score across 3 eval scenarios
Critical
Do not install without reviewing
Optimize this skill with Tessl
npx tessl skill review --optimize ./.agent-skills/plannotator/SKILL.mdKeyword:
plan| Source: https://github.com/backnotprop/plannotatorAnnotate and review AI coding agent plans visually, share with your team, send feedback with one click. Works with Claude Code, OpenCode, Gemini CLI, and Codex CLI.
All patterns have a corresponding script in scripts/. Run them directly or let the agent call them.
| Script | Pattern | Usage |
|---|---|---|
scripts/install.sh | CLI Install | One-command install; --all sets up every AI tool |
scripts/setup-hook.sh | Claude Code Hook | Configure Claude Code ExitPlanMode hook |
scripts/setup-gemini-hook.sh | Gemini CLI Hook | Configure Gemini CLI ExitPlanMode hook + GEMINI.md |
scripts/setup-codex-hook.sh | Codex CLI Setup | Configure Codex CLI developer_instructions + prompt |
scripts/setup-opencode-plugin.sh | OpenCode Plugin | Register plugin + slash commands |
scripts/check-status.sh | Status Check | Verify all integrations and configuration |
scripts/configure-remote.sh | Remote Mode | SSH / devcontainer / WSL configuration |
scripts/review.sh | Code Review | Launch diff review UI |
# Install CLI only (macOS / Linux / WSL)
bash scripts/install.sh
# Install CLI and get Claude Code plugin commands
bash scripts/install.sh --with-plugin
# Install CLI + configure Gemini CLI
bash scripts/install.sh --with-gemini
# Install CLI + configure Codex CLI
bash scripts/install.sh --with-codex
# Install CLI + register OpenCode plugin
bash scripts/install.sh --with-opencode
# Install CLI + all AI tool integrations at once
bash scripts/install.sh --allWhat it does:
https://plannotator.ai/install.sh# Add hook to ~/.claude/settings.json
bash scripts/setup-hook.sh
# Preview what would change (no writes)
bash scripts/setup-hook.sh --dry-runWhat it does:
ExitPlanMode hook into ~/.claude/settings.json safely (backs up first)Run inside Claude Code:
/plugin marketplace add backnotprop/plannotator
/plugin install plannotator@plannotator
# IMPORTANT: Restart Claude Code after plugin installTriggered automatically via hook when Claude Code exits plan mode.
When your agent finishes planning (Claude Code: Shift+Tab×2 to enter plan mode), plannotator opens automatically:
delete — remove risky or unnecessary stepinsert — add missing stepreplace — revise incorrect approachcomment — clarify constraints or acceptance criteria# Review all uncommitted changes
bash scripts/review.sh
# Review a specific commit
bash scripts/review.sh HEAD~1
# Review branch diff
bash scripts/review.sh main...HEADWhat it does:
plannotator review UI# Interactive setup (SSH, devcontainer, WSL)
bash scripts/configure-remote.sh
# View current configuration
bash scripts/configure-remote.sh --show
# Set port directly
bash scripts/configure-remote.sh --port 9999What it does:
.zshrc, .bashrc, .profile)PLANNOTATOR_REMOTE=1 and PLANNOTATOR_PORT to shell profileManual environment variables:
export PLANNOTATOR_REMOTE=1 # No auto browser open
export PLANNOTATOR_PORT=9999 # Fixed port for forwarding| Variable | Description |
|---|---|
PLANNOTATOR_REMOTE | Remote mode (no auto browser open) |
PLANNOTATOR_PORT | Fixed local/forwarded port |
PLANNOTATOR_BROWSER | Custom browser path/app |
PLANNOTATOR_SHARE_URL | Custom share portal URL |
bash scripts/check-status.shChecks all of:
~/.claude/settings.json (or plugin detected)~/.gemini/settings.json~/.codex/config.toml developer_instructionsopencode.json + slash commands# Configure Gemini CLI (hook + GEMINI.md instructions)
bash scripts/setup-gemini-hook.sh
# Preview what would change (no writes)
bash scripts/setup-gemini-hook.sh --dry-run
# Only update settings.json hook (skip GEMINI.md)
bash scripts/setup-gemini-hook.sh --hook-only
# Only update GEMINI.md (skip settings.json)
bash scripts/setup-gemini-hook.sh --md-onlyWhat it does:
ExitPlanMode hook into ~/.gemini/settings.json (same format as Claude Code)~/.gemini/GEMINI.mdUsage in Gemini CLI after setup:
# Enter planning mode (hook fires when you exit)
gemini --approval-mode plan
# Manual plan review (validated format)
python3 -c "
import json
plan = open('plan.md').read()
print(json.dumps({'tool_input': {'plan': plan, 'permission_mode': 'acceptEdits'}}))
" | plannotator > /tmp/plannotator_feedback.txt 2>&1 &
# Code review after implementation
plannotator reviewNote: Gemini CLI supports
gemini hooks migrate --from-claudeto auto-migrate existing Claude Code hooks.
# Configure Codex CLI (developer_instructions + prompt file)
bash scripts/setup-codex-hook.sh
# Preview what would change (no writes)
bash scripts/setup-codex-hook.sh --dry-runWhat it does:
developer_instructions in ~/.codex/config.toml~/.codex/prompts/plannotator.md (invoke with /prompts:plannotator)Usage in Codex CLI after setup:
# Use the plannotator agent prompt
/prompts:plannotator
# Manual plan review (validated format)
python3 -c "
import json
plan = open('plan.md').read()
print(json.dumps({'tool_input': {'plan': plan, 'permission_mode': 'acceptEdits'}}))
" | plannotator > /tmp/plannotator_feedback.txt 2>&1 &
# Code review after implementation
plannotator review HEAD~1Note:
plannotator plan -with heredoc/echo can fail withFailed to parse hook event from stdin. Use the python3 JSON format above.
Save the current plan to Obsidian or Bear Notes at any time — without approving or denying.
Note: The Notes tab uses
POST /api/save-noteswhich writes directly to the vault filesystem (Obsidian) or callsbear://x-callback-url/create(Bear). This endpoint is only available in hook mode.
# 1. Install CLI + configure all AI tool integrations at once
bash scripts/install.sh --all
# 2. Verify everything
bash scripts/check-status.sh
# 3. Restart your AI tools (Claude Code, Gemini CLI, OpenCode, Codex)1. bash scripts/install.sh --with-plugin
└─ Installs CLI + shows plugin install commands
2. bash scripts/setup-hook.sh ← skip if using plugin
└─ Configures automatic plan review trigger
3. bash scripts/check-status.sh
└─ Confirm everything is ready
4. [Code with agent in plan mode → Shift+Tab×2]
└─ plannotator opens automatically
5. bash scripts/review.sh ← after agent finishes coding
└─ Opens visual diff review1. bash scripts/install.sh
2. bash scripts/setup-gemini-hook.sh
3. gemini --approval-mode plan ← work in plan mode
└─ plannotator fires on exit1. bash scripts/install.sh
2. bash scripts/setup-codex-hook.sh
3. /prompts:plannotator ← inside Codex session# Automated (recommended)
bash scripts/setup-opencode-plugin.sh
# Or add manually to opencode.json:{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@plannotator/opencode@latest"]
}After setup, restart OpenCode. Available slash commands:
/plannotator-review — open code review UI for current git diff/plannotator-annotate <file.md> — annotate a markdown fileThe submit_plan tool is automatically available to the agent for plan submission.
Auto-save approved plans to your Obsidian vault with YAML frontmatter and tags.
~/Documents/Obsidian/MyVaultobsidian.json config after first vault creation# Check Obsidian installation (macOS)
ls /Applications/Obsidian.app
# Check Obsidian config exists (vault detection depends on this)
# macOS
cat ~/Library/Application\ Support/obsidian/obsidian.json
# Linux
cat ~/.config/obsidian/obsidian.json
# Windows
cat %APPDATA%/obsidian/obsidian.json# Step 1: Verify Obsidian is installed and has at least one vault
bash scripts/check-status.sh
# Step 2: Trigger a plan review (any method)
# Claude Code: Shift+Tab×2 → plan mode → exit plan mode
# Gemini CLI: gemini --approval-mode plan
# OpenCode: Agent creates a plan
# Step 3: In the plannotator UI:
# 1. Click ⚙️ (Settings gear icon)
# 2. Go to "Saving" tab
# 3. Toggle ON "Obsidian Integration"
# 4. Select your vault from dropdown (auto-detected)
# - Or enter custom path if vault not detected
# 5. Set folder name (default: "plannotator")
# Step 4: Approve a plan to test the integration
# - Click "Approve" in the plannotator UI
# - Check your vault for the saved file| Setting | Description | Default |
|---|---|---|
| Vault | Path to Obsidian vault | Auto-detected |
| Folder | Subfolder in vault for plans | plannotator |
| Custom Path | Manual path if auto-detect fails | - |
Files are saved with human-readable names and YAML frontmatter:
Filename: {Title} - {Month} {Day}, {Year} {Hour}-{Minute}{am/pm}.md
Example: User Authentication - Feb 22, 2026 10-45pm.md---
created: 2026-02-22T22:45:30.000Z
source: plannotator
tags: [plannotator, project-name, typescript, ...]
---
[[Plannotator Plans]]
# Original plan content...Tag extraction:
plannotator — always includedOrganize plans within the vault using subfolders:
vault/plannotator/
├── approved/ ← approved plans
├── denied/ ← rejected plans
└── 2026-02/ ← monthly archiveCreate subfolders manually (Obsidian detects them automatically):
mkdir -p ~/path/to/vault/plannotator/approved
mkdir -p ~/path/to/vault/plannotator/denied
mkdir -p ~/path/to/vault/plannotator/2026-02Or write directly to any subfolder:
cp ~/.plannotator/plans/<name>-approved.md ~/path/to/vault/plannotator/approved/If you prefer Bear Notes over Obsidian:
bear://x-callback-url/createopen "bear://x-callback-url/create?title=Plannotator%20Check&text=Bear%20callback%20OK"| Feature | Obsidian | Bear |
|---|---|---|
| Storage | File system | x-callback-url |
| Frontmatter | YAML | None (hashtags) |
| Platforms | macOS/Win/Linux | macOS/iOS |
Vault not detected:
# 1. Check Obsidian config exists
ls ~/Library/Application\ Support/obsidian/obsidian.json # macOS
# 2. If missing, open Obsidian and create a vault first
open /Applications/Obsidian.app
# 3. After creating vault, restart plannotatorPlans not saving:
# Check write permissions on vault folder
ls -la ~/path/to/vault/plannotator/
# Check browser console for errors (F12 → Console)Export → Notes tab Save buttons require hook mode:
review/annotate modes, the /api/save-notes endpoint is not active. Normal Claude Code hook invocation (ExitPlanMode hook) always runs in hook mode.Settings not visible in automated/headless browsers:
Bear export not working:
open "bear://x-callback-url/create?..." works from terminalSettings not persisting:
Obsidian integration is optional — plans can still be reviewed and approved without it.
c033769
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.