github backnotprop/plannotator v0.19.0

5 hours ago

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.18.0 Annotate focus & wide modes, OpenCode origin detection, word-level inline plan diff, Markdown content negotiation, color swatches
v0.17.10 HTML and URL annotation, loopback binding by default, Safari scroll fix, triple-click fix, release pipeline smoke tests
v0.17.9 Hotfix: pin Bun to 1.3.11 for macOS binary codesign regression
v0.17.8 Configurable default diff type, close button for sessions, annotate data loss fix, markdown rendering polish
v0.17.7 Fix "fetch did not return a Response" error in OpenCode web/serve modes
v0.17.6 Bun.serve error handlers for diagnostic 500 responses, install.cmd cache fix
v0.17.5 Fix VCS detection crash when p4 not installed, install script cache path fix
v0.17.4 Vault browser merged into Files tab, Kanagawa themes, Pi idle session tool fix
v0.17.3 Sticky lane repo/branch badge overflow fix
v0.17.2 Supply-chain hardening, sticky toolstrip and badges, overlay scrollbars, external annotation highlighting, Conventional Comments
v0.17.1 Pi PR review parity, parseRemoteUrl rewrite, cross-repo clone fixes, diff viewer flash fix
v0.17.0 AI code review agents, token-level annotation, merge-base diffs

What's New in v0.19.0

v0.19.0 lands updates across all four surfaces — Plan/Annotate, Code Review, Pi, and Claude Code. Four PRs, one from a first-time contributor.

Plan / Annotate

GitHub-Flavored Markdown

The in-app reader now matches GitHub's rendering across blocks and inline. Raw HTML blocks (<details>, <summary>, and friends) render through marked plus DOMPurify, with nested markdown preserved; innerHTML is set imperatively via ref+useEffect so React reconciliation doesn't collapse an open <details> on rerender. GitHub alerts (> [!NOTE], [!TIP], [!WARNING], [!CAUTION], [!IMPORTANT]) render with inline Octicons and Primer colors, honoring prefers-color-scheme. Directive containers (:::kind ... :::) cover project-specific callouts, and every heading now carries a slug-derived anchor id.

Inline gains came alongside: bare URL autolinks with trailing-punctuation trimming; @mentions and #issue-refs that render as clickable links when the repo is a GitHub repo and styled spans otherwise; 29 curated emoji shortcodes (:wave:, :rocket:, …); and smart punctuation (curly quotes, em and en dashes, ellipsis). All inline transforms run after the code-span regex has consumed code content, so backticks stay literal for shell and regex snippets.

The refactor that landed with the feature is as important as the feature itself: InlineMarkdown, BlockRenderer, and the new block components were pulled out of Viewer.tsx into dedicated files. Viewer dropped from 1279 to 770 lines. New block features now land in blocks/*.tsx rather than swelling Viewer further. DOMPurify's allowlist blocks on* handlers, style attrs, and scripts; sanitizeLinkUrl strips javascript:, data:, vbscript:, and file: protocols. Total bundle cost: +1.8KB gzipped.

Copy Table as Markdown or CSV

Every markdown table now has a small toolbar. Copy the rendered table as markdown (round-trip ready for another document) or as RFC 4180 CSV (safe to paste into a spreadsheet — commas, quotes, and newlines are escaped per the spec). Useful when a plan or annotated doc includes a comparison table you want to extract.

Table Popout

Tables can also pop out into a dedicated overlay for wide or dense data that doesn't fit the reader flow. The popout gives the table its own scroll container, so you can read across columns without competing with the document's own scroll position. Cycle back to the inline table when you're done.

  • All three features shipped in #597

Code Review

Custom Settings Per Agent

Every review agent now has first-class model and effort/reasoning controls. Claude Review exposes --model and --effort. Codex Review exposes -m, -c model_reasoning_effort=..., and -c service_tier=fast. Code Tour supports both engines, each with its own model and effort settings. The Settings dropdowns dropped the hidden "Default" option in favor of explicit sensible defaults — Opus 4.7 / High for Claude, GPT-5.3 Codex / High for Codex, Sonnet / Medium for Tour Claude, GPT-5.3 Codex / Medium for Tour Codex.

Codex reasoning's invalid none option is gone (codex-rs rejects it); a one-shot cookie migration rewrites existing users' none values to the default on load so nobody keeps launching a broken flag.

Settings persistence moved to a single plannotator.agents cookie that holds the whole agent settings tree, keyed per (agent × model). Switching models reveals the effort/reasoning/fast-mode you last used with that specific model. React state is the authority; the cookie mirrors it; all mutations funnel through a single owner via functional setState, so rapid successive changes can't stale-read or lose writes.

The job card badge now carries the full story — Claude · Opus 4.7 · High, Codex · GPT-5.3 Codex · Medium · Fast, Tour · Claude · Sonnet · Medium — and the main dropdown reads action-first: Code Review · Claude, Code Review · Codex, Code Tour.

Code Tour

Alongside Claude Review and Codex Review, Plannotator now ships a third review agent: Code Tour. Point it at a PR and it produces a guided walkthrough — greeting, stated intent, before/after framing, ordered stops with inline diff anchors, key takeaways, and a QA checklist — rendered in a three-page animated dialog. Similar in spirit to Cursor's and Graphite's PR walkthroughs, but wired into the same review surface you already use. Demos coming.

The tour auto-opens when the job reaches a terminal state. Checklist state persists across dialog open/close within a review session, and pending saves are flushed on unmount with keepalive: true so closing the dialog during the 500ms debounce window never drops a tick.

Both Claude and Codex can drive the tour. Claude streams JSONL via stdin; Codex writes to a file via --output-schema. If the model returns empty or malformed output, the job flips to failed with a clear error rather than silently 404ing the dialog. Under prefers-reduced-motion, page navigation swaps directly instead of waiting on an onAnimationEnd that would otherwise soft-lock the walkthrough behind the intro. The Claude allowlist permits gh issue view, gh api repos/*/*/issues/*, and glab issue view, so when the prompt follows a Fixes #123, the agent can actually read the linked issue.

Under the hood, a shared createTourSession() factory owns the lifecycle — buildCommand, onJobComplete, getTour, saveChecklist — so the Bun hook server and the Pi Node server wire it up with about 25 lines of route glue each instead of the ~100 lines of duplicated provider-branch logic that the review agents used to carry. Route parity (GET /api/tour/:jobId, PUT /api/tour/:jobId/checklist) is enforced by tests across both runtimes.

  • Custom settings and Code Tour shipped in #569

Pi

More Flexible Planning Mode

The Pi extension used to require a single configured plan-file path — set once via --plan-file or /plannotator-set-file and stuck with it for the session. In practice this made multi-plan workflows awkward and confused the agent when a repo already had its own plan conventions. That whole layer is gone.

plannotator_submit_plan gained a required filePath argument, and the agent now writes its plan as a markdown file anywhere inside the working directory, passing the path at submission. Validation enforces .md or .mdx extension, rejects .. traversal and absolute paths that escape cwd, and stat-checks the file before it's read. The planning write gate allows any markdown file inside cwd, and lastSubmittedPath tracks the most recent submission so the execution phase rebuilds correctly on session resume — including after a denial. The planning system prompt suggests (but doesn't require) PLAN.md at the repo root or plans/<short-name>.md.

Since version history in ~/.plannotator/history/{project}/{slug}/ keys off plan content (first # Heading plus date) rather than file path, free-form naming keeps version linking intact.

Breaking changes for Pi users: the --plan-file flag, the /plannotator-set-file slash command, and the file-path argument to /plannotator have been removed. Existing workflows that relied on them need to let the agent pick the path instead.

Claude Code

/plannotator-last with Multiple Sessions in the Same Directory

/plannotator-last used to pick the wrong session whenever two Claude Code sessions shared a repo. Invoked from a slash command's ! bang, Plannotator's direct parent (process.ppid) is the intermediate bash shell that the Bash tool spawned, not Claude Code itself. The old resolveSessionLogByPpid() always missed on that parent, and the mtime-based fallback picked whichever .jsonl in the project had been touched most recently — which was usually the other session.

The fix is a four-tier resolution ladder. First, an ancestor-PID walk calls ps -o ppid= from process.ppid up to eight hops, checking ~/.claude/sessions/<pid>.json at each one; this matches the exact session deterministically. Second, a cwd-scan reads every session metadata file, filters by cwd, and picks the entry with the most recent startedAt — a better fallback than mtime when ps is unavailable. The legacy cwd-slug mtime check and ancestor directory walk remain as tiers three and four. 17 new tests cover the ladder with injectable process-tree and filesystem dependencies.

Additional Changes

  • Prompts reference page. New /docs/reference/prompts/ page documents the three-layer message shape — system prompt owned by the CLI, user message (review prompt joined to user prompt with \n\n---\n\n), and JSON schema as a terminal constraint. Calls out that Claude and Codex review prompts are upstream-derived; only Tour's prompt is new (#569)
  • Motion library added. Code Tour's spring-driven accordions and intro composition cascade pulled in motion@12.38.0 (~30 KB gzipped) (#569)

Install / Update

macOS / Linux:

curl -fsSL https://plannotator.ai/install.sh | bash

Windows:

irm https://plannotator.ai/install.ps1 | iex

Claude Code Plugin: Run /plugin in Claude Code, find plannotator, and click "Update now".

OpenCode: Clear cache and restart:

rm -rf ~/.bun/install/cache/@plannotator

Then in opencode.json:

{
  "plugin": ["@plannotator/opencode@latest"]
}

Pi: Install or update the extension:

pi install npm:@plannotator/pi-extension

What's Changed

  • feat: Code Tour — guided PR walkthrough as a third agent provider by @backnotprop in #569
  • fix(pi): let agent submit any markdown plan file by path by @backnotprop in #595
  • feat(ui): markdown reader parity — HTML blocks, GitHub alerts, GFM inline extras by @backnotprop in #597
  • fix(session-log): walk ancestor PIDs to resolve correct session log by @elithompson in #598

New Contributors

Contributors

@elithompson authored the session-log ancestor-PID walk (#598), closing a long-standing issue where /plannotator-last picked the wrong session whenever two Claude Code sessions shared a repo. First contribution to the project.

@blimmer diagnosed and reported the session-log bug (#458) with a detailed empirical walkthrough of the process tree, which made the fix straightforward to scope.

Full Changelog: v0.18.0...v0.19.0

Don't miss a new plannotator release

NewReleases is sending notifications on new releases.