Files
boocode/boocode_roadmap.md
indifferentketchup 2bce4d85fa feat(mobile): v1.8 tab switcher + branch indicator + git_status tool
Mobile header is now two rows. Row 1: hamburger | project · branch
indicator (live via GET /api/projects/:id/git, 30s poll) | ModelPicker |
FolderTree. Row 2: pane-switcher pill (hand-rolled BottomSheet) +
NewPaneMenu. Chat-within-pane navigation hidden on mobile; users switch
panes via the sheet. Cross-tab status sync via chat_status frames
published from inference.ts at working/idle/error transitions; StatusDot
component renders amber-pulse/green/red/gray on each pane row and on
desktop ChatTabBar tabs. Level 1 git awareness exposes a read-only
git_status tool to the model, backed by services/git_meta.ts (execFile
+ 2s timeout + 30s cache). Workspace.tsx now receives panes/chats hooks
as props (hoisted into Session.tsx) so the header pill shares state
with the pane grid.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 20:07:53 +00:00

341 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BooCode v1.x — Roadmap
Last updated: 2026-05-16
## Overview
BooCode is a standalone code-chat tool at `/opt/boocode/`. Read-only by design — pick a project, chat with a local LLM that has file-inspection tools, get streaming responses over WebSocket.
Live at `https://code.indifferentketchup.com` (Caddy → Authelia → Tailscale → `100.114.205.53:9500`).
**Architectural commitments:**
- No embeddings. The model uses file-view tools (`view_file`, `list_dir`, `grep`, `find_files`) + sidecar analyzers (codecontext, codesight). Walked away from the RAG pipeline May 2026.
- Read-only in v1.x. Write tools land in BooCoder (separate container, post-v1.x).
- One Postgres (`boocode_db`), one frontend SPA, container-per-service for new capabilities.
External code lifted from / referenced in: see `boocode_code_review.md` for full inventory.
-----
## Batch summary
|Batch |Theme |Status |Branch / Notes |
|------------------------------------------|-----------------------------------------------------------------------------------|-----------|---------------------------------------|
|1 |Markdown, Copy + Regen, tok/s + ctx, AI naming |✅ Done |`v1.1-batch1` merged |
|2 |Sidebar restructure |✅ Done |`v1.1-batch2` merged |
|3 |Pane system, FileBrowserPane + Shiki, cross-tab |✅ Done |`v1.1-batch3` merged |
|3.5 |Chip infrastructure, `@file`, line-select |✅ Done |merged |
|4 (v1.2) |Chats inside sessions, right-rail, `/compact`, archive, force-send |✅ Done |merged |
|4.14.4 |Project archive, sidebar context, Gitea API, bootstrap |✅ Done |merged |
|v1.5 cleanup |resolveProjectPath, BOOTSTRAP_ROOT, vitest pin |✅ Done |merged |
|v1.6 mobile |Drawer, single-pane, long-press, IME-safe, pull-to-refresh, swipe-close |✅ Done |merged |
|v1.6.1 |RightRail mobile wrapper fix |✅ Done |merged |
|Tool-loop bump |MAX_TOOL_LOOP_DEPTH 5→15 |✅ Done |merged |
|v1.6.2 |Workspace + Session+Project headers + ChatTabBar new-chat + RightRail mobile drawer|🔄 In flight|`v1.6.2-mobile-ui-fixes` |
|**v1.8 mobile tabs** |**Bottom-sheet pane switcher + cross-tab `pane_status` WS sync + StatusDot on tabs**|**Next up**|`v1.8-mobile-tabs`; hand-rolled sheet |
|9 (REORDERED, DECOUPLED) |Agents (Tier 2): `AGENTS.md`, per-agent temp/tools, picker in ChatInput toolbar |✅ Implemented, uncommitted|six builtins; on `main` awaiting commit|
|5 |Fork message, delete message, header polish |Planned | |
|6 |Drag-drop file + paste-as-attachment |Planned |thin extension of 3.5 chips |
|7 |Settings drawer: system prompt, web search toggle, agent entry |Planned |adds SettingsDrawer agent entry (Batch 9 deferred half) |
|8 |Web search backend: SearXNG `web_search` + `web_fetch` |Planned | |
|10 |BooTerm: separate container, xterm.js + node-pty + tmux |Planned | |
|11 — Architect: codebase map |codecontext sidecar + MCP tool wiring |Planned |from nmakod/codecontext |
|11b — Architect: repo health |call graph, circular deps, dead code |Planned |from spirituslab/codesight |
|12 — Tool approval + plan/act mode |Read-only invariant, per-tool gating |Planned |from cline |
|13 — Append-only event log |Replace messages-table semantics |Planned |from OpenHands V1 |
|14 — BooCoder: pending changes |Sandboxed edit queue, atomic apply |Post-v1.x |from plandex |
|15 — BooCoder runtime isolation |Per-session Docker sandbox |Post-v1.x |from OpenHands |
|16 — Multi-provider LLM |Optional litellm-style abstraction |Optional |from pi-ai |
|17 — Workflow graphs |Multi-agent coordination |Far future |from microsoft/agent-framework concepts|
**Old Batch 12 (codebase indexer w/ Harrier embeddings) — REMOVED.** Replaced by Batch 11/11b sidecar approach. See `boocode_code_review.md` decisions log.
**Batch 9 reordered ahead of 58, 10.** Picker mounts in `ChatInput.tsx` toolbar only. SettingsDrawer agent entry rolled into Batch 7 when it lands. No UI dependency on Batches 5/6/7, so it can ship anytime after v1.6.2.
-----
## Batch details (planned / new)
### Batch 9 — Agents (Tier 2, DECOUPLED)
**Spec:** `boocode_batch9.md` with the deltas below.
**Status:** Next up after v1.6.2 merges. Decoupled from Batch 7.
**Deltas from `boocode_batch9.md`:**
1. Builtin defaults in `agents.ts` OMIT the `model` field. Resolution order makes `session.model` win when `agent.model` is null. Spec line 30 example is misleading — do not hardcode any model in builtins.
2. Builtin defaults are the six agents shipped in `/opt/boocode/AGENTS.md`: **Code Reviewer, Debugger, Refactorer, Architect, Security Auditor, Prompt Builder.** If project root `AGENTS.md` exists, only its agents show. If absent, show the six builtins.
3. AgentPicker mounts in `ChatInput.tsx` toolbar between ModelPicker and the `+` button. **No `SettingsDrawer.tsx` or `Header.tsx` changes in this batch.**
4. SettingsDrawer agent entry + Header active-agent badge moved to Batch 7.
**Files to create:**
- `apps/server/src/services/agents.ts` — parser, six builtin defaults, mtime-keyed cache.
- `apps/server/src/routes/agents.ts``GET /api/projects/:id/agents`.
- `apps/web/src/components/AgentPicker.tsx` — dropdown, matches ModelPicker pattern.
**Files to modify:**
- `apps/server/src/schema.sql``ALTER TABLE sessions ADD COLUMN IF NOT EXISTS agent_id TEXT;`
- `apps/server/src/services/inference.ts` — resolution order: `effective_system_prompt`, `effective_model`, `effective_temperature`, `effective_tools` from session + agent + project. Filter tools array against agent whitelist before sending to llama-swap.
- `apps/server/src/routes/sessions.ts` — PATCH accepts `agent_id`.
- `apps/server/src/types/api.ts` — Agent type, extend Session with `agent_id`.
- `apps/web/src/api/client.ts`, `apps/web/src/api/types.ts` — Agent type, `api.agents.list(projectId)`.
- `apps/web/src/components/ChatInput.tsx` — mount AgentPicker.
**Testing plan (manual, before locking temps):**
- Drop `/opt/boocode/AGENTS.md` (six agents, no `model` field on any).
- For each of the 7 keeper models, switch session model and run the same target prompt against each agent. Log tok/s, instruction-following quality.
- Adjust per-agent temperature in `AGENTS.md` based on results.
- A/B candidates: qwen3.6-35b-a3b-mxfp4 (daily), qwopus3.6-35b-a3b-q4 (reasoning), qwopus3.5-27b-q4, qwen3.6-27b-ud-q4-xl, nemotron-3-nano-30b, gemma-4-26b-a4b-mxfp4, qwen3-coder-30b-apex.
**Dependencies:** v1.6.2 merged.
-----
### Batch 11 — Architect: codebase map (REVISED)
**Inspiration / lift:** `nmakod/codecontext` (MIT, Go binary).
**What it gives BooCode:** an architect-grade codebase overview without embeddings. Codecontext parses the repo with tree-sitter, extracts symbols, builds import/dependency relationships, and exposes the result via an MCP server with 8 tools. The model gets a structural map of any codebase on demand.
**Why this replaces the original Batch 11 (aider PageRank port):** codecontext is a finished binary in our stack language (Go), with watch mode, incremental updates, framework detection, and git-co-change-based semantic neighborhoods (no embeddings). The aider port would be reimplementing what codecontext already ships.
**Scope:**
- Add `codecontext` sidecar container to `docker-compose.yml`. Mount the project root read-only. One sidecar per BooCode instance — projects are addressed by absolute path.
- Wire each codecontext MCP tool into BooCodes `inference/tools.ts` as a native tool the model can call:
- `repo_overview(project_id)` → codecontext `get_codebase_overview`
- `repo_file_analysis(project_id, path)``get_file_analysis`
- `repo_symbol_info(project_id, symbol)``get_symbol_info`
- `repo_search_symbols(project_id, query)``search_symbols`
- `repo_dependencies(project_id, path)``get_dependencies`
- `repo_semantic_neighborhoods(project_id, path)``get_semantic_neighborhoods` (git co-change)
- `repo_framework_analysis(project_id)``get_framework_analysis`
- `path_guard.ts` extension: incorporate `continuedev/continue` `DEFAULT_SECURITY_IGNORE_FILETYPES` so codecontext cant surface `.env`, `.pem`, keys, etc.
- Fallback grammars: drop `Aider-AI/aider`s `aider/queries/tree-sitter-*.scm` files for any language codecontext doesnt cover. Use them via an in-process tree-sitter wrapper *only if* a project needs an unsupported language. Defer wrapper build until thats an actual gap.
**Where it goes:** new `apps/server/src/architect/` directory. No new tables — codecontext maintains its own state on disk. New env: `CODECONTEXT_URL=http://codecontext:8765` (MCP endpoint).
**Decisions to make at recon time:**
- Bundle the binary directly in the BooCode Dockerfile, or run codecontext as its own service? Sidecar is cleaner. Bundle is one less container.
- How does the model discover codecontext tools — register them statically in the tools registry, or proxy MCP `tools/list` at startup?
**Dependencies:** none. Can ship before Batches 510.
-----
### Batch 11b — Architect: repo health (NEW)
**Inspiration / lift:** `spirituslab/codesight` (MIT-ish, TS/Node).
**What it gives BooCode:** complement to Batch 11. Where codecontext answers “what is this codebase,” repo health answers “whats wrong with this codebase.” Call graph, circular dependency detection, dead code flagging.
**Scope:**
- Port codesights `analyze.mjs` analyzer core into `apps/server/src/architect/repo_health.ts`. Drop the VS Code extension shell. Keep:
- Symbol extraction (already overlaps codecontext — call codecontext where possible, only redo whats needed for graph edges).
- Call graph builder (function-to-function edges).
- Circular dependency detector.
- Dead code detector (exported symbols never imported or called).
- New tool: `repo_health(project_id)` returning `{ circular_dependencies: [...], dead_code: [...] }`. Output respects codesights documented false-positive caveats (customElements.define, framework entry points, dynamic imports) — surface those in the tool description so the model doesnt trust dead-code flags blindly.
- Cache results in `boocode_db` keyed by `(project_id, file_hashes)`. Invalidate on file change via file-index hash check.
**Decisions:**
- Build it in-process (Node) vs spawn a CLI? In-process is simpler. Spawn matches codecontext sidecar pattern but adds latency.
**Dependencies:** Batch 11 merged (so we can reuse codecontexts parse output where possible). Can be deferred until after Batches 510.
-----
### Batch 12 — Tool approval gating + plan/act mode
**Inspiration / lift:** `cline/cline` (Apache-2.0).
**What it gives BooCode:** per-session control over which tools the model can call. Lays the groundwork for BooCoder by building the gating mechanism before there are any write tools to gate.
**Scope:**
- New column `sessions.tool_approval_mode TEXT` — values: `read_only` (v1.x default), `plan`, `act_auto`, `act_approve`.
- New column `sessions.approved_tools JSONB` — per-session whitelist for `act_approve` mode.
- Tool registry refactor: tools tagged `read_only` or `write`. In `read_only` mode (v1.x), write tools never appear in the models tools array. In `plan` mode, same — write tools hidden, model produces a plan only. `act_*` modes unlock writes (post-v1.x).
- UI: mode picker in SettingsDrawer (Batch 7 dependency). Inline indicator in chat header.
**Dependencies:** Batch 7 (SettingsDrawer).
-----
### Batch 13 — Append-only event log
**Inspiration / lift:** `OpenHands/OpenHands` V1 (MIT).
**What it gives BooCode:** replaces the ad-hoc `messages` table semantics with a typed event stream. Unlocks rewind, time-travel, and clean handoff semantics for multi-agent flows.
**Scope:**
- New `session_events` table: `(id, session_id, ts, kind, payload JSONB, parent_id)`. Event kinds: `user_message`, `assistant_message`, `tool_call`, `tool_result`, `pane_action`, `mode_change`, `system`.
- Existing `messages` table becomes a derived view over `session_events` for backward compatibility, then deprecated over a release.
- Inference loop emits events instead of mutating message rows.
- Frontend `useSessionStream` reducer rewritten to consume events.
**Migration is non-trivial.** Plan in a dedicated batch with explicit cutover window.
**Dependencies:** Batches 5 (fork/delete) and 7 (settings) merged. Must not be in flight with other backend work.
-----
### Batch 14 — BooCoder: pending changes
**Inspiration / lift:** `plandex-ai/plandex` (MIT).
**What it gives BooCode:** safe write tools. Edits queue in a virtual layer; nothing touches the filesystem until explicit `/apply`.
**Scope:**
- New container `boocoder` at `100.114.205.53:9502`. Owns write tools (`edit_file`, `create_file`, `delete_file`, `apply_pending`, `rewind`).
- New table `pending_changes (id, session_id, file_path, diff TEXT, status, created_at)`. Status: `pending`, `applied`, `rejected`.
- Tools execute against the pending-changes layer, not the filesystem. `apply_pending` is the only path that touches disk. `rewind` rolls back a `pending`-id back to disk state.
- BooCode chat container stays read-only (`/opt:/opt:ro`). BooCoder mounts `/opt/repos:/opt/repos:rw` and uses git worktree pattern from paseo for isolation.
- Frontend: new pane kind `pending_diff` shows the queued diff inline with Approve/Reject per chunk.
**Dependencies:** Batches 12 (gating) + 13 (events). Dont start until both are live.
-----
### Batch 15 — BooCoder runtime isolation
**Inspiration / lift:** `OpenHands/OpenHands` (MIT).
**What it gives BooCode:** per-session Docker sandbox for BooCoder writes. Closes the `/opt:ro` mount risk identified in v1.x open items.
**Scope:**
- Per-session container spawned by BooCoder on first write. Container has only the projects path mounted, not `/opt`.
- Container lifecycle: spawn on first write call, idle-timeout after 30 min, recreate on resume.
- Action execution server pattern: HTTP API inside the container, BooCoder calls in. Standard OpenHands runtime contract.
**Dependencies:** Batch 14.
-----
### Batch 16 — Multi-provider LLM abstraction
**Inspiration / lift:** `earendil-works/pi` `pi-ai` (MIT).
**What it gives BooCode:** optional non-llama-swap inference paths (Anthropic, OpenAI, Mistral direct). Currently we have one provider (llama-swap) and the existing `streamCompletion` is hardcoded to OpenAI-compatible at that endpoint.
**Scope:**
- Provider abstraction: `interface LLMProvider { stream(req): AsyncIterator<Frame> }`.
- Built-in: llama-swap (current), Anthropic, OpenAI (Codex-style).
- Per-session `provider_id` column.
**Status:** **Optional. Skip unless a concrete need surfaces.** llama-swap covers daily driver work.
-----
### Batch 17 — Workflow graphs
**Inspiration / lift:** `microsoft/agent-framework` (MIT) — concepts only.
**What it gives BooCode:** multi-agent coordination. Architect → Coder → Reviewer → Verifier handoffs orchestrated by a YAML-defined workflow.
**Status:** **Far future.** Read agent-frameworks `docs/decisions/` ADRs. Dont port code — Azure/.NET-heavy.
**Dependencies:** Batches 12 (modes), 13 (events). Realistically a v2.x topic.
-----
## Order of operations
Two tracks. Pick one to drive next.
**Track A — Finish v1.x mobile + polish then agents:**
- v1.6.2 ships (in flight)
- **Batch 9 (agents)** — decoupled, can land next; no UI dependency on 5/6/7
- Batches 5, 6, 7, 8 in order. Each is small, frontend-heavy, no architecture risk. Batch 7 absorbs SettingsDrawer agent entry.
**Track B — Begin architect capabilities in parallel:**
- Batch 11 (codecontext sidecar) — biggest single capability jump. Frontend stays the same; new tools appear to the model.
- Batch 11b (repo health) — follow-up.
- Batch 12 (gating) — sets up everything post-v1.x.
Recommendation: ship v1.6.2, then **Batch 9 (agents)** next so the test bed exists before Track A continues. Then Track A through Batch 7. Batch 11 can run in parallel with Batches 810 since 11 has no UI dependency.
-----
## Architecture target state
### Containers
|Container |Port |Mount |Purpose |Status |
|-------------|--------------------------------|--------------------------|------------------------------|--------|
|`boocode` |`100.114.205.53:9500` |`/opt:/opt:ro` |Chat + read-only tools + SPA |Live |
|`boocode_db` |`127.0.0.1:5500` |`boocode_pgdata` volume |Postgres 16-alpine |Live |
|`codecontext`|`100.114.205.53:8765` (internal)|project root :ro |MCP server for architect tools|Batch 11|
|`booterm` |`100.114.205.53:9501` |`/opt/repos:/opt/repos:rw`|Terminals (tmux + node-pty) |Batch 10|
|`boocoder` |`100.114.205.53:9502` |per-session sandbox |Write tools |Batch 14|
### Schema additions
**Batch 9:** `sessions.agent_id TEXT` (nullable; references AGENTS.md by slug).
**Batch 11:** none (codecontext stateless on disk).
**Batch 11b:** `repo_health_cache (project_id, file_hashes_sig, payload JSONB, created_at)`.
**Batch 12:** `sessions.tool_approval_mode`, `sessions.approved_tools`.
**Batch 13:** `session_events`; deprecate `messages` long-tail.
**Batch 14:** `pending_changes`.
-----
## Lift sources (summary)
Full inventory in `boocode_code_review.md`. Headline items:
|Source |Used for |Where |
|--------------------------------------|----------------------------------------|---------------------|
|nmakod/codecontext (MIT, Go) |Architect: codebase map sidecar |Batch 11 |
|spirituslab/codesight (MIT-ish, TS) |Architect: repo health analyzer |Batch 11b |
|Aider-AI/aider (Apache-2.0) |Fallback `.scm` grammars (60+ languages)|Batch 11 (fallback) |
|continuedev/continue (Apache-2.0) |DEFAULT_SECURITY_IGNORE_FILETYPES |Batch 11 prep |
|cline/cline (Apache-2.0) |Plan/Act mode pattern |Batch 12 |
|plandex-ai/plandex (MIT) |Pending-changes data model |Batch 14 |
|OpenHands/OpenHands (MIT) |Event log + sandbox runtime |Batches 13, 15 |
|aimasteracc/tree-sitter-analyzer (MIT)|Outline-first response patterns |Reference |
|earendil-works/pi (MIT) |Multi-provider LLM |Batch 16 (optional) |
|rshah515/claude-code-subagents (MIT) |Reference for builtin agent prompts |Batch 9 (six builtins)|
|microsoft/agent-framework (MIT) |Workflow concepts |Batch 17 (far future)|
-----
## Decisions log
- **Embeddings dropped from BooCode.** Replaced RAG with file-view tools + sidecar analyzers.
- **Original Batch 11 (aider PageRank port) replaced** by codecontext sidecar approach.
- **Original Batch 12 (codebase indexer w/ Harrier) removed** entirely. No embedding infrastructure in BooCode v1.x.
- **Globstar parked** — not an architect tool, future verify-before-commit candidate only.
- **codeprysm rejected** — embedding-based; node/edge taxonomy noted as reference if we ever build our own graph.
- **Batch 9 decoupled from Batch 7 (2026-05-16).** AgentPicker mounts in `ChatInput.tsx` toolbar only. SettingsDrawer agent entry and Header active-agent badge moved to Batch 7. Builtin defaults shipped: six agents (Code Reviewer, Debugger, Refactorer, Architect, Security Auditor, Prompt Builder) with no `model` field — session model wins by default.
-----
## Workflow
Each batch:
1. Verify previous batch merged.
2. Dispatch via Paseo to Claude Code at `/opt/boocode`.
3. Claude Code recon → blocking questions → implement → hand back.
4. Compliance review in separate Claude chat.
5. Deploy: `docker compose up --build -d`.
6. Smoke test.
7. Sam commits and pushes.
Sam reviews all diffs. Sam commits. Never git pull/push/commit on his behalf.