v2.0 proposal: BooCoder — write tools, pending changes, ACP dispatch, MCP server
Comprehensive roadmap for the v2.0 major version bump. Covers: - Schema: pending_changes, tasks, available_agents tables + human_inbox view - Path A: native write tools (edit_file, create_file, delete_file) queuing through pending_changes before /apply flushes to disk - Path B: external agent dispatch via ACP (opencode, goose) or PTY fallback (claude, pi) with per-task git worktrees and automatic diff-on-completion - BooCoder MCP server: 6 tools exposing task primitives over stdio - Code lifts: agent-hub (Apache-2.0, task DAG), plandex (MIT, diff UX), ACP SDK (Apache-2.0, subprocess protocol), Paseo (AGPL, design-only) - Sub-versions: v2.0.0 (Path A), v2.0.1 (Path B), v2.0.2 (MCP server), v2.0.3 (CLI + polish) - Estimate: ~2200 LoC total All v1.x dependencies shipped (v1.13 parts, v1.14 outer loop, v1.15 MCP client, v1.16 codesight). v2.0 is unblocked. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
130
openspec/changes/v2.0-boocoder/tasks.md
Normal file
130
openspec/changes/v2.0-boocoder/tasks.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# v2.0 — BooCoder task breakdown
|
||||
|
||||
## Phase 0 — Prep (before any code)
|
||||
|
||||
- [ ] Clone lift sources: `agent-hub`, `plandex`, `opencode` to `/opt/forks/`
|
||||
- [ ] Read agent-hub's schema + dispatcher pattern (Apache-2.0)
|
||||
- [ ] Read plandex's pending-changes + diff/apply/rewind flow (MIT)
|
||||
- [ ] Read opencode's `permission/evaluate.ts` for write-gate patterns (MIT)
|
||||
- [ ] Install ACP SDK: `pnpm add @zed-industries/agent-client-protocol`
|
||||
- [ ] Verify `opencode acp` and `goose acp` are available on the host
|
||||
- [ ] Write `openspec/changes/v2.0-boocoder/design.md` with finalized decisions
|
||||
|
||||
## v2.0.0 — Schema + Path A (native write tools + pending-changes + diff UI)
|
||||
|
||||
### Infra
|
||||
|
||||
- [ ] Create `apps/coder/` directory skeleton (Fastify server, mirroring `apps/server/` structure)
|
||||
- [ ] Create `apps/coder/Dockerfile` (Node 20 bookworm-slim, `/opt:/opt:rw` mount)
|
||||
- [ ] Add `boocoder` service to `docker-compose.yml` (port 9502, boocode_net)
|
||||
- [ ] Add Caddy route: `coder.indifferentketchup.com` → boocoder:9502
|
||||
- [ ] DB rename: `boocode_db` → `boochat_db` (one-time ALTER DATABASE + docker-compose volume rename)
|
||||
- [ ] Schema migration: CREATE TABLE `pending_changes`, `tasks`, `available_agents`; CREATE VIEW `human_inbox`
|
||||
- [ ] Container guidance: `BOOCODER.md` (bind-mounted at `/app/BOOCODER.md`)
|
||||
|
||||
### Write tools
|
||||
|
||||
- [ ] `apps/coder/src/services/write_guard.ts` — `resolveWritePath(projectRoot, filePath)` (resolve + prefix-check, no realpath since file may not exist)
|
||||
- [ ] `apps/coder/src/services/pending_changes.ts` — queue, apply, reject, revert operations
|
||||
- [ ] Tool: `edit_file` — takes `{file_path, old_string, new_string}`, computes unified diff, queues in `pending_changes`
|
||||
- [ ] Tool: `create_file` — takes `{file_path, content}`, queues as `operation='create'`
|
||||
- [ ] Tool: `delete_file` — takes `{file_path}`, queues as `operation='delete'`
|
||||
- [ ] Tool: `apply_pending` — flushes pending changes to disk (re-validates write_guard before each write)
|
||||
- [ ] Tool: `rewind` — reverts applied changes by inverse-diff
|
||||
|
||||
### Inference loop
|
||||
|
||||
- [ ] Port the v1.14 outer loop from `apps/server/` into `apps/coder/` (or share via workspace package)
|
||||
- [ ] Register write tools in the coder's tool registry (alongside all read tools from BooChat)
|
||||
- [ ] Permission gate: write tools require `pending_changes` queue (can't bypass to direct disk write)
|
||||
|
||||
### Frontend (diff pane)
|
||||
|
||||
- [ ] Create `apps/coder/web/` SPA (React + Vite, same stack as BooChat's `apps/web/`)
|
||||
- [ ] Diff pane component: shows pending changes with syntax-highlighted diffs
|
||||
- [ ] Approve / Reject per change, Approve All / Reject All buttons
|
||||
- [ ] Workspace splitter integration (chat pane + diff pane side by side)
|
||||
|
||||
### Verification
|
||||
|
||||
- [ ] `pnpm -C apps/coder build` clean
|
||||
- [ ] Write path-guard fuzz tests (traversal patterns, symlinks, non-existent paths, `.env` deny)
|
||||
- [ ] `docker compose up --build -d` — boocoder container starts, healthcheck passes
|
||||
- [ ] Smoke: send a chat requesting a file edit → see it queued in diff pane → approve → file written
|
||||
|
||||
## v2.0.1 — Path B (ACP dispatch + PTY fallback + worktrees)
|
||||
|
||||
### ACP client
|
||||
|
||||
- [ ] `apps/coder/src/services/acp-client.ts` — spawn `opencode acp` / `goose acp` via `@zed-industries/agent-client-protocol` StdioTransport
|
||||
- [ ] Event mapping: ACP `file_operation` → `tool_call` part, `terminal_output` → BooTerm route, `permission_request` → pause
|
||||
- [ ] Session lifecycle: start, mid-session model switch, end
|
||||
- [ ] MCP auto-forward: pass BooCoder's `context_servers` config to the ACP session
|
||||
|
||||
### PTY fallback
|
||||
|
||||
- [ ] `apps/coder/src/services/pty-dispatch.ts` — spawn `claude` / `pi` / `smallcode` via `node-pty`
|
||||
- [ ] Capture stdout/stderr/exit-code into parts (less structured than ACP)
|
||||
- [ ] Worktree setup: `git worktree add /tmp/booworktrees/<task-id> -b task-<task-id> HEAD`
|
||||
- [ ] On completion: diff worktree vs HEAD → queue into `pending_changes`
|
||||
|
||||
### Dispatcher
|
||||
|
||||
- [ ] `apps/coder/src/services/dispatcher.ts` — polls `tasks` WHERE `state='pending'`, picks by priority + creation order
|
||||
- [ ] Transport selection: check `available_agents.supports_acp` at dispatch time
|
||||
- [ ] On failure: mark `state='failed'`, surface in `human_inbox`
|
||||
- [ ] On completion: mark `state='completed'`, queue diff if Path B
|
||||
|
||||
### Agent probing
|
||||
|
||||
- [ ] Startup probe: `which opencode && opencode --version`, `which goose`, `which claude`, `which pi`
|
||||
- [ ] Populate `available_agents` table with version + ACP support
|
||||
|
||||
### Verification
|
||||
|
||||
- [ ] Smoke: dispatch a task to `opencode` via ACP → task completes → diff queued
|
||||
- [ ] Smoke: dispatch to `claude` via PTY fallback → captures output → diff from worktree
|
||||
- [ ] Worktree cleanup after task completion
|
||||
|
||||
## v2.0.2 — BooCoder MCP server
|
||||
|
||||
### Implementation
|
||||
|
||||
- [ ] `apps/coder/src/services/mcp-server.ts` — register 6 tools as MCP tool handlers
|
||||
- [ ] Stdio transport (use `@modelcontextprotocol/sdk` server-side, same SDK as client)
|
||||
- [ ] Tools: `boocoder.create_task`, `boocoder.list_pending_changes`, `boocoder.apply`, `boocoder.reject`, `boocoder.dispatch_external_agent`, `boocoder.list_worktrees`
|
||||
- [ ] Each tool maps to a DB operation or service call
|
||||
|
||||
### Eval
|
||||
|
||||
- [ ] Write 10-question eval per `anthropics/skills/mcp-builder` framework
|
||||
- [ ] Run eval against the MCP server — all 10 must pass before shipping
|
||||
- [ ] Document eval results in openspec
|
||||
|
||||
### Verification
|
||||
|
||||
- [ ] From a terminal: `echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | boocoder --mcp` → returns 6 tools
|
||||
- [ ] From opencode: configure BooCoder as an MCP server in `~/.opencode/config.json`, verify tool calls work
|
||||
|
||||
## v2.0.3 — Polish
|
||||
|
||||
### CLI client
|
||||
|
||||
- [ ] `apps/coder/src/cli.ts` — thin WebSocket/HTTP client against BooCoder API
|
||||
- [ ] Verbs: `boocode run <task>`, `boocode ls`, `boocode attach <id>`, `boocode send <id> <message>`
|
||||
- [ ] Mirrors Paseo's UX, license-clean implementation
|
||||
|
||||
### Human inbox UI
|
||||
|
||||
- [ ] Frontend route showing tasks in `blocked`/`failed` state
|
||||
- [ ] Per-task: view output, retry, cancel, reassign to different agent
|
||||
|
||||
### Cost tracking
|
||||
|
||||
- [ ] `tasks.cost_tokens` populated from inference usage
|
||||
- [ ] Summary view: per-project, per-agent, per-day token spend
|
||||
|
||||
### Verification
|
||||
|
||||
- [ ] `boocode run "add a health endpoint"` from terminal → task appears in UI → completes → diff in pane
|
||||
- [ ] `boocode ls` shows running/completed/failed tasks
|
||||
Reference in New Issue
Block a user