Context
Spec-driven development frameworks (spec-kit, kiro, openspec, etc.) are replacing traditional plan mode in AI coding workflows. Instead of a single plan file, these frameworks generate multiple markdown artifacts (spec.md, plan.md, tasks.md, research.md, data-model.md) that go through iterative review cycles.
Plannotator's annotation UI is a perfect fit for reviewing these artifacts — inline, targeted feedback on markdown is exactly what's needed. I've built integrations for both Claude Code (PostToolUse hook) and OpenCode (event plugin) that trigger plannotator annotate whenever a spec artifact is written.
The value proposition is significant: every spec-driven framework generates multiple markdown files per feature, each needing human review. Plannotator could be the universal review layer across all of them.
Problem
plannotator annotate currently has no approve/accept exit path. The UI shows Close and Annotate buttons, but no Approve.
This creates three issues:
-
No "looks good" signal: Closing without feedback returns "Annotation session closed without feedback" on stdout. There's no way to distinguish "I reviewed this and it's fine" from "I dismissed this without looking."
-
Claude Code hook breaks: The Claude Code hook (source) runs as a blocking PostToolUse hook. Any stdout from plannotator triggers a block — including the "closed without feedback" message. This means every spec file write gets blocked with no way to approve.
-
OpenCode plugin works around it, but incompletely: The OpenCode plugin (source) runs async and sends annotations back as a session prompt. Empty stdout = no action, which is better. But "closed without feedback" still produces stdout, and there's still no explicit approve signal.
Proposed Solution
Add an Approve (or Accept) button to the annotation UI for plannotator annotate:
- Approve: exits with code 0 and empty stdout (or a structured
{"decision": "approved"} if downstream hooks want to distinguish approved from dismissed)
- Annotate: existing behavior — exits with annotations on stdout
- Close/Dismiss: exits with code 0 and empty stdout (current behavior for no annotations, but currently outputs the "closed without feedback" message)
Optionally:
- A
--gate or --review-mode flag that explicitly enables the 3-button (Approve/Annotate/Dismiss) UX for hook integrations
- Structured JSON output mode (
--json) so hooks can parse the decision cleanly
Why This Matters Beyond Plan Mode
Plannotator currently shines for plan review. But spec-driven development is where the volume is:
- A single feature generates 4-6 markdown files (spec, plan, tasks, research, data-model, quickstart)
- Each goes through clarify → review → approve cycles
- Multiple frameworks exist (spec-kit, kiro, openspec) with the same pattern
- All of them need a human-in-the-loop review step for markdown artifacts
A working approve/reject flow for plannotator annotate would make plannotator the universal review tool for all of these frameworks.
Related Issues
Environment
- plannotator binary:
~/.local/bin/plannotator (installed ~April 14, 2026)
- Claude Code: PostToolUse Python hook
- OpenCode: Bun event plugin
- OS: macOS Darwin 25.4.0
Context
Spec-driven development frameworks (spec-kit, kiro, openspec, etc.) are replacing traditional plan mode in AI coding workflows. Instead of a single plan file, these frameworks generate multiple markdown artifacts (spec.md, plan.md, tasks.md, research.md, data-model.md) that go through iterative review cycles.
Plannotator's annotation UI is a perfect fit for reviewing these artifacts — inline, targeted feedback on markdown is exactly what's needed. I've built integrations for both Claude Code (PostToolUse hook) and OpenCode (event plugin) that trigger
plannotator annotatewhenever a spec artifact is written.The value proposition is significant: every spec-driven framework generates multiple markdown files per feature, each needing human review. Plannotator could be the universal review layer across all of them.
Problem
plannotator annotatecurrently has no approve/accept exit path. The UI shows Close and Annotate buttons, but no Approve.This creates three issues:
No "looks good" signal: Closing without feedback returns
"Annotation session closed without feedback"on stdout. There's no way to distinguish "I reviewed this and it's fine" from "I dismissed this without looking."Claude Code hook breaks: The Claude Code hook (source) runs as a blocking PostToolUse hook. Any stdout from plannotator triggers a block — including the "closed without feedback" message. This means every spec file write gets blocked with no way to approve.
OpenCode plugin works around it, but incompletely: The OpenCode plugin (source) runs async and sends annotations back as a session prompt. Empty stdout = no action, which is better. But "closed without feedback" still produces stdout, and there's still no explicit approve signal.
Proposed Solution
Add an Approve (or Accept) button to the annotation UI for
plannotator annotate:{"decision": "approved"}if downstream hooks want to distinguish approved from dismissed)Optionally:
--gateor--review-modeflag that explicitly enables the 3-button (Approve/Annotate/Dismiss) UX for hook integrations--json) so hooks can parse the decision cleanlyWhy This Matters Beyond Plan Mode
Plannotator currently shines for plan review. But spec-driven development is where the volume is:
A working approve/reject flow for
plannotator annotatewould make plannotator the universal review tool for all of these frameworks.Related Issues
Environment
~/.local/bin/plannotator(installed ~April 14, 2026)