Chat interfaces assume you are present when the agent runs. That assumption breaks when you have three coding agents refactoring a monorepo overnight, a personal assistant drafting emails, and a research agent pulling competitive analysis. You need a review surface that batches decisions, surfaces artifacts, and lets you annotate without blocking execution.
Plannotator (10,977 stars, trending #1 on GitHub TypeScript) is a local, browser-based inbox for multi-agent work. It treats agent outputs like email: each task lands in a unified surface where you review diffs, annotate plans, approve prototypes, and send feedback back to the agent. The contract is simple: agents write artifacts to a local directory, Plannotator renders them in a scannable UI, and your annotations flow back as structured input for the next run.
Why the Inbox Model Fits Asynchronous Agent Work
Chat UIs force synchronous interaction. You ask, the agent responds, you reply. That loop works for single-turn tasks but collapses when agents run in the background or when you manage multiple agents with overlapping outputs.
An inbox model decouples execution from review:
- Agents write artifacts to disk. Plans, diffs, HTML prototypes, markdown specs. Each artifact is a file with metadata (agent ID, timestamp, task context).
- The inbox surfaces unreviewed items. You see a list of pending decisions, not a chronological chat log.
- Annotations are first-class. You highlight a section of a plan, add a comment, mark a diff as approved or rejected. These annotations persist as structured data.
- Feedback loops are explicit. When you click “Send Feedback,” Plannotator packages your annotations and writes them to a location the agent reads on the next run.
This pattern mirrors how engineering teams handle code review. You do not sit next to the developer while they write code. You review the PR when it is ready, leave comments, and they iterate.
Architecture: File-Based State and Browser Rendering
Plannotator runs entirely in the browser. No server, no database. State lives in a local directory that both the agent and the UI can access.
Directory Structure
~/.plannotator/
├── inbox/
│ ├── task-001-refactor-auth/
│ │ ├── plan.md
│ │ ├── diff.patch
│ │ ├── metadata.json
│ │ └── annotations.json
│ ├── task-002-landing-page/
│ │ ├── prototype.html
│ │ ├── metadata.json
│ │ └── annotations.json
├── archive/
│ └── task-000-initial-setup/
└── config.json
Each task is a directory. The agent writes artifacts (plan.md, diff.patch, prototype.html) and a metadata.json file that includes:
- Agent ID (Claude Code, Copilot CLI, custom harness)
- Task description
- Timestamp
- Parent task ID (for multi-step workflows)
Plannotator watches this directory. When a new task appears, it renders the artifacts in the inbox. When you annotate, it writes annotations.json to the same directory.
Annotation Contract
Annotations are JSON objects with a schema the agent can parse:
{
"annotations": [
{
"artifact": "plan.md",
"line_start": 12,
"line_end": 15,
"comment": "Use bcrypt instead of SHA-256 for password hashing",
"status": "change_requested"
},
{
"artifact": "diff.patch",
"file": "src/auth/login.ts",
"line_start": 42,
"line_end": 42,
"comment": "Approved",
"status": "approved"
}
],
"overall_status": "needs_revision",
"feedback_sent_at": "2026-11-14T20:15:00Z"
}
The agent reads this file, applies changes, and writes a new task directory with updated artifacts. The cycle repeats.
Multi-Agent Coordination
Plannotator supports heterogeneous agents. You might have:
- Claude Code generating a FastAPI backend
- Copilot CLI writing frontend components
- A custom research agent pulling competitor pricing data
Each agent writes to the same inbox directory but uses a different agent_id in metadata.json. The inbox groups tasks by agent, so you can review all Claude Code outputs in one session and all Copilot CLI outputs in another.
Cross-Agent Dependencies
If Task B depends on Task A, the agent writes a parent_task_id field in metadata.json. Plannotator renders a dependency graph in the UI. You can see which tasks are blocked and which are ready for review.
This is not orchestration. Plannotator does not schedule agents or enforce execution order. It surfaces dependencies so you can decide whether to approve Task A before Task B runs again.
Code Review Surface
Plannotator renders diffs with syntax highlighting and inline comments. You can:
- Approve individual files
- Request changes on specific lines
- Mark entire diffs as “needs revision” or “approved”
The diff viewer is a React component that parses .patch files and maps line numbers to the original source. When you add a comment, it stores the file path, line range, and comment text in annotations.json.
Integration with Git
Plannotator does not replace Git. It sits between the agent and your version control workflow. A typical flow:
- Agent writes a diff.patch to the inbox
- You review in Plannotator, add comments
- Agent applies the patch to a feature branch
- You review the PR in GitHub/GitLab as usual
The inbox is for high-level approval (“yes, refactor the auth module”) before the agent commits code. The PR is for line-by-line review before merging.
Artifact Types and Rendering
Plannotator handles multiple artifact types:
| Artifact Type | Rendering | Annotation Support |
|---|---|---|
| Markdown plans | Rendered HTML with section anchors | Inline comments on paragraphs |
| Diffs (.patch) | Syntax-highlighted side-by-side view | Line-level comments |
| HTML prototypes | Sandboxed iframe with interaction | Visual annotations (click to comment) |
| JSON specs | Collapsible tree view | Key-level comments |
| Plain text | Monospace with line numbers | Line-level comments |
HTML artifacts are sandboxed in an iframe with a restrictive Content Security Policy. You can interact with the prototype (click buttons, fill forms) but cannot execute arbitrary JavaScript. This prevents malicious agents from injecting code that runs in your browser.
Observability and Failure Modes
What You Can See
- Task history: All tasks in the inbox and archive
- Agent activity: Which agent wrote which artifact, when
- Annotation history: Your comments and status changes over time
- Dependency graph: Which tasks block others
What You Cannot See
- Agent internal state: Plannotator does not inspect the agent’s memory or reasoning process
- Execution logs: If the agent crashes, you see the last artifact it wrote, not the error trace
- Real-time progress: The inbox updates when the agent writes a new task directory, not during execution
Failure Modes
Agent writes malformed metadata.json. Plannotator skips the task and logs an error in the browser console. You can manually fix the JSON and refresh.
Agent overwrites an existing task directory. Plannotator treats this as a new version. The old artifacts are lost unless you have a backup.
Annotations.json is corrupted. The agent cannot parse your feedback. You must manually edit the file or delete it and re-annotate.
Multiple agents write to the same task directory. Last write wins. Plannotator does not lock directories. Use unique task IDs per agent.
Deployment Shape
Plannotator is a static site. You can:
- Run it locally with
npx serveor any static file server - Deploy to Vercel/Netlify and point it at a synced directory (Dropbox, Google Drive)
- Embed it in an Electron app for a desktop experience
The agent must have write access to the inbox directory. If you deploy Plannotator to a remote server, you need a sync mechanism (rsync, cloud storage API) to move artifacts from the agent’s local environment to the server.
Security Boundaries
No network access. Plannotator does not send data to external servers. All state is local.
Sandboxed artifacts. HTML prototypes run in an iframe with sandbox="allow-scripts allow-same-origin" and a CSP that blocks external resources.
No authentication. Plannotator assumes you control the machine. If you deploy it remotely, add HTTP basic auth or a reverse proxy with authentication.
When to Use This Pattern
Use Plannotator when:
- You run multiple agents asynchronously (overnight builds, background research)
- You need to review and annotate before the agent proceeds
- You want a file-based contract between human and agent (no API, no database)
- You prefer local-first tools with no cloud dependency
Avoid Plannotator when:
- You need real-time collaboration (multiple humans reviewing the same task)
- You want the agent to execute based on your feedback without human approval
- You need fine-grained access control (who can approve which tasks)
- You require audit logs for compliance (Plannotator does not track who made which annotation)
Technical Verdict
Plannotator solves a real coordination problem: how do you stay in the loop when agents work in the background? The inbox model is a good fit for asynchronous, multi-agent workflows where human approval is a gate, not a bottleneck.
The file-based contract is simple and inspectable. You can debug by looking at the directory structure. You can version control the entire inbox with Git. You can write custom agents that follow the same schema without touching Plannotator’s code.
The tradeoffs are clear. No real-time collaboration. No built-in orchestration. No server-side logic. If you need those, you are building a different system.
For solo developers or small teams running local agents, this is a clean primitive. It does one thing (surface agent outputs for review) and does it without adding a database, API, or deployment complexity.