Skip to content

Releases: backnotprop/plannotator

v0.19.7

02 May 21:05
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.19.6 Non-blocking Pi browser sessions, agent picker dropdown for OpenCode, annotate-last file resolution fix
v0.19.5 All-files diff view, clickable code file paths, server-side hide whitespace, non-ASCII path support
v0.19.4 All-files diff type, code file viewer, hide whitespace, quick-settings popover
v0.19.3 Configurable feedback messages, hide merged PRs in stacked PR selector
v0.19.2 Stacked PR review, source line numbers in feedback, diff type dialog re-show, ghost dot removal, docs cleanup
v0.19.1 Hook-native annotation, custom base branch, OpenCode workflow modes, quieter plan diffs, anchor navigation
v0.19.0 Code Tour agent, GitHub-flavored Markdown, copy table as Markdown/CSV, flexible Pi planning mode, session-log ancestor-PID walk
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

What's New in v0.19.7

v0.19.7 brings Codex plan review to Plannotator. Four PRs, two from first-time contributors, extend full plan review support to OpenAI's Codex CLI and add Codex-callable skills for review, annotate, and annotate-last. Two UX improvements for the plan and code review editors round out the release.

Codex Plan Review via Stop Hook

Plannotator now intercepts Codex plan submissions through Codex's Stop hook system. When Codex proposes a plan, the hook extracts the plan from the agent's rollout transcript, opens Plannotator in the browser, and lets you review, annotate, and approve or deny exactly as you would with Claude Code. Denying sends structured feedback back to Codex with continuation instructions, so the agent revises and resubmits.

The implementation parses Codex's output format to find the latest plan content, handles both fresh plans and revised resubmissions, and supports the full Plannotator feature set: version history, plan diff, archive, and annotation. All three install scripts (install.sh, install.ps1, install.cmd) now configure Codex hooks automatically during installation when a Codex config directory is detected.

The release pipeline also gained smoke tests that exercise the compiled binary's server startup across plan review, code review, and annotate subcommands, catching integration failures before artifacts are published.

Codex Skills for Review, Annotate, and Last

Codex's app interface doesn't accept ! shell commands in chat, which made invoking Plannotator awkward. This PR adds three OpenAI-compatible skill definitions under apps/skills/ that make Plannotator callable via $plannotator-review, $plannotator-annotate, and $plannotator-last directly from the Codex app.

Each skill instructs the agent to run the Plannotator command, wait for the browser session to complete, and then act on the returned feedback without requiring an extra follow-up message from the user. This closes a workflow gap where Codex would receive annotation feedback but sit idle until explicitly prompted to continue.

Additional Changes

  • Auto-close sidebar when TOC is empty. Documents with no level 1-3 headings (common in annotate and annotate-last sessions) no longer force-open the Table of Contents sidebar. The collapsed sidebar strip remains accessible for manual opening, and the preference resets when the document changes. Archive and annotate-folder modes are unaffected. (#651 by @backnotprop)
  • Right-click to copy path or filename in file tree. The code review file tree now has a context menu on each file row with "Copy path" (repo-relative), "Copy filename", and "Copy full path" options. Full path resolves against the active worktree or agent CWD and is hidden in PR-review mode where files aren't on local disk. (#650 by @backnotprop)

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

New Contributors

Contributors

@ivanov17andrey authored the Codex Stop-hook plan review integration (#577), bringing full plan review support to a new agent platform. The PR included Codex session parsing, install script updates across all three platforms, CI smoke tests, a reproducible E2E test harness, and documentation updates. First contribution to the project.

@leoreisdias added Codex skill definitions (#644) that bridge the gap between Codex app's UI and Plannotator's shell-based invocation. Also a first contribution.

Community members who requested Codex support:

Full Changelog: v0.19.6...v0.19.7

v0.19.6

02 May 01:41
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.19.5 All-files diff view, clickable code file paths, server-side hide whitespace, non-ASCII path support
v0.19.4 All-files diff type, code file viewer, hide whitespace, quick-settings popover
v0.19.3 Configurable feedback messages, hide merged PRs in stacked PR selector
v0.19.2 Stacked PR review, source line numbers in feedback, diff type dialog re-show, ghost dot removal, docs cleanup
v0.19.1 Hook-native annotation, custom base branch, OpenCode workflow modes, quieter plan diffs, anchor navigation
v0.19.0 Code Tour agent, GitHub-flavored Markdown, copy table as Markdown/CSV, flexible Pi planning mode, session-log ancestor-PID walk
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

What's New in v0.19.6

v0.19.6 ships 3 PRs closing 4 long-standing issues. Two changes stand out: Pi browser sessions are now fully async, so review and annotation commands no longer lock the chat while the UI is open; and OpenCode gets a visible agent picker on the Approve button, replacing the buried Settings-only agent switch. A fix for annotate-last mode rounds out the release.

Non-Blocking Browser Sessions for Pi

Every Plannotator command in Pi that opens a browser — plan review, code review, annotation, and annotate-last — previously blocked the chat session until the browser tab was closed. The chat input was locked the entire time. If the review server crashed, or the user simply forgot to close the tab, the Pi session hung indefinitely with no way to recover except restarting.

This release rewrites the Pi browser session lifecycle from the ground up. All four browser-based flows now return control to the chat immediately after opening the browser. Users can continue working, ask follow-up questions, or start entirely new tasks while the review UI stays open in a separate tab. When the user submits feedback, approves a plan, or closes the browser, the decision is forwarded back into the Pi session automatically.

The implementation introduces a BrowserDecisionSession abstraction that wraps the server lifecycle, browser launch, and decision forwarding into a single async pattern. Each session tracks its own state and cleanup, so multiple review sessions can coexist without interfering. A stop() mechanism ensures sessions are cleaned up even if the browser tab is abandoned, preventing zombie server processes.

This also required extracting assistant message parsing into a dedicated module (assistant-message.ts) and building a session state tracker (current-pi-session.ts) to correctly scope tool availability and saved state across the new async boundaries.

Agent Picker Dropdown for OpenCode

OpenCode users can now select which agent to switch to directly from a split Approve button, without opening Settings. The button label shows exactly what will happen: "Approve → Build", "Approve → Orchestrator", or just "Approve" when switching is disabled. Click the chevron to see all available agents from the OpenCode API, plus a "No switch" option that prevents any agent mode change on approval.

Before this change, agent switching was controlled by a setting buried in the Plannotator Settings panel. Most users didn't know it existed. The default was "Build", which meant every plan approval silently switched the CLI to Build mode. Users running Orchestrator workflows, Sisyphus mode, or custom agent topologies would find their agent unexpectedly changed after approving a plan.

The "No switch" option also changes the approval prompt itself. When selected, the "approved with notes" message no longer includes "Proceed with implementation," letting the current agent decide its own next step. This is particularly useful for planning-only workflows where approval shouldn't trigger immediate implementation.

Non-OpenCode origins (Claude Code, Gemini CLI, Copilot CLI) are completely unaffected and continue using the standard Approve button.

Fix Code File and Linked Doc Resolution in Annotate-Last Mode

When annotating the last assistant message (plannotator last or /plannotator-annotate last), clicking a code file path or linked document returned a 404. The annotate-last mode sets filePath to the literal string "last-message", which was passed through as a filesystem base directory for resolving relative paths. The server tried to resolve files against "last-message" as a directory, which doesn't exist.

The fix guards both the code file popout and linked doc URL builders to skip non-path values and fall back to the project root. Normal file and folder annotation are unaffected since those use real filesystem paths.


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(pi): make browser review and annotation sessions async by @backnotprop in #645
  • feat(opencode): agent picker dropdown on Approve button by @backnotprop in #648
  • fix(ui): code file and linked doc resolution in annotate-last mode by @backnotprop in #647

Community

Four issues drove the agent picker feature, all from users who were surprised or frustrated by invisible agent switching:

Full Changelog: v0.19.5...v0.19.6

v0.19.5

01 May 07:18
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.19.4 All-files diff type, code file viewer, hide whitespace, quick-settings popover
v0.19.3 Configurable feedback messages, hide merged PRs in stacked PR selector
v0.19.2 Stacked PR review, source line numbers in feedback, diff type dialog re-show, ghost dot removal, docs cleanup
v0.19.1 Hook-native annotation, custom base branch, OpenCode workflow modes, quieter plan diffs, anchor navigation
v0.19.0 Code Tour agent, GitHub-flavored Markdown, copy table as Markdown/CSV, flexible Pi planning mode, session-log ancestor-PID walk
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

What's New in v0.19.5

v0.19.5 is a review editor release with five changes across four PRs and one direct commit. The headline feature is the all-files diff view, which renders every changed file in a single scrollable pane. This release also fixes two bugs reported by community members: code review failing on repos with non-ASCII file paths (Korean, Chinese, Japanese, Cyrillic, etc.), and hide-whitespace destroying code indentation.

All-Files Diff View

The review editor now has a unified scrolling mode that renders every changed file in a single pane, with sticky file headers and viewport-based lazy mounting via IntersectionObserver. Instead of clicking through files one at a time, you can scroll through the entire diff in one pass.

Each file has a sticky header that stays visible as you scroll, showing the file path, viewed/staged status, and collapse controls. Files can be collapsed individually or marked as viewed (which auto-collapses them). Keyboard shortcuts make navigation fast: [ and ] scroll between files, v marks a file as viewed and collapses it, a stages or unstages, c opens a file comment, and x collapses or expands. The z key undoes the last collapse, reopening the file and scrolling back to it.

The all-files view opens by default and coexists with single-file tabs in the Dockview panel system. Click-and-drag line selection works directly in the diff content area, not just the gutter.

File Comments in All-Files View

The single-file diff view already supported file-scoped comments via a button in the file header. The all-files view now has the same capability. Press c or click the comment button in any file's sticky header to open a comment popover anchored to that file. This rounds out the annotation workflow so you can leave file-level feedback without switching to a single-file tab.

Clickable Code File Paths in Plans

Inline code spans like `src/utils/foo.ts` and bare prose paths like packages/server/index.ts are now detected as code file paths and rendered as clickable elements. Clicking one opens the code file viewer with syntax highlighting, the same viewer introduced in v0.19.4 for markdown file links.

Backtick-wrapped paths use direct file extension matching, while bare prose paths require a / separator to avoid false positives on plain words. A subtle shimmer animation hints at interactivity without disrupting the familiar inline-code appearance. The shimmer respects prefers-reduced-motion.

Server-Side Hide Whitespace

The hide-whitespace toggle introduced in v0.19.4 processed whitespace suppression on the client side by normalizing file contents before diffing. This worked for most cases but had a side effect: the normalization trimmed and collapsed whitespace in the file content itself, destroying all code indentation in the rendered diff.

The fix moves whitespace handling to the server, where git diff -w does the comparison correctly. Git ignores whitespace for diffing purposes but preserves the original formatting in its output. The setting is read from ~/.plannotator/config.json on startup so the initial diff already respects the saved preference. Toggling the setting does an in-place patch update without resetting the active file.

Non-ASCII and Whitespace File Path Support

Code review was showing 0 files when the repository contained paths with non-ASCII characters (Korean, Chinese, Japanese, accented Latin, Cyrillic, etc.) or whitespace. Git defaults to core.quotePath=true, which emits paths as octal escapes (e.g., \355\225\234\352\265\255\354\226\264 instead of 한국어). The diff parser expected unquoted paths and silently dropped every affected file.

The fix passes -c core.quotePath=false as a per-invocation flag to both the Bun and Pi server git entry points. This outputs raw UTF-8 paths without modifying the user's git config. It has no effect on ASCII-only repositories.


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

  • fix(review): support non-ASCII and whitespace file paths in code review by @backnotprop in #637
  • fix(review): move hide-whitespace to server-side git diff -w by @backnotprop in #638
  • feat(ui): detect code file paths in backtick spans and bare prose by @backnotprop in #639
  • feat(review): all-files diff view with unified scrolling by @backnotprop in #640
  • feat(review): file comment button in all-files view + remap C/X shortcuts by @backnotprop

Community

Two community reports directly shaped this release:

  • @silee9019 filed a detailed bug report in #628 documenting the non-ASCII file path issue, including a minimal reproduction case and the root cause analysis that identified core.quotePath as the culprit
  • @zeroZshadow caught the hide-whitespace indentation regression on #631, which led to the server-side rewrite in #638

Full Changelog: v0.19.4...v0.19.5

v0.19.4

30 Apr 18:13
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.19.3 Configurable feedback messages, hide merged PRs in stacked PR selector
v0.19.2 Stacked PR review, source line numbers in feedback, diff type dialog re-show, ghost dot removal, docs cleanup
v0.19.1 Hook-native annotation, custom base branch, OpenCode workflow modes, quieter plan diffs, anchor navigation
v0.19.0 Code Tour agent, GitHub-flavored Markdown, copy table as Markdown/CSV, flexible Pi planning mode, session-log ancestor-PID walk
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

What's New in v0.19.4

v0.19.4 is a review editor release. Six PRs bring a new diff type for reviewing entire repos, a code file viewer with syntax highlighting and annotation support, per-file quick-settings for diff display, and a hide-whitespace toggle that matches GitHub's ?w=1 behavior.

"All Files" Diff Type

Sometimes you want to review an entire repository, not just uncommitted changes. The new "All files" diff type diffs the empty tree against HEAD, showing every tracked file as an addition. This is useful when a repo has no working tree changes but you still want to launch a review, or when you want to browse the full codebase through the review UI.

The option appears in the diff type dropdown alongside the existing choices and can be set as the default preference in the setup dialog or config.

Code File Viewer with Syntax Highlighting and Annotations

Clicking a code file link (.ts, .py, .go, etc.) in a plan or annotated document now opens a read-only dialog with full syntax highlighting. The server runs preloadFile from @pierre/diffs/ssr to return pre-rendered HTML, so there's zero client-side Shiki cost and the file renders instantly.

The viewer supports line-level annotations: click the gutter button on any line, select a line range, or drag across text to add a comment. Annotations appear in the sidebar panel alongside prose annotations and are included in exported feedback. Draft recovery covers code file annotations as well, so nothing is lost if the server restarts.

Under the hood, the dialog uses a new reusable PopoutDialog component extracted from the table popout, which also fixes the table popout's missing backdrop blur.

Hide Whitespace

A new toggle suppresses whitespace-only changes in diffs, matching GitHub's ?w=1 / git diff -w behavior. When enabled, re-indentation, alignment padding, and interior whitespace changes are removed from the diff, leaving only substantive code changes visible. The implementation normalizes all whitespace runs to a single space before diffing, so interior whitespace changes like alignment shifts and extra spaces between tokens are correctly suppressed.

The toggle is available in the per-file quick-settings popover and in the global settings dialog. Default: off.

Quick-Settings Popover

Each file header in the review editor now has a gear icon that opens a compact popover with all diff display options: style (split/unified), overflow mode, change indicators, inline diff granularity, line numbers, diff background colors, and hide whitespace. This provides quick per-file access to display options without opening the full settings dialog.

Additional Changes

  • Gutter hover button fix: The + button for adding line comments wasn't rendering because Pierre updates hover state imperatively (no React re-render). The button now always renders and checks hover state at click time. Button styling was also updated to match Pierre's theme spec. — #630
  • @pierre/diffs 1.1.20: Picks up split-view scroll fix, WorkerPool race condition fix, hydration fixes, CSS refactoring, and empty-file-as-deleted fix. — #630
  • File tree expand toggle: The separate expand-all and collapse-all buttons are replaced with a single toggle. Shows the collapse action when all folders are expanded, otherwise shows expand. Disabled when the tree has no folders. — #633

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(review): add "All files" diff type by @backnotprop in #629
  • fix(review): gutter hover button not rendering + update @pierre/diffs to 1.1.20 by @backnotprop in #630
  • feat(review): diff display options — hide whitespace + quick-settings popover by @backnotprop in #631
  • feat(review): single file tree expand/collapse toggle by @backnotprop in #633
  • feat(ui): code file viewer with syntax highlighting and annotations by @backnotprop in #634
  • fix(review): hide-whitespace matches GitHub's git diff -w by @backnotprop in #635

Full Changelog: v0.19.3...v0.19.4

v0.19.3

29 Apr 07:33
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.19.2 Stacked PR review, source line numbers in feedback, diff type dialog re-show, ghost dot removal, docs cleanup
v0.19.1 Hook-native annotation, custom base branch, OpenCode workflow modes, quieter plan diffs, anchor navigation
v0.19.0 Code Tour agent, GitHub-flavored Markdown, copy table as Markdown/CSV, flexible Pi planning mode, session-log ancestor-PID walk
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

What's New in v0.19.3

v0.19.3 makes feedback messages fully configurable and cleans up the stacked PR selector for teams working with long PR chains. Three PRs, one from an external contributor.

Configurable Feedback Messages

Every message Plannotator sends to your agent is now customizable through ~/.plannotator/config.json. Plan approvals, plan denials, review approvals, review feedback suffixes, and annotation feedback all flow through a shared prompt pipeline with {{variable}} template interpolation.

The config supports generic overrides that apply to all runtimes, plus per-runtime overrides for cases where Claude Code, OpenCode, and Pi need different phrasing. A four-level resolution order (runtime-specific, generic, runtime built-in default, global default) means you can be as granular or as broad as you want. Users who don't touch the config get identical behavior to previous versions.

This started with @oorestisime's PR adding configurable review approval prompts (#561), which was then expanded to cover all 17 hardcoded feedback strings across the hook, OpenCode, and Pi integrations (#627). The full pipeline includes 72 tests (55 unit, 17 integration) covering template resolution, config merging, backward compatibility, and end-to-end disk-to-output flow.

A new documentation page at Custom Feedback walks through the config format, available template variables, and a context-anchoring pattern contributed by @aviadshiber.

Hide Merged PRs in Stacked PR Selector

When reviewing a long chain of stacked PRs, merged PRs would show up alongside open ones in the stack tree and PR selector. For teams that iterate through a stack over several sessions, this made it harder to see which PRs still needed review.

A "Hide merged" toggle now appears in both the stack tree popover and the PR selector dropdown. When enabled, merged PRs are removed from the list and a summary count shows how many are hidden. When visible, merged PRs appear dimmed with a strikethrough title and a "merged" badge, and they're not clickable. The toggle state persists via cookie across sessions. Tree indentation was also tightened to 2px per level to prevent horizontal overflow on deep stacks (10+ nodes).


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(review): add configurable approval prompts by @oorestisime in #561
  • feat(review): hide/de-emphasize merged PRs in stacked PR selector by @backnotprop in #626
  • feat(feedback): configurable plan, annotation, and review feedback by @backnotprop in #627

Contributors

@oorestisime filed #558 requesting commit-on-approve for code review sessions, then contributed #561 adding configurable review approval prompts. That PR seeded the broader feedback customization pipeline shipped in this release.

Community members whose issues shaped this release:

  • @JohannesKlauss filed #624 requesting customizable feedback prompts for the build agent handoff
  • @leoreisdias filed #625 requesting that merged PRs be hidden from the stacked PR selector, with a detailed description of the 10+ PR workflow that motivated the change
  • @aviadshiber contributed a context-anchoring prompt pattern featured in the custom feedback documentation

Full Changelog: v0.19.2...v0.19.3

v0.19.2

28 Apr 06:52
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.19.1 Hook-native annotation, custom base branch, OpenCode workflow modes, quieter plan diffs, anchor navigation
v0.19.0 Code Tour agent, GitHub-flavored Markdown, copy table as Markdown/CSV, flexible Pi planning mode, session-log ancestor-PID walk
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

What's New in v0.19.2

v0.19.2 adds stacked PR review, source line numbers in exported feedback, and several UX fixes. Five PRs, one from a first-time contributor.

Code Review

Stacked PR Review

Reviewing a PR that belongs to a stack used to mean reviewing it in isolation. You could see the diff for that one branch, but not how it fit into the larger chain. Switching to a different PR in the stack meant closing the review and starting a new session.

Stacked PR review keeps you in a single session across every PR in the stack. A stack tree popover shows the full chain with clickable navigation. Each PR gets its own worktree checkout, so switching PRs recomputes the diff against the correct base without mixing changes between layers. Two scope modes let you toggle between viewing a single PR's changes (layer) and all accumulated changes from the default branch (full-stack).

Multi-PR posting lets you submit review feedback to multiple PRs at once. A confirmation dialog shows exactly where comments will go before posting to GitHub or GitLab, with parallel submission and partial-failure retry. Annotations from full-stack diffs can't be mapped to a single PR's line numbers, so they're surfaced as copyable markdown rather than silently dropped.

A new "Branch" option in the default diff type setting (and first-run dialog) gives users who work primarily with committed changes a one-click default.

Source Line Numbers in Exported Feedback

When Claude receives annotation feedback, it got the block content and the highlighted text but had no way to locate the annotation in the source file. For large documents with repeated headings or similar paragraphs, this ambiguity forced extra round-trips.

Exported annotations now include source line numbers. Single-line blocks show (line 42), multi-line blocks show (lines 10–14). Code blocks account for fence lines when computing ranges. Files with YAML frontmatter are offset-corrected so line numbers match the original file, not the parsed output.

For converted content (HTML files rendered through Turndown, URLs fetched via Jina Reader), the feedback includes a caveat that line numbers refer to the converted markdown rather than the original source. When viewing a linked HTML document within a plan, the conversion flag is derived per-document so mixed collections of markdown and HTML files each get the correct label.

UX

Diff Type Dialog Re-Presented

Many users who set up Plannotator before v0.17.8 never saw the "Committed" option (branch diff vs. the default branch) because the first-run dialog only showed at install time. Users were asking how to set committed changes as their default without realizing the option existed.

The dialog is now re-presented to existing users with clearer descriptions, a wider layout with a 60/40 split, and a hover-to-zoom preview of the toolbar dropdown. The dialog reminds users they can switch views anytime during a review. Existing preferences are preserved — this only re-shows the picker, it doesn't reset anyone's choice.

Options Menu Ghost Dot Removed

The pulsing notification dot on the Options menu was meant to flag new settings after an update. In practice, the dot appeared on every session and users couldn't figure out how to dismiss it. The entire new-settings-hint system has been removed. Settings changes are communicated through release notes instead.

Additional Changes

  • Docs: toolbar inventory updated. Documentation references to "Insert" and "Replace" annotation types have been scrubbed to match the shipped UI, which uses Delete, Comment, Quick Label, Looks Good, Global Comment, and Copy. — #618 by @vxio, closing #617
  • Docs: OpenCode plugin configuration. Clarified plugin setup instructions for OpenCode users. — commit 33f409a

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: stacked PR review — PR switching, scope toggling, multi-PR posting by @backnotprop in #620
  • feat(plan,annotate): include source line numbers in exported feedback by @backnotprop in #623
  • docs: scrub Insert/Replace from docs to match shipped UI by @vxio in #618
  • fix: remove ghost dot on Options menu (new-settings-hint system) by @backnotprop in commit 7ab2d8f
  • fix: re-show diff type setup dialog with clearer options and toolbar hint by @backnotprop in commits aaad89e, 03d4e8b

New Contributors

  • @vxio made their first contribution in #618

Community

@vxio noticed the docs still referenced Insert and Replace annotation types that were removed from the UI, filed #617, and contributed the fix in #618. First contribution to the project.

Full Changelog: v0.19.1...v0.19.2

v0.19.1

24 Apr 05:52
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
v0.19.0 Code Tour agent, GitHub-flavored Markdown, copy table as Markdown/CSV, flexible Pi planning mode, session-log ancestor-PID walk
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

What's New in v0.19.1

v0.19.1 adds gated approval and hook-native output to plannotator annotate, so you can integrate annotation review into spec-driven workflows and agent hook pipelines. Code review gains a base-branch picker, and OpenCode users get explicit control over which agents can submit plans. Seven PRs, one from a first-time contributor.

Annotate

Hook-Native Annotation for Spec-Driven Workflows

Spec-driven development frameworks like spec-kit, kiro, and openspec generate multiple markdown artifacts that go through iterative review. Previously, integrating Plannotator's annotation UI into a hook pipeline required a wrapper script to parse stdout and translate it into the host's hook protocol. That friction made adoption impractical for most setups.

plannotator annotate now ships a --hook flag that emits hook-native JSON directly. Pass plannotator annotate "$FILE" --hook as a PostToolUse or Stop hook command, and the output works with Claude Code and Codex hook protocols without any glue code. Approve emits {"decision":"allow"}, annotate emits {"decision":"block","reason":"..."} with the feedback inlined, and dismiss emits {"decision":"allow"} with no side effects. The flag implies --gate (three-button UX: Approve / Annotate / Close) and supersedes --json when both are passed.

The underlying --gate flag landed first as a standalone feature, adding the three-way review UX and structured JSON output. --hook builds on it by mapping those three outcomes to the hook protocol's allow and block decisions, removing the need for intermediate translation.

Code Review

Custom Base Branch

Code review diffs used to compare against the auto-detected default branch. For teams that branch from develop, release/*, or another feature branch, the diff showed changes that had nothing to do with the current PR. Users had to live with noisy diffs or skip review entirely.

A searchable base-branch picker now appears in the review toolbar for Branch diff and PR Diff modes. Select any local or remote branch as the comparison target, and the diff recomputes server-side against the chosen base. The picker is hidden in modes where a base doesn't apply (staged, unstaged). Branch lists and merge-base resolution live in packages/shared/review-core.ts, so both the Bun and Pi runtimes share the same logic.

Async Remote Default Branch Detection

When origin/HEAD isn't set (common in worktrees, manually added remotes, and long-lived repos), the review server fell back to local main instead of querying the remote. This silently produced wrong diffs when the upstream default branch was develop or trunk.

The server now runs git ls-remote --symref origin HEAD as a network-based fallback with a 3-second timeout. It detects any default branch name without hardcoded guesses. On the Pi runtime, this fix also replaced the synchronous spawnSync git adapter with an async spawn implementation, so the 3-second timeout no longer blocks the entire Node.js event loop during startup.

  • #609 and commit 5a1dd03

OpenCode

Workflow Modes for Planning Agents

OpenCode's submit_plan tool was available to every agent in the session, including build agents, test runners, and subagents that had no business writing plans. This caused confusion when non-planning agents surfaced the tool in their capabilities and occasionally called it by accident.

The plugin now supports three explicit workflow modes. plan-agent (the new default) keeps submit_plan visible only to OpenCode's built-in plan agent and any additional agents listed in the planningAgents configuration. manual hides submit_plan entirely and relies on slash commands (/plannotator-review, /plannotator-annotate, etc.) for all interactions. all-agents restores the previous behavior for users who intentionally route planning through non-default agents.

Plan Diff

Quieter Diffs on Prose Edits

Plan diffs use word-level diffing, which produces readable results for most code-like edits but struggles with three specific patterns: markdown emphasis delimiters (**bold****new bold**), adjacent word-level swaps, and hyphenated compound changes. The diff engine highlighted individual characters in ways that were technically correct but hard to parse visually.

Three post-processing passes now clean up these patterns. Bold-phrase swaps collapse into single changed regions instead of fragmenting across delimiter boundaries. Adjacent single-word changes merge when they share a boundary. Hyphenated compounds that change a single segment highlight the full compound rather than the hyphen and segment separately.

In-Page Anchor Navigation

Clicking a #-prefixed link in the plan viewer scrolled the entire browser window instead of the plan content viewport. Since plans render inside a sticky scroll container, the native jump missed the target entirely.

Anchor clicks are now intercepted and smooth-scrolled within the correct viewport. Each heading exposes both a canonical slug (collapsed separators) and a legacy slug via data-anchor-aliases, so previously shared URLs keep resolving. Initial-hash and hashchange events are handled so direct links land on the right heading after load.

Additional Changes

  • Pi async git runtime. The Pi extension's git adapter used spawnSync, which blocked the Node.js event loop during every git operation. Replaced with an async spawn implementation that mirrors the Bun server's pattern, including timeout support via proc.kill(). This was particularly important for detectRemoteDefaultBranch, which fires at review server startup with a multi-second timeout. (commit 5a1dd03)

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/...
Read more

v0.19.0

22 Apr 02:38
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

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 suggest...

Read more

v0.18.0

20 Apr 00:44
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
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
v0.16.7 Gemini CLI plan review, install script skills directory fix

What's New in v0.18.0

v0.18.0 adds focus & wide modes for annotate, first-class OpenCode detection, word-level inline plan diffs, content negotiation for URLs that publish Markdown (via Cloudflare), and inline color swatches in the plan viewer. 13 PRs, 7 from external contributors — 6 of them first-timers.

Word-Level Inline Plan Diff

The old plan diff stacked the full old block above the full new block whenever a paragraph was modified. A single word change showed the same paragraph twice with no visual cue to where the edit actually happened. Readers ended up comparing two nearly identical blocks line by line to find the delta.

The new default Rendered mode performs a second-pass word diff on modified blocks and highlights only the changed tokens inline. A one-word reword now reads as a single paragraph with <ins> and <del> markers on exactly the changed words. Inline code spans, markdown links, and fenced code blocks are preserved as atomic units through a sentinel substitution pass, so diff markers can't split them.

A third mode switcher tab, "Classic," keeps the legacy block-level stacked rendering for users who prefer it. Raw git-style output is unchanged. Modified blocks are click-to-annotate directly, with both the old and new content captured in the exported feedback so comments on struck-through words keep their context.

Amber borders on modified blocks complete the green/red/yellow convention used by GitHub and VS Code.

Wide and Focus Modes

Wide markdown tables were unreadable because both side panels (TOC on the left, annotations on the right) stayed fixed while the reader width was capped. Tables wrapped awkwardly or required horizontal scrolling inside a narrow column.

Two new toggles sit above the document and next to the lightning-bolt action:

  • Wide hides both panels and removes the reader width cap. Wide tables and code fences get the full document area.
  • Focus hides both panels but keeps the normal reader width. Distraction-free reading without stretching the content.

Enabling either mode collapses the left sidebar, hides the annotations panel and resize handle, and toggles the width cap accordingly. Exiting restores the exact previous layout, including which sidebar tab was open. Opening any sidebar or annotations panel automatically exits.

Available in plan review, annotate, and linked-doc overlays. Archive mode and plan-diff view keep the standard layout.

First-Class OpenCode Detection

The origin detection chain in the hook server didn't include OpenCode. Every OpenCode invocation fell through to the claude-code default, which loaded the wrong UI variant: missing agent-switch toggle, wrong agent badge. The opencode origin key was already defined in AGENT_CONFIG with its badge styling in place, but the detection side was never wired up.

OpenCode is now detected via OPENCODE=1, the canonical runtime flag set unconditionally by the OpenCode binary. The full priority order is:

PLANNOTATOR_ORIGIN > Codex > Copilot CLI > OpenCode > Claude Code (default)

The PLANNOTATOR_ORIGIN environment variable was documented in the source but never read. It now functions as an explicit override at the top of the chain, validated against AGENT_CONFIG so invalid values fall through to env-based detection instead of breaking.

Content Negotiation for Markdown-Serving URLs

When you run plannotator annotate https://..., the tool goes through Jina Reader (or Turndown as a fallback) to convert HTML to markdown. But a growing number of sites — including Cloudflare's developer docs — now publish Markdown directly when you ask for it. Routing those through an HTML-to-markdown converter is wasteful and loses fidelity.

URL annotation now tries Accept: text/markdown, text/html;q=0.9 first, with a 5-second timeout. If the server returns content-type: text/markdown, the response is used directly — one fetch, no conversion. If the server returns HTML or the request fails, it falls through silently to the existing Jina/Turndown pipeline. Local URLs skip negotiation entirely.

A new content-negotiation source type is recorded on the result so the UI can indicate which path produced the content.

Hex Color Swatches in the Plan Viewer

Frontend plans reference hex color values constantly — design tokens, Tailwind overrides, CSS variable assignments, component palette decisions. Reviewers had to mentally decode every #ff6600 or open a color picker to follow the author's intent.

The plan viewer now renders a small filled swatch inline, immediately to the left of the hex code. The swatch is a 14×14 rounded square matching the referenced color. Supports 3-, 4-, 6-, and 8-digit hex with a negative lookahead that excludes URL anchors, CSS id selectors, and any identifier that continues with word characters.

The color value is constrained by the regex before reaching React, and rendered via the React style object — not cssText — so there's no CSS injection path. 19 tests cover valid patterns, false-positive guards, and injection attempts.

Self-Hosted Paste Service Support

Short-link sharing for larger plans routes through a paste service at plannotator-paste.plannotator.workers.dev. Self-hosted deployments had no way to point at their own paste service — the URL was hardcoded in the OpenCode plugin.

The PLANNOTATOR_PASTE_URL environment variable now configures a custom paste endpoint. The OpenCode plugin reads it via a new getPasteApiUrl dependency that flows through command handlers (annotate, annotate-last, archive) and the review server. The Landing component accepts a shareBaseUrl prop with a fallback to the default. CORS documentation in the paste service now includes explicit guidance for self-hosters.

Backward compatible: unset PLANNOTATOR_PASTE_URL continues to use the hosted default.

OpenCode Review: Reuse the Existing Local Server

On subsequent review commands, the OpenCode AI review path tried to start a second opencode serve and collided with the existing local server on port 4096. The first opencode serve wasn't being cleaned up, so port conflicts were guaranteed on the second inv...

Read more

v0.17.10

13 Apr 15:06
Immutable release. Only release title and notes can be modified.

Choose a tag to compare

Follow @plannotator on X for updates


Missed recent releases?
Release Highlights
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
v0.16.7 Gemini CLI plan review, install script skills directory fix
v0.16.6 Perforce support, Pi shared event API, suggested code prefill, file tree expand fix

What's New in v0.17.10

v0.17.10 adds HTML and URL annotation, binds local servers to loopback for security, fixes two UI bugs in the review and plan editors, and hardens the release pipeline with supply chain age gating and binary smoke tests. 7 PRs, 1 from a first-time external contributor.

Annotate HTML Files and URLs

plannotator annotate now accepts HTML files and URLs in addition to markdown. Running plannotator annotate page.html converts the file to markdown via Turndown and opens the standard annotation UI. Running plannotator annotate https://example.com/docs fetches the page content through Jina Reader (which handles JavaScript-rendered pages), falls back to plain fetch with Turndown conversion, and opens it for annotation.

Local and private URLs skip Jina automatically and use direct fetch. A --no-jina flag, PLANNOTATOR_JINA environment variable, and config.json setting are available to disable Jina Reader entirely. For authenticated use with higher rate limits, set JINA_API_KEY.

Folder mode now shows .html and .htm files alongside markdown, with on-demand conversion when you click one. A subtle source badge in the UI shows the URL hostname or original filename so you always know where the content came from.

Dangerous link protocols (javascript:, data:, vbscript:) are blocked in the markdown renderer. Local HTML files are capped at 10MB and restricted to the project root.

Pi extension parity is included: file browser, HTML conversion, URL/Jina support, and the source badge all work identically in the Node.js server.

Local Servers Bind to Loopback by Default

Local plan, review, and annotate servers now bind to 127.0.0.1 instead of 0.0.0.0. Previously, running plannotator review on a laptop exposed the review API (including the agent job launcher) to every device on the local network. Remote sessions (SSH, Docker, devcontainers) continue to bind to 0.0.0.0 so port forwarding still works.

Both the Bun and Pi server implementations were updated with regression tests verifying hostname selection in local vs. remote sessions.

Safari Scroll Position Fix in Code Review

Safari users experienced the diff view snapping back to the top after momentum scrolling. The root cause was a WebKit compositor bug: Safari loses track of scroll position when a web component shadow DOM (<diffs-container> from @pierre/diffs) is a child of a scroll container. The reset bypasses all JavaScript APIs, so intercepting scrollTo and the scrollTop setter caught nothing.

The fix adds a WebKit-only scroll event listener that detects bogus resets (scrollTop jumping from over 200px to 0 in a single event) and synchronously restores the last known position. It is never attached on Chrome, Firefox, or Edge.

Triple-Click Paragraph Selection Restored

Triple-clicking a paragraph to select the full line stopped producing the annotation toolbar. The bug was a timing interaction between the dismiss-on-outside-click handler (added in #182) and browser click counting. The third pointerdown fired the dismiss hook, which removed the <mark> element and normalized text nodes. This DOM mutation changed the element under the cursor, resetting the browser's click count so the third click registered as detail=1 instead of detail=3.

The fix guards the dismiss handler: multi-click pointerdowns (event.detail >= 2) are skipped because they are part of an active selection gesture.

Additional Changes

  • 7-day minimum release age for dependencies — Renovate and bunfig.toml now enforce a 7-day hold on new dependency versions. This prevents repeat incidents like the Bun 1.3.12 codesign regression (#541), where a 2-day-old release was picked up by CI before the defect surfaced. Automerge is also disabled. #550 by @backnotprop
  • Smoke tests for compiled binaries — The release pipeline now tests the linux-x64 binary after compilation: --help for basic loading, review and annotate for full server startup with HTTP binding. If any test fails, artifacts are never uploaded. #555 by @backnotprop
  • Annotate documentation and blog post — Docs for all four annotate input types (markdown, HTML, URLs, folders), environment variable references for PLANNOTATOR_JINA and JINA_API_KEY, and a blog post with demo video. #553 by @backnotprop

Install / Update

macOS / Linux:

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

Windows PowerShell:

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

Pin a specific version:

curl -fsSL https://plannotator.ai/install.sh | bash -s -- --version v0.17.10

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

Copilot CLI:

/plugin marketplace add backnotprop/plannotator
/plugin install plannotator-copilot@plannotator

Gemini CLI: The install script auto-detects ~/.gemini and configures hooks, policy, and slash commands.

OpenCode: Clear cache and restart:

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

Then in opencode.json:

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

Pi: Install or update the extension:

pi install npm:@plannotator/pi-extension

VS Code Extension: Install from the VS Code Marketplace.


What's Changed

  • feat(annotate): support HTML files and URL annotation by @backnotprop in #545
  • fix(ui): restore triple-click paragraph selection by @backnotprop in #546
  • fix(review): work around Safari scroll-reset bug with shadow DOM diffs by @backnotprop in #547
  • chore: enforce 7-day minimum release age for supply chain hardening by @backnotprop in #550
  • docs(annotate): URL/HTML annotation docs, blog post, and promo video by @backnotprop in #553
  • Bind local Plannotator servers to loopba...
Read more