Express 5 + WebSocket server. Orchestrates AI agents, manages build sessions, and handles hardware integration.
- Express 5, TypeScript 5.9, tsx (runtime)
- ws 8 (WebSocket)
- simple-git 3 (git operations)
- serialport 12 (ESP32 communication)
- @anthropic-ai/sdk (Claude API for planner/teaching)
- zod 4 (validation)
npm run dev # Start with tsx watch (port 8000, auto-reload)
npm run start # Production start
npm run test # Vitest (single run)
npm run test:watch # Vitest (watch mode)src/
server.ts Express app, route registration, WebSocket upgrade
routes/
sessions.ts /api/sessions/* endpoints
hardware.ts /api/hardware/* endpoints
services/
orchestrator.ts Central build pipeline controller
metaPlanner.ts ProjectSpec -> task DAG decomposition (Claude API)
agentRunner.ts Runs agents via SDK query() API per task
gitService.ts Per-session git repo init + commits
testRunner.ts pytest execution + coverage parsing
hardwareService.ts ESP32 detect/compile/flash/serial monitor
teachingEngine.ts Concept curriculum, dedup, Claude Sonnet fallback
Build pipeline (managed by Orchestrator):
MetaPlanner.plan(spec)-- Calls Claude (model:claude-opus-4-6) to decompose ProjectSpec into a task DAG with dependencies. Validates for cycles. Retries on parse failure.- Task execution loop -- For each ready task:
AgentRunner.execute(prompt)-- Calls SDKquery()to run agent. Streams output/tokens via async iteration. Timeout: 300s, retries: 2, model:claude-opus-4-6.GitService.commit()-- Commits changes with agent attribution.TeachingEngine.check()-- Surfaces teaching moments (deduped per concept per session). Falls back to Claude Sonnet.
TestRunner.runTests()-- Runspytest tests/ -v --cov=src. Parses output. Timeout: 120s.HardwareService.flash()-- If ESP32 target: detect USB, compile withpy_compile, flash viampremote. Timeout: 60s.
All state is in-memory. No database. Each session gets a temp workspace directory.
- Add the route handler in the appropriate file under
routes/. - Register it in
server.ts. - If it emits WebSocket events, add the event type to the
WSEventunion in the types file. - Update the API Reference.
- Add the role to the
AgentRoletype. - Update
MetaPlannerprompt to understand the new role. - Configure any role-specific behavior in
AgentRunner. - Add a corresponding block type in the frontend if users should be able to select it.