Plannotator's Inbox Pattern: Why Background Agent Execution Needs an Email-Like UI Plannotator, a local browser-based inbox for multi-agent work with roughly 11,000 GitHub stars, treats background agent outputs like email: agents write artifacts such as plans, diffs and prototypes to a local directory, and the UI renders them for batched review, with annotations written back as structured JSON the agent can parse. The tool supports heterogeneous agents via an agent_id field and surfaces task dependencies through parent_task_id, but explicitly does not orchestrate or schedule agents. It sits between agent execution and Git, handling high-level approval before agents commit code. 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. 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: 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. 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. ~/.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: 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. 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. Plannotator supports heterogeneous agents. You might have: 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. 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. Plannotator renders diffs with syntax highlighting and inline comments. You can: 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. Plannotator does not replace Git. It sits between the agent and your version control workflow. A typical flow: 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. 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. 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. Plannotator is a static site. You can: npx serve or any static file server 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. 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. Use Plannotator when: Avoid Plannotator when: 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.