- MCP secrets: substituteEnvVars recursively resolves {env:NAME} in mcp.json string values from process.env before Zod (opencode-compatible); unset -> '' + boot warning, and invalid-config log names the unset vars (an empty {env:VAR} in a strict url/command field invalidates the whole config)
- data/mcp.json now untracked (.gitignore flips !data/mcp.json -> !data/mcp.example.json); tracked template data/mcp.example.json carries "{env:CONTEXT7_API_KEY}"; .env.example documents the key (9 mcp-config tests)
- Coder fix: message_complete frame model widened string -> string|null (server+web ws-frames parity); dispatcher publishes model: task.model at all 4 external completion points — a null model otherwise fail-closed in publishFrame and dropped the whole frame incl. status:'complete' (regression test)
- Coder fix: claude-sdk mapUserToolResults maps user-message tool_result blocks -> terminal tool_update events (completed/failed w/ output) so tool snapshots resolve instead of spinning forever
- Composer: AgentComposerBar drops §9b resumed/history/new chip + token readout, loses flex-wrap so the row stays one line; CoderPane gains a per-chat localStorage agent-config cache (restores last model on reopen) + threads model into the timeline/chip
- Docs: root CLAUDE.md slimmed (~190 lines), per-app refs split to apps/{coder,server,web}/CLAUDE.md; new docs/coder-backends.md, docs/project-discovery.md, docs/coding-standards/ (cross-app-contract-parity); ARCHITECTURE.md links the backends doc
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.9 KiB
8.9 KiB
Project Discovery
Auto-generated stack / tooling / command inventory for the BooCode repository. Static reference for skills, agents, and contributors. Deep engineering notes live in the root and per-app
CLAUDE.mdfiles; this file is the factual "what's installed and how to run it" map.
Repository
- type: pnpm monorepo (workspaces
apps/*+apps/coder/web) - package manager: pnpm 10.15.1 (root
package.jsonpackageManager) - lock file:
pnpm-lock.yaml - workspace config:
pnpm-workspace.yaml - shared TS config:
tsconfig.base.json(ES2022 target, strict,noUncheckedIndexedAccess,isolatedModules) - languages: TypeScript (all Node packages), Go 1.24 (codecontext sidecar)
- database: PostgreSQL 16 (single
boochatDB; two schema files applied idempotently —apps/server/src/schema.sql+apps/coder/src/schema.sql) - members: 5 Node packages (
@boocode/server,@boocode/web,@boocode/coder,@boocode/coder-web,@boocode/booterm) + 1 Go sidecar (codecontext/) - cross-workspace dep:
@boocode/coder→@boocode/server(workspace:*); server must build first (emits.d.tsfor consumers) - build order: server → coder → web/booterm (independent) → codecontext (Docker, Go)
Repository-level
Documentation
- primary guidance:
CLAUDE.md(root, tracked) + per-appapps/server/CLAUDE.md,apps/coder/CLAUDE.md,apps/web/CLAUDE.md(lazy-loaded per subtree) - overview:
README.md - release log:
CHANGELOG.md(per-tag, newest-first) - system prompts:
BOOCHAT.md,BOOCODER.md(bind-mounted into containers) - architecture:
docs/ARCHITECTURE.md(system diagram + overview) - planning docs:
docs/codecontext-ts-plan.md,docs/DEFERRED-WORK.md,docs/STALE-DEPRECATED.md,docs/themes_v1.md,docs/superpowers/plans/ - specs/design:
openspec/README.md(convention) +openspec/changes/<slug>/{proposal,tasks,design}.md; shipped batches snapshot underopenspec/changes/archived/
Agent registry & skills
- agent registry:
data/AGENTS.md(tracked; parsed — each## <Name>+---frontmatter fence is one agent) - skills:
data/skills/<vendor>/(each skill =SKILL.md+ optionaleval.yaml); vendors includeboocode/(committing-changes,improving-boocode-guidance,systematic-debugging,using-worktrees),anthropics/,superpowers/,mattpocock/, others
Infrastructure
- container build:
Dockerfile(root — boocode = server + web;node:20-alpinebuilder + runtime; runtime adds ripgrep/git/ssh) - container build:
apps/booterm/Dockerfile(node:20-alpinebuilder →node:20-bookworm-slimruntime for node-pty libc parity) - container build:
codecontext/Dockerfile(golang:1.24-alpine→alpine:3.20) - container build:
apps/coder/Dockerfile(present but unused — BooCoder now runs via host systemd, not Docker) - orchestration:
docker-compose.yml— servicesboocode(:9500),booterm(:9501),boocode_db(postgres:16-alpine, host :5500),codecontext(internal :8080);boocoderservice commented out (moved to host systemdboocoder.service, :9502) - CI/CD: none in repo (
.github/workflows,.gitea,.gitlab-ci.ymlabsent); deploy is manual (docker compose up --build -d; boocoder viapnpm build+sudo systemctl restart boocoder) - git hooks: none committed (
.git/hooks/has only.sample); a host-sidesecurity_reminder_hook.pyis referenced but not in-repo - ADRs: no dedicated directory; decisions live inline in
CLAUDE.mdfiles,docs/ARCHITECTURE.md, andopenspec/changes/*/design.md - linters/formatters: none configured (no eslint/prettier/stylelint config)
Environment & configuration
- env file:
.env(gitignored) /.env.example(tracked template) - boocoder host env:
apps/coder/.env.host - config template:
data/mcp.example.json(tracked) — livedata/mcp.jsonis gitignored; secrets live in.envand resolve via{env:VAR}substitution (e.g.CONTEXT7_API_KEY) - config template:
data/coder-providers.example.json(tracked) — livedata/coder-providers.jsonis gitignored (runtime, read+written on UI toggles)
Projects
boocode (root coordinator) — /
- manifest:
package.json - role: pnpm workspace root; coordinates dev/build across members
- install:
pnpm install - dev:
pnpm dev:server(tsx watch, :3000),pnpm dev:web(Vite, :5173) - build:
pnpm build(web then server) - start:
pnpm start(node apps/server/dist/index.js) - typecheck:
npx tsc --noEmit(project references; per-apptscis authoritative)
@boocode/server — apps/server/
- manifest:
apps/server/package.json - runtime: Node.js + TypeScript
- frameworks: Fastify ^4.28.1 (+
@fastify/websocket^10,@fastify/static^7); postgres ^3.4.4 (porsager, tagged-template SQL, no ORM); Vercel AI SDK —ai^6 +@ai-sdk/openai-compatible^2 (llama-swap); Zod ^3;@modelcontextprotocol/sdk^1.29 - build:
pnpm -C apps/server build(tsc+ copyschema.sql→dist/) — authoritative for server code - dev:
pnpm -C apps/server dev(tsx watch) - typecheck:
pnpm -C apps/server typecheck - test:
pnpm -C apps/server test(vitest run) - tsconfig:
apps/server/tsconfig.json(NodeNext,declaration: truefor workspace consumers;exportsmap withtypesconditions) - test config:
apps/server/vitest.config.ts(vitest ^3.2.4, env=node,globals: false,fileParallelism: false) - test pattern:
src/**/__tests__/**/*.test.ts - DB-integration tests: opt-in via
DATABASE_URL='postgres://boocode:devpass@localhost:5500/boochat' pnpm -C apps/server test
@boocode/web — apps/web/
- manifest:
apps/web/package.json - runtime: Node.js + TypeScript (browser SPA; also hosts the BooCoder pane)
- frameworks: React ^18.3.1 + React DOM; React Router v6.26.0; Tailwind v4.3.0 (+
@tailwindcss/postcss); shadcn/radix-ui primitives; Shiki ^1.29 (highlighting);@xterm/xterm5.5 (+ addons fit/web-links/webgl); Vite ^5.3.4 (+@vitejs/plugin-react) - build:
pnpm -C apps/web build(tsc -b+vite build) - dev:
pnpm -C apps/web dev(Vite, :5173) - preview:
pnpm -C apps/web preview - typecheck:
pnpm -C apps/web typecheck(tsc -b --noEmit) — ornpx tsc -p apps/web/tsconfig.app.json --noEmit - tests: none (no test harness by design)
- tsconfig:
apps/web/tsconfig.json(composite refs) +apps/web/tsconfig.app.json(Bundler resolution,react-jsx, path alias@/→src/*) - dev config:
apps/web/vite.config.ts(proxy order:/api/term+/ws/term→ :9501,/api/coder→ :9502,/api→ :3000)
@boocode/coder — apps/coder/
- manifest:
apps/coder/package.json - runtime: Node.js + TypeScript; runs as host systemd service (
boocoder.service, :9502), postgres at127.0.0.1:5500 - frameworks: Fastify ^4.28.1 (+
@fastify/websocket); postgres ^3.4.4; agent SDKs —@agentclientprotocol/sdk^0.22,@anthropic-ai/claude-agent-sdk^0.3,@opencode-ai/sdk~1.15 (imported via@opencode-ai/sdk/v2/client);@modelcontextprotocol/sdk^1.29;@boocode/server(workspace:*) - build:
pnpm -C apps/coder build(tsc+ copyschema.sql) — requires server built first - dev:
pnpm -C apps/coder dev(tsx watch) - cli:
pnpm -C apps/coder cli(tsx src/cli.ts) - typecheck:
pnpm -C apps/coder typecheck - test:
pnpm -C apps/coder test(vitest run) - deploy:
pnpm -C apps/server build && pnpm -C apps/coder build && sudo systemctl restart boocoder - tsconfig:
apps/coder/tsconfig.json(NodeNext,declaration: false) - test config:
apps/coder/vitest.config.ts(vitest ^3.0.0, env=node,globals: false,fileParallelism: false) - test pattern:
src/**/__tests__/**/*.test.ts
@boocode/coder-web — apps/coder/web/
- manifest:
apps/coder/web/package.json - runtime: Node.js + TypeScript; standalone fallback SPA served at :9502 (primary coder UI is the pane in
@boocode/web) - frameworks: React ^18.3.1 + React Router v6.26.0 + Tailwind v4.3.0 + Vite ^5.3.4
- dev config:
apps/coder/web/vite.config.ts(port 5174; proxies/api→http://127.0.0.1:3000)
@boocode/booterm — apps/booterm/
- manifest:
apps/booterm/package.json - runtime: Node.js + TypeScript; Docker container (:9501, bookworm-slim+glibc)
- frameworks: Fastify ^4.28.1 (+
@fastify/websocket); node-pty ^1.0.0;pg^8.13 (session persistence); tmux (per-sessionbc-<sid>) - build:
pnpm -C apps/booterm build(tsconly) - dev:
pnpm -C apps/booterm dev(tsx watch) - typecheck:
pnpm -C apps/booterm typecheck - tests: none
- tsconfig:
apps/booterm/tsconfig.json(NodeNext,declaration: false)
codecontext shim — codecontext/
- manifest:
codecontext/go.mod - runtime: Go 1.24; standalone binary, MCP stdio↔HTTP adapter (NDJSON framing); Docker sidecar at
http://codecontext:8080/v1/<tool_name> - source: single
shim.go; wraps the CodeContext fork staged viacodecontext/fork.tar.gz(gitignored; fork repo at/opt/forks/codecontext/, branchboocode-ts) - build:
go build ./...(use/snap/go/current/bin/go); built into the container in Docker - test:
go test ./...