Setup
electron, @modelcontextprotocol/sdk, and @playwright/mcp.
The three trees
server/— the Node runtime (the brain). HTTP server, LLM harness, providers, the tool protocol, handlers, memory, cron.shell/— the classic browser display (onboarding + dev), vanilla HTML/CSS/JS.host/— the Electron Mac host (the product): presence window, native app windows, wallpaper.
CLAUDE.md for the code-level map.
Key files
Conventions
These are enforced across the codebase:- Strict B&W default aesthetic. No emojis, gradients, or color in core UI. Apple-grade. Named themes are the deliberate exceptions. Run the design process before any UI redesign.
- LLM model ids go stale. Before editing
server/providers/*.js, fetch the provider’s live model docs — hardcoded ids rot in months. - Avatar = the
MemojiRendererpresence engine. Extendshell/memoji.js(presets, colors); don’t introduce external avatar libraries. - Provider parity. All providers are first-class; never “optimize for one, adapt the rest.”
- The default file root for AI-created files (no path given) is
.bor/, not the project tree. - Surfaces are sandboxed iframes. All I/O goes through
parent.postMessage→ the bridge, validated server-side. - Audit everything that mutates state. Call
ctx.audit({ kind, … })from handlers.
The LLM harness
The harness isserver/ai.js + server/protocol/ (streaming XML-tool protocol). server/protocol/registry.js is the single source of truth for the tool surface — adding a tool there plus a handler module is all it takes.
Extending BOR
Code style
Match the surrounding code — its comment density, naming, and idioms. Reference code asfile_path:line. The runtime is dependency-light by design; prefer the standard library.