# 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
apps/server + built web
:9500"] BooTerm["booterm container
apps/booterm
:9501"] PG[("boocode_db
Postgres 16
database: boochat
host :5500")] CC["codecontext sidecar
:8080 internal"] end BooCoder["boocoder.service
apps/coder
:9502"] Agents["Host CLI agents
opencode goose claude qwen"] LLM["llama-swap
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
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
CoderPane"] --> Route{"provider?"} Route -->|boocode| Inf["In-process inference
pending_changes queue"] Route -->|external| Task["tasks row
dispatcher poll"] Task --> ACP["ACP dispatch
opencode goose"] Task --> PTY["PTY dispatch
claude qwen"] ACP --> Host["spawn install_path
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