Ship Paseo-equivalent provider snapshot, AgentComposerBar, ACP dispatch rewrite with streaming/persist, permission prompts, and agent commands. Follow-up: pane-scoped chat resolution, CoderMessageList tool timeline, WS user-delta replace, and inference orphan tool_call stripping. Archive openspec v2-2; update CHANGELOG and CURRENT. Co-authored-by: Cursor <cursoragent@cursor.com>
123 lines
4.1 KiB
Markdown
123 lines
4.1 KiB
Markdown
# BooCode architecture
|
|
|
|
Last updated: 2026-05-25. **Navigation:** `AGENTS.md`. **Deep reference:** `CLAUDE.md`.
|
|
|
|
## System overview
|
|
|
|
```mermaid
|
|
flowchart TB
|
|
subgraph client [Browser]
|
|
SPA["apps/web React SPA"]
|
|
end
|
|
|
|
subgraph edge [Edge]
|
|
Caddy --> Authelia
|
|
end
|
|
|
|
subgraph host ["Host 100.114.205.53"]
|
|
subgraph docker [Docker boocode_net]
|
|
BooChat["boocode container<br/>apps/server + built web<br/>:9500"]
|
|
BooTerm["booterm container<br/>apps/booterm<br/>:9501"]
|
|
PG[("boocode_db<br/>Postgres 16<br/>database: boochat<br/>host :5500")]
|
|
CC["codecontext sidecar<br/>:8080 internal"]
|
|
end
|
|
BooCoder["boocoder.service<br/>apps/coder<br/>:9502"]
|
|
Agents["Host CLI agents<br/>opencode goose claude qwen"]
|
|
LLM["llama-swap<br/>100.101.41.16:8401"]
|
|
end
|
|
|
|
Authelia --> SPA
|
|
SPA -->|"HTTP /api WS /api/ws"| BooChat
|
|
SPA -->|"WS /ws/term"| BooTerm
|
|
SPA -->|"HTTP /api/coder proxy<br/>WS direct"| BooCoder
|
|
|
|
BooChat --> PG
|
|
BooTerm --> PG
|
|
BooCoder --> PG
|
|
BooChat -->|"HTTP tools"| CC
|
|
BooChat -->|"streamText"| LLM
|
|
BooCoder -->|"native inference"| LLM
|
|
BooCoder -->|"ACP or PTY spawn"| Agents
|
|
Agents --> LLM
|
|
```
|
|
|
|
## Three surfaces, one database
|
|
|
|
| Surface | Code | Runtime | Primary role |
|
|
|---------|------|---------|--------------|
|
|
| BooChat | `apps/server` + `apps/web` | Docker | Read-only chat, file tools, MCP client, skills |
|
|
| BooTerm | `apps/booterm` + terminal panes in `apps/web` | Docker | tmux + xterm.js PTY panes |
|
|
| BooCoder | `apps/coder` + `CoderPane` in `apps/web` | Host systemd | Write tools, task queue, ACP/PTY agent dispatch |
|
|
|
|
All surfaces share Postgres (`boochat` DB). Cross-surface joins link chats, tasks, and sessions.
|
|
|
|
## BooChat request path
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant U as User
|
|
participant W as apps/web
|
|
participant S as apps/server
|
|
participant DB as Postgres
|
|
participant L as llama-swap
|
|
|
|
U->>W: POST message
|
|
W->>S: /api/sessions/:id/messages
|
|
S->>DB: user + assistant streaming rows
|
|
S->>S: inference.enqueue()
|
|
loop outer step loop
|
|
S->>L: streamText
|
|
L-->>S: deltas / tool calls
|
|
S->>W: WS frames via broker
|
|
opt tool calls
|
|
S->>S: executeToolPhase
|
|
S->>DB: message_parts
|
|
end
|
|
end
|
|
S->>DB: finalize message
|
|
S->>W: session_updated user frame
|
|
```
|
|
|
|
Key modules: `services/inference/turn.ts` (outer loop), `stream-phase.ts` (AI SDK adapter), `tool-phase.ts`, `services/broker.ts`, `hooks/useSessionStream.ts`.
|
|
|
|
## BooCoder execution paths
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
Msg["User message<br/>CoderPane"] --> Route{"provider?"}
|
|
Route -->|boocode| Inf["In-process inference<br/>pending_changes queue"]
|
|
Route -->|external| Task["tasks row<br/>dispatcher poll"]
|
|
Task --> ACP["ACP dispatch<br/>opencode goose"]
|
|
Task --> PTY["PTY dispatch<br/>claude qwen"]
|
|
ACP --> Host["spawn install_path<br/>on host"]
|
|
PTY --> Host
|
|
Inf --> Apply["apply_pending → disk"]
|
|
```
|
|
|
|
Since v2.1.0, BooCoder runs on the host (not Docker). Agent binaries spawn directly — no SSH tunnel.
|
|
|
|
## Supporting services
|
|
|
|
| Service | Reachability | Purpose |
|
|
|---------|--------------|---------|
|
|
| codecontext | `http://codecontext:8080` from Docker network | Code graph / symbol analysis (Go sidecar) |
|
|
| llama-swap | `LLAMA_SWAP_URL` env | Local LLM inference + model props |
|
|
| SearXNG | `SEARXNG_URL` (Tailscale Fathom) | `web_search` / `web_fetch` when enabled |
|
|
| MCP servers | `/data/mcp.json` config | Optional tools (e.g. Context7), read-only in BooChat |
|
|
|
|
## Config and data files
|
|
|
|
| Path | Role |
|
|
|------|------|
|
|
| `data/AGENTS.md` | Global agent registry (bind-mounted `/data/AGENTS.md`) |
|
|
| `data/mcp.json` | MCP server config (opencode-compatible shape) |
|
|
| `data/skills/` | On-demand skill library |
|
|
| `BOOCHAT.md` / `BOOCODER.md` | Container guidance (mtime-cached into system prompt) |
|
|
| `apps/server/src/schema.sql` | Canonical DB schema |
|
|
|
|
## Deploy topology
|
|
|
|
- **BooChat + BooTerm + Postgres + codecontext:** `docker compose up --build -d` from `/opt/boocode`
|
|
- **BooCoder:** `pnpm -C apps/server build && pnpm -C apps/coder build && sudo systemctl restart boocoder`
|
|
- **Ports bind to Tailscale IP** `100.114.205.53`, not `0.0.0.0` — use that IP for host smoke curls
|