-
Notifications
You must be signed in to change notification settings - Fork 45
Architecture
Elisa is a kid-friendly IDE that orchestrates AI agent teams to build real software and hardware. Kids compose specs using visual blocks (Blockly); the backend decomposes specs into task DAGs, executes them via the Claude Agent SDK, and streams results back in real-time.
Electron main process (electron/main.ts)
|→ Loads API key from encrypted store (OS keychain via safeStorage)
|→ Picks a free port
|→ Starts Express server in-process
|→ Opens BrowserWindow → http://localhost:{port}
frontend/ (React 19 + Vite) backend/ (Express 5 + TypeScript)
+-----------------------+ +---------------------------+
| Blockly Editor | REST | Express Server |
| (BlockCanvas) |---------->| POST /api/sessions/:id/* |
| | | |
| MissionControl | WS | Orchestrator |
| (TaskDAG, CommsFeed, |<---------| → MetaPlanner (Claude) |
| Metrics, Deploy) | events | → AgentRunner (SDK) |
| | | → TestRunner (pytest) |
| BottomBar | | → GitService (simple-git) |
| (Trace, Board, Learn, | | → HardwareService |
| Progress, Health) | | → TeachingEngine |
+-----------------------+ +---------------------------+
|
runs agents via SDK query() API
per task (async streaming)
In production, Express serves everything: /api/* (REST), /ws/* (WebSocket), and /* (built frontend static files). CORS is unnecessary (same-origin). In dev mode, the frontend runs on Vite (port 5173) with proxy to backend (port 8000), and CORS is enabled.
elisa/
package.json Root package: Electron deps, build/dev/dist scripts
electron/ Electron main process, preload, settings dialog
frontend/ React SPA — visual block editor + real-time dashboard
backend/ Express server — orchestration, agents, hardware
scripts/ Build tooling (esbuild backend bundler)
devices/ ESP32 templates and shared MicroPython library
docs/ Documentation (manual, API reference, PRD)
Root package.json manages Electron and build tooling. Frontend and backend remain independent Node.js projects with their own package.json.
1. User arranges blocks in Blockly editor
2. Click GO → blockInterpreter converts workspace to NuggetSpec JSON
3. POST /api/sessions (create) → POST /api/sessions/:id/start (with spec)
4. Backend Orchestrator.run():
a. PLAN: MetaPlanner calls Claude API to decompose spec into task DAG
b. EXECUTE: Streaming-parallel pool (Promise.race, up to 3 concurrent tasks)
Each agent gets: role prompt + task description + context from prior tasks
Agent output streams via SDK → WebSocket events to frontend
Git commit after each completed task (serialized via mutex)
Token budget tracked per agent; warning at 80%, halt on exceed
c. TEST: TestRunner executes pytest, parses results + coverage
d. REVIEW: Optional reviewer agent pass
e. DEPLOY: Surface before_deploy rules as deploy_checklist event
If web: build → find serve dir → start local HTTP server → open browser
If ESP32: compile → flash → serial monitor
If CLI portals: execute via CliPortalAdapter (no shell)
5. session_complete event with summary
Human gates can pause execution at any point, requiring user approval via REST endpoint.
| Channel | Direction | Purpose |
|---|---|---|
| REST | client → server | Commands: create session, start build, gate responses, question answers |
| WebSocket | server → client | Events: task progress, agent output, test results, teaching moments, errors |
WebSocket path: /ws/session/:sessionId
JSON schema produced by blockInterpreter from the Blockly workspace. Drives the entire pipeline. Contains: goal, requirements, style, agents, hardware config, deployment target, workflow flags, skills, rules. Validated server-side via Zod schema.
Directed acyclic graph of tasks with dependencies. Generated by MetaPlanner. Executed in topological order by Orchestrator. Uses Kahn's algorithm (backend/src/utils/dag.ts).
In-memory state for one execution run. Tracks: session ID, phase, tasks, agents, commits, events, teaching moments, test results, token usage. No database — everything lives in memory with optional JSON persistence for crash recovery.
- Builder — Writes source code
- Tester — Writes and runs tests
- Reviewer — Reviews code quality
- Custom — User-defined persona
Each agent runs via the Claude Agent SDK's query() API with role-specific system prompts injected from backend/src/prompts/.
idle → planning → executing → testing → reviewing → deploying → done
^ |
human gates (pause/resume via REST) keep working
|
v
design
- Event-driven UI: All frontend state updates flow through WebSocket event handlers. No polling.
-
Agent isolation: Each agent task runs as a separate SDK
query()call. No shared state between agents except via context summaries. -
Context chain: After each task, a summary is written to
.elisa/context/nugget_context.md. Subsequent agents receive this as input. - Graceful degradation: Missing tools (git, pytest, mpremote, serialport) cause warnings, not crashes.
-
Bearer token auth: Server generates a random auth token on startup. All
/api/*routes (except/api/health) requireAuthorization: Bearer <token>. WebSocket upgrades require?token=<token>. - Content safety: All agent prompts include a Content Safety section enforcing age-appropriate output (ages 8–14). User-controlled placeholder values are sanitized before prompt interpolation.
-
Abort propagation: Orchestrator's AbortController signal is forwarded to each agent's SDK
query()call. -
API key management: In dev, read from
ANTHROPIC_API_KEYenv var. In Electron, encrypted via OS keychain (safeStorage). Child processes receive sanitized env without the API key.
-
Session state: In-memory
Map<sessionId, Session>with optional JSON persistence for crash recovery -
Workspace: Temp directory per session or user-chosen directory. Contains generated code, tests, git repo,
.elisa/metadata. - localStorage: Workspace JSON, skills, and rules auto-saved in browser. Restored on page load.
-
Nugget files:
.elisazip format for export/import (workspace + skills + rules + generated code) - No database
-
npm run build:frontend— Vite builds React SPA intofrontend/dist/ -
npm run build:backend— esbuild bundles Express server intobackend/dist/server-entry.js -
npm run build:electron— tsc compileselectron/main.tsandpreload.ts -
npm run dist— electron-builder packages into installer (NSIS on Windows, DMG on macOS)
Deeper context for each subsystem lives in CLAUDE.md files within each directory:
-
frontend/CLAUDE.md— Frontend architecture, component tree, state management -
backend/CLAUDE.md— Backend architecture, services, API surface -
backend/src/services/CLAUDE.md— Service responsibilities and interactions -
frontend/src/components/CLAUDE.md— Component hierarchy and patterns
Elisa — A kid-friendly IDE for orchestrating AI agent teams