diff --git a/README.md b/README.md index b06fd41..b3e4235 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Self-hosted single-user developer chat app. 3-app monorepo: BooChat (read-only chat), BooCoder (write tools + agent dispatch), BooTerm (PTY terminals). +**Latest release:** `v2.2.1-pane-scoped-chats` (2026-05-26) · [`CHANGELOG.md`](CHANGELOG.md) · **Current focus:** [`CURRENT.md`](CURRENT.md) + **Agent navigation:** [`AGENTS.md`](AGENTS.md) · **Architecture:** [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) · **Engineering reference:** [`CLAUDE.md`](CLAUDE.md) ## Stack @@ -53,6 +55,14 @@ docker compose up --build -d Binds to `100.114.205.53:9500` (Tailscale). Authelia is expected to gate the upstream and inject `Remote-User`. Postgres binds loopback only. +BooCoder runs as a **host systemd service** (`boocoder.service`, port `:9502`), not in Docker: + +```bash +pnpm -C apps/server build && pnpm -C apps/coder build +sudo systemctl restart boocoder +curl http://100.114.205.53:9502/api/health +``` + ## Services |Service|Port|Description| @@ -65,6 +75,12 @@ upstream and inject `Remote-User`. Postgres binds loopback only. ## What's shipped -- **BooChat**: streaming chat, file-read tools, compaction, reasoning support, HTML/Markdown artifact panes, cross-repo read grants, MCP client (Context7 + multi-server), tool-cost tracking, skills system, agent registry, provider picker with model discovery +See [`boocode_roadmap.md`](boocode_roadmap.md) for full version history. Highlights as of **v2.2.1**: + +- **BooChat**: streaming chat, file-read tools, compaction, reasoning support, HTML/Markdown artifact panes, cross-repo read grants, MCP client (multi-server + stdio), tool-cost tracking, skills system, builtin agent registry, multi-pane workspace (chat / terminal / coder) - **BooTerm**: in-browser terminal panes via tmux + xterm.js, per-session tmux sessions, SSH-out support -- **BooCoder**: write tools (`edit_file`, `create_file`, `delete_file`, `apply_pending`, `rewind`), pending-changes queue with diff UI, ACP/PTY dual-path agent dispatch, MCP server (6 tools, stdio), CLI client, human inbox, Boomerang orchestration, path-guard fuzz suite +- **BooCoder (v2.2)**: write tools (`edit_file`, `create_file`, `delete_file`, `apply_pending`, `rewind`), pending-changes queue with diff UI, Paseo-style provider snapshot (7 providers: boocode, cursor, claude, opencode, goose, qwen, copilot), `AgentComposerBar` (provider / mode / model / thinking), ACP dispatch with inline permission prompts + tool/reasoning streaming, PTY fallback, Arena, MCP server (6 tools, stdio), CLI client, human inbox, Boomerang orchestration, path-guard fuzz suite, **pane-scoped chats** (v2.2.1 — each coder/terminal pane owns its chat) + +## Planned + +- **v2.3 provider lifecycle** — config-backed provider registry (`/data/coder-providers.json`), enable/disable toggles, two-tier probe (openspec drafted). See [`CURRENT.md`](CURRENT.md). diff --git a/boocode_roadmap.md b/boocode_roadmap.md index b9f34e8..360736b 100644 --- a/boocode_roadmap.md +++ b/boocode_roadmap.md @@ -1,6 +1,6 @@ -# BooCode v1.x — Roadmap +# BooCode roadmap (v1.x–v2.x) -Last updated: 2026-05-25 +Last updated: 2026-05-26 > **Companion doc:** `boocode_code_review.md` holds the full external-repo inventory, lift rationale, and license analysis. This document is the canonical source for shipping state, version ordering, and what's planned vs. shipped. @@ -9,7 +9,7 @@ Last updated: 2026-05-25 BooCode is a **3-app monorepo** at `/opt/boocode/` (locked 2026-05-22): - **BooChat** (`apps/server` + `apps/web`, port `9500`, `code.indifferentketchup.com`) — read-only chat with file-inspection tools. Backend in `apps/server`, SPA in `apps/web`. Database `boochat` (renamed from `boocode` at v2.0). -- **BooCoder** (`apps/coder`, port `9502`, `coder.indifferentketchup.com`) — write tools + external-CLI dispatch. **Shipped v2.0.0–v2.1.0.** Host systemd service (not Docker since v2.1.0). In-process inference (with `pending_changes` table) AND ACP-dispatched external agents (opencode/goose) with PTY fallback (claude/qwen). +- **BooCoder** (`apps/coder`, port `9502`, `coder.indifferentketchup.com`) — write tools + external-CLI dispatch. **Shipped v2.0.0–v2.2.1.** Host systemd service (not Docker since v2.1.0). In-process inference (with `pending_changes` table) AND Paseo-style ACP dispatch for seven providers (cursor, opencode, goose, claude, qwen, copilot + native boocode) with PTY fallback where ACP is unavailable. - **BooTerm** (`apps/booterm`, port `9501`) — PTY/tmux/xterm.js. **Live since May 2026.** bookworm-slim + node-pty + tmux + xterm.js. Tmux session per pane (`bc-`), SSH-out works (openssh-client + gosu in the image). Shares Postgres database `boochat`. Caddy → Authelia → Tailscale → `100.114.205.53` → 9500/9501/9502. Three apps, **one shared Postgres** (Docker service `boocode_db`, database name `boochat`). @@ -21,13 +21,13 @@ Caddy → Authelia → Tailscale → `100.114.205.53` → 9500/9501/9502. Three - **Mount strategy: blanket `/opt:rw`, permission gating at the write-tool layer.** Per-project scoping is policy, not mount. Path-guard correctness is the #1 test target for v2.0. - **External CLI agents (`opencode`/`claude`/`goose`/`pi`) live on the host, not in containers.** BooCoder shells out via local-exec PTY or ACP subprocess. Host install inherits Sam's existing `~/.opencode/`, `~/.claude/`, `~/.config/goose/` configs. - **Protocol roles locked (2026-05-22):** **BooChat = MCP client only** (read-only tool consumer, never enables write-capable MCP servers). **BooCoder = MCP client + MCP server + ACP client (host) + ACP agent (driveable)** — full matrix. BooCoder's ACP-client role replaces raw-PTY dispatch for ACP-capable agents (opencode `opencode acp`, goose `goose acp`); PTY fallback retained for claude/pi/smallcode. -- **Strategic target: Paseo-equivalent dispatcher inside BooCode** (2026-05-22 pivot). Paseo (`getpaseo/paseo`) is AGPL-3.0 — incompatible with BooCode's MIT license and network-served deployment. Reproduce the architecture using only license-clean patterns. Primary architectural template: `Dominic789654/agent-hub` (Apache-2.0). Critical context-management primitive: Roo Code Boomerang Tasks pattern. Observation pattern: Claude Code hooks (siropkin/budi reference). +- **Paseo-equivalent dispatcher inside BooCode** (2026-05-22 pivot, **shipped v2.2**). Paseo (`getpaseo/paseo`) is AGPL-3.0 — incompatible with BooCode's MIT license and network-served deployment. BooCode reproduces the architecture using license-clean patterns only (`provider-snapshot.ts`, ACP merge/stream/persist, `AgentComposerBar`). Primary architectural template: `Dominic789654/agent-hub` (Apache-2.0). Critical context-management primitive: Roo Code Boomerang Tasks pattern. Observation pattern: Claude Code hooks (siropkin/budi reference). External code lifted from / referenced in: see `boocode_code_review.md` for full inventory. ----- -## Shipped (status as of 2026-05-23) +## Shipped (status as of 2026-05-26) |Version |Theme |Tag | |-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------| @@ -263,7 +263,7 @@ Independent batch — ships clean any time after v1.13. Low leverage unless Sam **Major version bump.** New app `apps/coder/` inside the existing monorepo (not a separate repo). Shipped with database rename `boocode` → `boochat` and subdomain split (`code.indifferentketchup.com` → BooChat, `coder.indifferentketchup.com` → BooCoder). -**Shipped v2.0.0–v2.0.4.** All 8 phases complete. See retrospective below. +**Shipped v2.0.0–v2.0.5.** All 8 phases complete plus v2.0.5 (Arena, FAST_MODEL, Qwen dispatch). See retrospective below. **Three protocol roles in one surface:** @@ -318,7 +318,7 @@ Independent batch — ships clean any time after v1.13. Low leverage unless Sam **Estimated:** ~1500 LoC for Path A + Path B + shared schema, plus ~400 LoC for the MCP-server role, plus ~300 LoC for the ACP-client role. Multiple sub-versions: v2.0.0 native + ACP, v2.0.1 MCP server, v2.0.2 polish. -**Retrospective (2026-05-25):** All 8 phases shipped. v2.0.0-alpha through v2.0.4-hardening. The full BooCoder line is complete: write tools with pending-changes queue, dispatcher with ACP/PTY dual paths, MCP server (6 tools, stdio transport, 10-question eval passed), CLI client, human inbox, Boomerang `new_task` orchestration, and path-guard fuzz suite (34 traversal-attack tests). Runtime isolation (v2.1) remains optional pending production bake. +**Retrospective (2026-05-25, updated 2026-05-26):** All 8 phases shipped. v2.0.0-alpha through v2.0.5. The full BooCoder foundation is complete: write tools with pending-changes queue, dispatcher with ACP/PTY dual paths, MCP server (6 tools, stdio transport, 10-question eval passed), CLI client, human inbox, Boomerang `new_task` orchestration, and path-guard fuzz suite (34 traversal-attack tests). v2.1 added host systemd + provider picker; **v2.2 shipped the Paseo provider/dispatch stack** (`v2.2-paseo-providers` + `v2.2.1-pane-scoped-chats`). Runtime isolation (v2.1 optional batch) remains optional pending production bake. ----- @@ -338,7 +338,27 @@ Per-session Docker sandbox spawned by BooCoder on first write. Only project path ----- -## v2.2 — BooCoder as ACP agent (driveable from external editors) +----- + +## v2.2 — Paseo-style providers + +**Shipped `v2.2-paseo-providers` (2026-05-26).** Paseo-equivalent provider stack for BooCoder. Seven providers (boocode, cursor, claude, opencode, goose, qwen, copilot) with snapshot API (`provider-snapshot.ts`, ACP cold probe, per-provider model merge, cursor models from ACP). Frontend `AgentComposerBar` replaces v2.1's `ProviderPicker` — provider / mode / model / thinking in the coder composer; `SlashCommandPicker` + `useProviderSnapshot`. ACP dispatch rewritten (`acp-dispatch.ts`, `acp-stream.ts`, `acp-spawn.ts`, `agent-turn-persist.ts`, `acp-tool-snapshot.ts`) with Paseo merge/stream/persist, inline `PermissionCard` prompts, and `reasoning_delta` WS frames. Agent slash-command hints via ACP `available_commands_update` + `AgentCommandsHint`. Arena and MCP entry points accept `mode_id` / `thinking_option_id`. SSH helpers removed; host exec via `host-exec.ts`. Openspec archived to `openspec/changes/archived/v2.2-paseo-providers.md`. + +**Shipped `v2.2.1-pane-scoped-chats` (2026-05-26, same commit).** Follow-up fixes: pane-scoped chat resolution (`resolveChatId` requires `pane_id`; client seeds dedicated chats per coder/terminal pane), `CoderMessageList` BooChat-style tool timeline, WS user-delta replace-not-append, inference `buildMessagesPayload` orphan `tool_calls` stripping for shared chats with ACP history. + +----- + +## v2.3 — Provider lifecycle (Paseo-style registry) + +**Planned.** Config-backed provider registry (`/data/coder-providers.json`), merged built-ins + overrides, enable/disable toggles, two-tier probe (fast binary vs slow ACP session), generic ACP spawn from config without new code paths. Depends on v2.2 snapshot wire shape. Openspec: `openspec/changes/v2-3-provider-lifecycle/`. See `CURRENT.md`. + +**Lift source:** Paseo provider docs (design only — no AGPL code lift). + +**Dependencies:** v2.2. + +----- + +## v2.4 — BooCoder as ACP agent (driveable from external editors) **Goal:** expose `boocoder acp` so Zed, JetBrains, Avante.nvim, CodeCompanion.nvim can drive BooCoder as their agent. Outbound exposure of the BooCoder write-tool surface to ACP-compatible editors. @@ -348,11 +368,11 @@ Per-session Docker sandbox spawned by BooCoder on first write. Only project path 1. BooCoder UI features remain optional: editor drives session via ACP; pending-changes queue still gates writes; user can approve/reject from either BooCoder's web UI or the editor's permission dialog (whichever responds first). 1. Same auth model as the rest of BooCoder — editor must be reachable on the Tailscale mesh, or BooCoder is invoked with a short-lived token. -**Why this is v2.2, not v2.0:** outbound ACP-agent role is cheap once the inbound ACP-client side is implemented (same protocol library, server side), but it's a *different product surface* — driving BooCoder from external editors. Ship it after BooCoder's own surface stabilizes. +**Why v2.4, not v2.0:** outbound ACP-agent role is cheap once the inbound ACP-client side is implemented (same protocol library, server side), but it's a *different product surface* — driving BooCoder from external editors. Ship it after BooCoder's own surface stabilizes. (The v2.2 version number was used for the Paseo provider/dispatch batch shipped 2026-05-26.) **Lift source:** `zed-industries/codex-acp` (Apache-2.0) as a server-side ACP reference implementation. -**Dependencies:** v2.0 + v2.1 (recommended; ACP-driven sessions inside a sandbox are stronger). +**Dependencies:** v2.0 + v2.2 (recommended; v2.1 runtime isolation optional). **Estimated:** ~400 LoC. @@ -360,7 +380,9 @@ Per-session Docker sandbox spawned by BooCoder on first write. Only project path ## v2.1.0 — Provider picker + model discovery -**Shipped `v2.1.0-provider-picker`.** Provider registry with 5 providers (boocode, opencode, goose, claude, qwen). Model discovery via `LLAMA_SWAP_URL/upstream//props`. `/api/providers` route returns installed providers with models. `ProviderPicker` frontend component in workspace toolbar. Agent-probe startup probe discovers installed agents on host, their versions, ACP support, and models. Booterm SSH host configurable via `BOOTERM_SSH_HOST`/`BOOTERM_SSH_USER` env vars. +**Shipped `v2.1.0-provider-picker`.** Provider registry with 5 providers (boocode, opencode, goose, claude, qwen). Model discovery via `LLAMA_SWAP_URL/upstream//props`. `/api/providers` route returns installed providers with models. v2.1 `ProviderPicker` UI **superseded by `AgentComposerBar` in v2.2.** Agent-probe startup probe discovers installed agents on host, their versions, ACP support, and models. Booterm SSH host configurable via `BOOTERM_SSH_HOST`/`BOOTERM_SSH_USER` env vars. + +**Shipped `v2.1.1-roadmap-cleanup`.** Roadmap reconciliation, README updates, openspec archive housekeeping. No runtime behavior changes. ----- @@ -390,7 +412,7 @@ Per-session Docker sandbox spawned by BooCoder on first write. Only project path |-------------------------------|---------------------|-----------------------------|------------------------------------------------------------------------|----------------------| |`boochat` (was `boocode`) |`100.114.205.53:9500`|`/opt:/opt:ro` |Read-only chat + SPA host + MCP client |Live (renames at v2.0)| |`booterm` |`100.114.205.53:9501`|`/opt:/opt` |PTY/tmux terminal sessions |**Live (May 2026)** | -|`boocoder` |`100.114.205.53:9502`|`/opt:/opt:rw` (policy-gated)|Write tools + ACP host + MCP client + MCP server + external-CLI dispatch|**Shipped v2.0.0–v2.0.4** | +|`boocoder` (host systemd) |`100.114.205.53:9502`|full host FS (policy-gated) |Write tools + ACP client + MCP client + MCP server + external-CLI dispatch|**Shipped v2.0.0–v2.2.1** (systemd since v2.1.0) | |**`boochat`** (Docker service `boocode_db`)|`127.0.0.1:5500` |`boocode_pgdata` volume |Postgres 16-alpine (shared by all three) |**Live** (DB renamed from `boocode` at v2.0)| |`codecontext` |`:8080` (internal, Docker network) |`/opt:/opt:ro`|Go HTTP sidecar for code graph tools |**Live (v1.12.0)** | @@ -436,7 +458,8 @@ term.indifferentketchup.com → booterm :9501 (or routed under code. - **v1.15:** `permissions` table, `agent_permissions` join, `session_permissions` join, `mcp_servers (name, type, transport, url_or_command, enabled, config_hash, last_probed_at)` registry - **v1.16:** `repo_health_cache (project_id, file_hashes_sig, payload JSONB, created_at)` - **v2.0 (shipped):** `pending_changes`, `tasks`, `available_agents`, `human_inbox` view; database renamed `boocode` → `boochat` -- **v2.2:** none (`boocoder acp` is a new entry point, not a schema change) +- **v2.2 (shipped):** none (provider snapshot + ACP dispatch are runtime/services; pane chat scoping uses existing `sessions.workspace_panes` + `chats`) +- **v2.4:** none (`boocoder acp` is a new entry point, not a schema change) ----- @@ -471,10 +494,10 @@ Full inventory and rationale in `boocode_code_review.md`. Headline items below; |`spirituslab/codesight` |MIT-ish |Repo health analyzer (`analyze.mjs`) |v1.16 | |`plandex-ai/plandex` |MIT |Pending-changes data model + diff/apply/rewind UX |v2.0 | |`Dominic789654/agent-hub` |Apache-2.0 |**Task DAG schema, dispatcher worker, project registry, human inbox** — primary architectural template for v2.0 dispatcher|v2.0 | -|`getpaseo/paseo` |AGPL-3.0 (**design only, no code lift**)|Daemon+clients arch, CLI verb shape, –worktree flag, three skills concept |v2.0 / v2.x | -|**`agentclientprotocol.com` spec + `@zed-industries/agent-client-protocol` SDK**|**Apache-2.0** |**ACP client (host) — replaces raw-PTY dispatch for opencode/goose** |**v2.0** | +|`getpaseo/paseo` |AGPL-3.0 (**design only, no code lift**)|Daemon+clients arch, CLI verb shape, –worktree flag, provider snapshot/dispatch patterns |**v2.2 (shipped)** / v2.x | +|**`agentclientprotocol.com` spec + `@zed-industries/agent-client-protocol` SDK**|**Apache-2.0** |**ACP client (host) — replaces raw-PTY dispatch for opencode/goose/cursor** |**v2.0 → v2.2** | |**anthropics/skills `mcp-builder`** |**MIT** |**MCP server build workflow + 10-question evaluation framework** |**v2.0 (BooCoder MCP server)** | -|**`zed-industries/codex-acp`** |**Apache-2.0** |**ACP server-side reference for `boocoder acp`** |**v2.2** | +|**`zed-industries/codex-acp`** |**Apache-2.0** |**ACP server-side reference for `boocoder acp`** |**v2.4** | |Roo Code: Boomerang Tasks |Apache-2.0 (pattern only) |Orchestrator capability restriction + down-pass/up-pass context discipline |v1.14 (AGENTS.md) → v2.0 (real delegation) | |`covibes/zeroshot` |MIT (pattern only) |Blind-validation invariant + complexity-classification conductor |v1.14 (AGENTS.md) → v2.0 (verify gate) | |`OpenHands/OpenHands` |MIT |Sandbox runtime contract |v2.1 | @@ -509,29 +532,29 @@ Full inventory and rationale in `boocode_code_review.md`. Headline items below; - **MCP client role:** inherits v1.15 client; write-capable servers allowed but writes route through `pending_changes` queue. - **MCP server role:** BooCoder exposes its own task primitives (`boocoder.create_task` etc.) so external `opencode` sessions in Termius become BooCoder-aware. Stdio for local, HTTP gated on OAuth+secret storage. - **ACP client (host) role:** replaces raw-PTY dispatch for ACP-capable agents (opencode, goose). PTY retained as fallback for claude/pi/smallcode. Critical pattern: ACP clients auto-forward MCP `context_servers` to the dispatched agent (per goose docs) — one MCP config drives every dispatched agent. - - **ACP agent role:** `boocoder acp` exposes BooCoder to Zed/JetBrains/Avante.nvim. Deferred to v2.2. + - **ACP agent role:** `boocoder acp` exposes BooCoder to Zed/JetBrains/Avante.nvim. Deferred to **v2.4**. - **Why BooChat doesn't get ACP:** ACP standardizes the editor→agent direction. BooChat doesn't drive agents; it *is* the chat. Adding ACP-agent to BooChat would convert it into an opencode-equivalent — different product. Skip. -- **MCP/ACP integration phasing:** v1.14.x (single-server MCP-client PoC against Context7) → v1.15 (full MCP client + permissions) → v2.0 (BooCoder full matrix: write-capable MCP client + MCP server + ACP client) → v2.2 (BooCoder ACP agent for external editor drive). +- **MCP/ACP integration phasing:** v1.14.x (single-server MCP-client PoC against Context7) → v1.15 (full MCP client + permissions) → v2.0 (BooCoder full matrix: write-capable MCP client + MCP server + ACP client) → **v2.2 (Paseo provider snapshot + ACP dispatch — shipped)** → v2.4 (BooCoder ACP agent for external editor drive). - **Reference materials:** anthropics `mcp-builder` skill (4-phase build workflow + 10-question eval framework — required for BooCoder's MCP server before shipping), opencode MCP/ACP docs as JSON-schema interop reference, goose ACP docs for the `context_servers` auto-forward pattern, `agentclientprotocol.com` spec (note: remote ACP via HTTP/WS still WIP, v2.0 uses stdio only). - **v1 MCP scope limit (security):** local-stdio MCP servers + Context7-style API-key remote only. Remote OAuth MCP servers (Sentry, Atlassian, etc.) deferred until BooCode has a real secret-storage primitive — token leakage from a PostgreSQL dump or Authelia bypass is a real attack surface that doesn't exist with local-stdio MCP. ### Monorepo / multi-app structure (2026-05-22, locked) -- **BooCode is a 3-surface monorepo** at `/opt/boocode/`: BooChat (`apps/server` + `apps/web`, :9500), BooCoder (`apps/coder`, :9502, **shipped v2.0–v2.1.0**, host systemd), BooTerm (`apps/booterm`, :9501, live since May 2026). One React SPA hosts chat, coder, and terminal panes. +- **BooCode is a 3-surface monorepo** at `/opt/boocode/`: BooChat (`apps/server` + `apps/web`, :9500), BooCoder (`apps/coder`, :9502, **shipped v2.0–v2.2.1**, host systemd), BooTerm (`apps/booterm`, :9501, live since May 2026). One React SPA hosts chat, coder, and terminal panes. - **Single shared database `boochat`.** Docker service `boocode_db`, all three surfaces connect to the same Postgres. Cross-surface joins are valuable (coder task → originating chat → term debugging session). - **Mount strategy: blanket `/opt:rw`, policy enforcement at the write-tool layer.** Per-project scoping is logic, not mount. Path-guard correctness becomes the highest-priority test target for v2.0 — fuzz it, property-test it, every traversal-attack pattern (including MCP-served filesystem writes). - **External CLI agents on the host, not in containers.** BooCoder shells out via local-exec PTY or ACP subprocess (`node-pty`, host shell, or `child_process.spawn('opencode', ['acp'])`). Host install inherits Sam's existing `~/.opencode/`, `~/.claude/`, `~/.config/goose/` configs without re-mounting. Containerize later only if a concrete reason emerges. -### Strategic pivot: Paseo-equivalent dispatcher (2026-05-22) +### Strategic pivot: Paseo-equivalent dispatcher (2026-05-22, **shipped v2.2**) -Sam wants BooCode to function like Paseo without using Paseo itself. **Paseo is AGPL-3.0** — incompatible with BooCode's MIT license and its network-served deployment at `code.indifferentketchup.com`. Solution: **reproduce the architecture in BooCode's existing Fastify + TS + PostgreSQL + React stack, using only license-clean patterns**. +Sam wanted BooCode to function like Paseo without using Paseo itself. **Paseo is AGPL-3.0** — incompatible with BooCode's MIT license and its network-served deployment at `code.indifferentketchup.com`. Solution: **reproduce the architecture in BooCode's existing Fastify + TS + PostgreSQL + React stack, using only license-clean patterns**. - **Primary architectural template:** `Dominic789654/agent-hub` (Apache-2.0) — three-process model (board server + dispatcher + assistant terminal) and schema (tasks/projects/templates/pipelines/human_inbox). - **Critical context-management primitive:** Roo Code Boomerang Tasks pattern — orchestrator with intentional capability restriction, down-pass/up-pass context discipline, no implicit inheritance. - **Observation pattern:** Claude Code hooks (siropkin/budi reference) — register BooCode as the hook receiver for `SessionStart`/`UserPromptSubmit`/`PostToolUse`/`SubagentStart`/`Stop`. -- **Protocol-level Paseo equivalence:** the ACP client + MCP server combination in BooCoder is the protocol-spelled version of Paseo's daemon. ACP gives multi-agent dispatch with structured events instead of free-form PTY output. MCP server gives BooCoder-as-task-board, callable from any MCP client (Termius-based opencode, future editors). One MCP config feeds every dispatched agent (via `context_servers` auto-forward). +- **Protocol-level Paseo equivalence (shipped v2.2):** the ACP client + MCP server combination in BooCoder is the protocol-spelled version of Paseo's daemon. ACP gives multi-agent dispatch with structured events instead of free-form PTY output. MCP server gives BooCoder-as-task-board, callable from any MCP client (Termius-based opencode, future editors). One MCP config feeds every dispatched agent (via `context_servers` auto-forward). v2.2 added provider snapshot, mode/thinking, permission prompts, and Paseo-style stream/persist. -This is now the dominant roadmap direction, **ahead of v1.13.x cleanup batches in importance** but **behind them in sequence** (v1.13 finishing now; Paseo-equivalent work is v2.0+). +**Next on this track:** v2.3 provider lifecycle (config-backed registry, enable/disable, two-tier probe). See openspec `v2-3-provider-lifecycle`. ### BooCoder execution: both Option A AND Option B, full-featured (2026-05-22) @@ -541,13 +564,20 @@ Earlier May 18 chat recommended Option A (thin orchestration shell over OpenCode The v1.13.x cleanup line shipped 21 batches over a single intense window in `vMAJOR.MINOR.PATCH-slug` form: **v1.13.0-ai-sdk-v6 ✅ → v1.13.1-cleanup-bundle ✅ → v1.13.2-compaction-prune ✅ → v1.13.3-truncate ✅ → v1.13.4-reasoning-fix ✅ → v1.13.5-stability-bundle ✅ → v1.13.6-prefix-stability ✅ → v1.13.7-compaction-trigger ✅ → v1.13.8-tool-cost ✅ → v1.13.9-agentlint ✅ → v1.13.10-openspec ✅ → v1.13.11-tools ✅ → v1.13.12-ws-schemas ✅ → v1.13.13-ws-publish ✅ → v1.13.14-skills-audit ✅ → v1.13.15-codecontext-synth ✅ → v1.13.16-xml-parser ✅ → v1.13.17-cross-repo-reads ✅ → v1.13.18-codecontext-file-path ✅ → v1.13.19-html-artifact-panes ✅ → v1.13.20-drop-legacy-cols ✅** → umbrella `v1.13` ✅. **Do not fold** was the discipline — each batch has a distinct rollback surface, and bisecting a 750-LoC merge across four unrelated changes is worse than four separate dispatches. Held throughout; CHANGELOG.md is the per-tag canonical record. -### v1.14–v2.1 shipped (2026-05-25) +### v1.14–v2.2 shipped (2026-05-26) - **v1.14.0-outer-loop** ✅ — explicit `while` loop, per-agent `steps:` cap, doom-loop migration - **v1.14.1-mcp-poc** ✅ — Context7 MCP client validated - **v1.15.0-mcp-multi** ✅ — multi-server MCP client, stdio transport, per-agent tool globs -- **v2.0.0-alpha through v2.0.4-hardening** ✅ — full BooCoder line: write tools, dispatcher (ACP/PTY), MCP server (6 tools, stdio, 10-question eval passed), CLI client, human inbox, Boomerang `new_task` orchestration, path-guard fuzz suite (34 traversal-attack tests) -- **v2.1.0-provider-picker** ✅ — 5-provider registry, model discovery, `/api/providers` route, `ProviderPicker` UI, agent-probe startup probe +- **v2.0.0-alpha through v2.0.5** ✅ — full BooCoder line: write tools, dispatcher (ACP/PTY), MCP server (6 tools, stdio, 10-question eval passed), CLI client, human inbox, Boomerang `new_task` orchestration, path-guard fuzz suite (34 traversal-attack tests), Arena, FAST_MODEL +- **v2.1.0-provider-picker** ✅ — 5-provider registry, model discovery, `/api/providers` route, agent-probe startup probe, BooCoder host systemd migration +- **v2.1.1-roadmap-cleanup** ✅ — roadmap/README/openspec archive housekeeping +- **v2.2-paseo-providers** ✅ — 7-provider snapshot, `AgentComposerBar`, ACP dispatch rewrite, permission prompts, agent commands, cursor/copilot providers +- **v2.2.1-pane-scoped-chats** ✅ — pane-scoped chat resolution, `CoderMessageList` tool UI, WS user-delta fix, inference orphan tool_call stripping + +### In flight + +- **v2.3-provider-lifecycle** — config-backed provider registry, enable/disable, two-tier probe (openspec drafted; not started). See `CURRENT.md`. ### Numbering and scope-revision discipline during v1.13.x (2026-05-23) diff --git a/docs/DEFERRED-WORK.md b/docs/DEFERRED-WORK.md index f948372..0436ec7 100644 --- a/docs/DEFERRED-WORK.md +++ b/docs/DEFERRED-WORK.md @@ -11,7 +11,7 @@ Last updated: 2026-05-26 | Item | Category | User impact | Effort | Risk if left alone | |------|----------|-------------|--------|-------------------| | Task cancel → abort ACP/PTY child | Correctness / UX | High — Stop does not kill external agents | Medium | Zombie processes, stuck `running` tasks, orphaned worktrees | -| ~~Skip ACP cold probe when DB fresh~~ | ~~Performance~~ | ~~Medium~~ | ~~Medium~~ | **RESOLVED — v2.3 provider lifecycle** | +| Skip ACP cold probe when DB fresh | Performance | Medium — composer open can stall 5–30s on cache miss | Medium (v2.3 batch) | Slow provider picker; repeated ACP spawns on every snapshot rebuild | | Unified `packages/types` | Maintainability | Low (dev-only) | Medium–High | Type drift between server, coder, web | | Large file splits | Maintainability | None directly | Medium per file | Harder reviews, merge conflicts | | Retire `apps/coder/web/` fallback SPA | Scope / ops | Low — Sam uses CoderPane | Medium | Dual UI maintenance, divergent API client | @@ -108,9 +108,42 @@ There is also **no frontend** calling task cancel today (`grep` across `apps/web --- -## 2. ~~Skip ACP cold probe when DB models are fresh~~ **RESOLVED — v2.3 provider lifecycle** +## 2. Skip ACP cold probe when DB models are fresh -Addressed in [`openspec/changes/v2-3-provider-lifecycle/`](../openspec/changes/v2-3-provider-lifecycle/design.md). The v2.3 snapshot module (`provider-snapshot.ts`) uses DB `available_agents` models as the warm path and only cold-probes on explicit `POST /api/providers/refresh`. Opening the provider picker no longer triggers any probe. `PROVIDER_PROBE_TTL_MS` env var (default 24h) controls stale-model self-heal. +**Status:** Planned — [`openspec/changes/v2-3-provider-lifecycle/`](../openspec/changes/v2-3-provider-lifecycle/proposal.md). **Not shipped** (no `v2.3` tag; all tasks unchecked). + +### Current behavior (v2.2) + +`apps/coder/src/services/provider-snapshot.ts` on cache miss: + +1. Reads `available_agents.models` as a **fallback** when building each entry +2. Still **cold-probes every installed ACP provider** on every rebuild (`probeAcpProvider` in `buildProviderEntry`) — DB models do not skip the probe +3. In-memory snapshot cache TTL is **5 minutes** (`CACHE_TTL_MS`); opening `AgentComposerBar` calls `GET /api/providers/snapshot` via `useProviderSnapshot` +4. `POST /api/providers/refresh` clears cache and forces a full rebuild (all probes again) +5. Uninstalled agents are **omitted** from the snapshot (`return null`) — not listed as `unavailable` +6. No config-file enable/disable; providers are hardcoded in `provider-registry.ts` + +`persistProbedModels()` writes probe results back to `available_agents` (including `last_probed_at`), but nothing reads `last_probed_at` to skip tier-2 probes yet. There is no `PROVIDER_PROBE_TTL_MS` env var. + +### Planned behavior (v2.3) + +See [`design.md`](../openspec/changes/v2-3-provider-lifecycle/design.md): + +- Tier-1 fast binary check + tier-2 ACP session only when stale or explicitly refreshed +- `PROVIDER_PROBE_TTL_MS` (default 24h) gate on `available_agents.last_probed_at` +- Return `loading` synchronously on cache miss; complete via inflight promise +- Always list registered providers (`ready` | `unavailable` | `error` | `loading`); respect `enabled` from `/data/coder-providers.json` +- Cold probe only on `POST /api/providers/refresh` (or TTL expiry), not on every composer open + +### Why deferred past v2.2 + +v2.2 shipped the snapshot wire shape and ACP dispatch stack. Lifecycle semantics (config registry, enable/disable, probe TTL, settings UI) were scoped as the follow-on **v2.3** batch to avoid mixing two large behavior changes in one tag. + +### Acceptance criteria (when v2.3 ships) + +- Second `GET /api/providers/snapshot` within TTL does not invoke `probeAcpProvider` (mock assert in tests) +- Disabled provider visible in settings, absent from composer +- Explicit refresh repopulates models; warm open is sub-second --- @@ -297,7 +330,7 @@ Standalone Vite React app (`@boocode/coder-web`) built into `apps/coder/web/dist If picking these up as openspec batches: 1. **Task cancel abort** — highest correctness gap; unblocks honest Stop button in CoderPane -2. **ACP probe skip** — quick win for provider picker latency once semantics agreed +2. **v2.3 provider lifecycle** — probe TTL, config registry, enable/disable (includes §2 above) 3. **CoderPane hook extraction** — natural follow-on when adding cancel UI 4. **Zod parity or packages/types** — when next WS/provider field is added 5. **Retire coder/web** — only after explicit “I don’t use :9502 UI” confirmation @@ -308,5 +341,6 @@ If picking these up as openspec batches: - [`STALE-DEPRECATED.md`](./STALE-DEPRECATED.md) — resolved stale items - [`ARCHITECTURE.md`](./ARCHITECTURE.md) — BooChat / BooCoder surfaces -- [`openspec/changes/v2-2-paseo-providers/design.md`](../openspec/changes/v2-2-paseo-providers/design.md) — provider snapshot API +- [`openspec/changes/archived/v2.2-paseo-providers.md`](../openspec/changes/archived/v2.2-paseo-providers.md) — shipped v2.2 provider snapshot API +- [`openspec/changes/v2-3-provider-lifecycle/`](../openspec/changes/v2-3-provider-lifecycle/) — planned probe lifecycle + config registry (§2) - [`BOOCODER.md`](../BOOCODER.md) — dispatch, worktrees, pending changes