github backnotprop/plannotator v0.19.1

16 hours ago

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/@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(opencode): workflow modes for planning agent scoping by @backnotprop in #571
  • fix(ui): in-page anchor navigation for headings by @dgrissen2 in #605
  • feat(review): custom base branch for code review by @backnotprop in #602
  • feat(annotate): approve/annotate/dismiss flow with --gate and --json by @backnotprop in #606
  • fix(review): detect remote default branch via ls-remote fallback by @backnotprop in #609
  • feat(annotate): replace --silent-approve with --hook for native hook protocol by @backnotprop in #610
  • feat(ui): quieter plan diffs on prose edits by @pbowyer in #603

New Contributors

Contributors

@pbowyer authored the plan diff post-processing passes (#603), fixing three categories of noisy word-level diffs that made prose edits hard to read. First contribution to the project.

@dgrissen2 fixed anchor navigation in the plan viewer (#605), adding smooth-scroll interception, legacy slug aliases, and initial-hash handling.

Community members who reported issues that shaped this release:

  • @punk-dev-robot filed #570 requesting an approve/reject flow for spec-driven frameworks, which led to the --gate and --hook flags
  • @timrichardson filed #422 requesting configurable planning agent names in OpenCode, which drove the workflow modes feature
  • @LUUUAN filed #599 requesting custom base branch support for code review
  • @leoreisdias participated in the #570 discussion with implementation feedback

Full Changelog: v0.19.0...v0.19.1

Don't miss a new plannotator release

NewReleases is sending notifications on new releases.