How fourcolors/luna works
1. Overall shape
Luna is a Bun + Effect-TS monorepo organized around a shared server/runtime core and multiple client surfaces. The core business logic lives in packages/core, while apps/* are presentation/entrypoint layers and packages/*-tools expose capabilities to agents over MCP-style tool servers.
2. Primary runtime boundary
The main deployment boundary is the Luna server versus local clients. The server runs the agent/session/memory/workflow machinery and exposes a WebSocket UI/control surface. Clients are the terminal app (apps/agent-cli), the Solid web app (apps/ui-web), and the Tauri desktop widget (apps/ui-moon-tauri).
3. Shared domain core
packages/core holds the durable backend subsystems: session storage, job scheduling, workflow runtime, account brokering, memory, observability, cost accounting, suggested actions, beliefs/alignment, skill registry, secret providers, and provider routing/config. This is the architectural center that everything else composes through Effect layers.
4. Agent execution path
The agent loop is split across packages/chat-service, packages/adapter-sdk, and the packages/core services. Chat requests flow through the chat service into the Anthropic Claude Code Agent SDK bridge, with tool wiring, env overlays, and account/token selection supplied by the broker and secret layers.
5. Account and secret management
Authentication is OAuth-based through Claude Code, not a direct Anthropic API key. AccountBroker manages token rotation and health; secret storage is abstracted through keychain/1Password/file/env backends in packages/core/src/secret-provider. This is a key trust boundary because the client does not own the Claude token lifecycle.
6. Persistence and state
Runtime state is mostly local and SQLite-backed. packages/core/src/db, session, threads, jobs, telemetry, cost-accounting, dream, alignment, and related stores persist durable state under ~/.luna/. Memory uses its own backend abstraction in packages/memory, including SQLite/vector variants and file/in-memory fallbacks.
7. Memory and retrieval
Persistent memory is a separate subsystem surfaced to agents via packages/memory-tools. The memory package provides the storage/retrieval layer, including vector search and bootstrap/maintenance logic, while the tools package turns that into callable agent actions. Local embeddings are supported; chat itself is still cloud Claude.
8. Scheduling and background work
Background behavior is centralized in JobTicker and the worker registry in packages/core/src/jobs. It drains the jobs table and dispatches due work such as prompt, workflow, dream, and wake tasks. This gives the system a single supervised scheduler rather than many ad hoc timers.
9. UI architecture
The UI is multi-surface but shares presentation/state concepts. packages/ui-shared and packages/ui-shared-solid contain reusable components and reducers, while packages/ui-ws provides the WebSocket protocol/server that feeds chat, vault, skills, suggestions, widgets, and workflow galleries to the browser and desktop clients.
10. Desktop widget and web app
apps/ui-moon-tauri is a Rust/Tauri desktop shell with a lightweight floating widget and panels. It talks to the server over the shared WebSocket protocol and is guarded by Tauri capabilities/permissions. apps/ui-web is the browser/Solid app and also hosts some setup flows, install helpers, and chat-server side scripts.
11. CLI and terminal client
apps/agent-cli is the luna terminal client. It covers chat, doctor/preflight, account management, memory, pairing, and recovery flows. It is mostly a thin client over the server WebSocket/API, with local config in ~/.luna/.env and shell/TUI helpers for interactive use.
12. Tooling and external integrations
The repo has many purpose-built tool servers: local shell, memory, scheduler, secret, observability, widget, job-input, and skill tools. packages/connectors adds external app integrations like GitHub, Slack, and Google Workspace via OAuth/store/catalog abstractions. packages/channel* handle message delivery/session mapping for channel integrations.
13. Control and transport boundaries
packages/control-server is a separate control plane from the UI/chat plane. The system uses WebSocket transport for UI communication and explicitly treats it as private-network traffic, typically behind Tailscale. This matters architecturally because the remote server/client pairing and token flow are part of the deployment model, not just app config.
14. Local host/runtime operations
The repo includes concrete deployment scripts for install, server boot, container creation, restart, and release. Stable and dev runtimes are managed separately, often via Incus containers or launchd on macOS, with local state under ~/.luna, ~/.luna-dev, and related runtime paths.
15. Release and verification model
Releases are tag-driven, especially for the Moon desktop app (moon-v* tags). CI and release workflows build, sign, and publish artifacts, while the repo also includes focused smoke tests, deployment verifiers, and boot probes to validate runtime behavior end-to-end.
Main entry points: ui-ws UI WS · src Domain Core · chat-service Chat Service · adapter-sdk Adapter SDK
Components 23
Apps
Client surfaces and entrypoints
- Agent CLI · Bun-based terminal and chat client
apps/agent-cli - UI Web · Browser client and setup surface
apps/ui-web - Moon Tauri · Rust/Tauri widget and panel host
apps/ui-moon-tauri
Core
Shared runtime, domain, and state services
- Session Core · Sessions, threads, and history projection
packages/core/src/session - Job Engine · Ticker, queue, and worker registry
packages/core/src/jobs - Agent Broker · Account brokering, rotation, and spend control
packages/core/src/account-broker - Memory Core · Durable memory storage and retrieval backends
packages/memory - Domain Core · Alignment, beliefs, dream, wake, skills, actions, telemetry, artifacts
packages/core/src - SQLite State · SQLite bootstrap and schema-versioned state store
packages/core/src/db - Secret Provider · Keychain, 1Password, file, env, and login plumbing
packages/core/src/secret-provider - Chat Service · Chat session lifecycle and turn coordination
packages/chat-service - Adapter SDK · Bridge to Claude Code Agent SDK and worker adapters
packages/adapter-sdk - Control Server · Separate private control-plane server
packages/control-server
UI
Shared presentation and transport layers
Tools
MCP-style capability servers
- Shell Tools · Local shell execution tools exposed to agents
packages/local-shell-tools - Memory Tools · Agent-facing memory search and mutation tools
packages/memory-tools - Scheduler Tools · Job and schedule operations exposed as tools
packages/scheduler-tools - Secret Tools · Secret registration and vault actions for agents
packages/secret-tools - Widget Tools · Widget and UI control tools
packages/widget-tools - Connectors · OAuth-backed GitHub, Slack, and Google Workspace integrations
packages/connectors
Ops
Deployment, release, and verification
- Ops Scripts · Server install, container, restart, and release scripts
scripts
Connections 28
- Agent CLI → UI WS: chat/ui · Terminal client talks to the shared websocket surface
- UI Web → UI WS: chat/ui · Browser app consumes websocket frames and setup flows
- Moon Tauri → UI WS: chat/ui · Desktop shell connects over the same protocol
- UI WS → UI Shared: frames · Server emits shared frames into reducers and transport state
- UI Shared → UI Solid: components · Shared state feeds Solid panels and widgets
- UI WS → Chat Service: turns · Chat frames are routed into chat-session orchestration
- Chat Service → Adapter SDK: agent turns · Chat service hands execution to the Claude SDK bridge
- Chat Service → Agent Broker: accounts · Chat orchestration uses brokered account and token selection
- Chat Service → Session Core: sessions · Chat writes and resumes session/thread state
- Adapter SDK → Domain Core: workers · Prompt, dream, wake, and workflow workers depend on shared domain services
- Adapter SDK → Memory Tools: memory · Agent turns can call memory tools through the adapter layer
- Domain Core → SQLite State: state · Durable domain stores persist to SQLite-backed state
- Domain Core → Secret Provider: secrets · Domain services read secret backends through abstraction layers
- Domain Core → Memory Core: retrieval · Persistent memory is a core domain capability
- Domain Core → Job Engine: background · Domain workers are scheduled through the job engine
- Job Engine → Scheduler Tools: tools · Job scheduling is also exposed to agents as a tool surface
- Memory Core → Memory Tools: mcp · Memory storage and search are surfaced through memory tools
- Secret Provider → Secret Tools: mcp · Secret backends are wrapped by secret tool actions
- Job Engine → Domain Core: workers · Ticker dispatches prompt, dream, and wake workers
- Connectors → UI WS: integrations · External account-backed data surfaces are reflected in UI frames
- Control Server → UI WS: control · Separate control plane complements the user-facing websocket plane
- Ops Scripts → Agent CLI: install · Scripts support terminal client and local runtime setup
- Ops Scripts → UI WS: deploy · Scripts boot and restart server/runtime components
- Ops Scripts → Moon Tauri: release · Deployment scripts support desktop packaging and release flows
- Widget Tools → Moon Tauri: widgets · Widget tools back the desktop widget surface
- Shell Tools → Adapter SDK: exec · Local shell capability is available to agent execution flows
- Memory Core → UI WS: search · Memory search and suggestions are broadcast to clients
- Session Core → UI WS: sync · Session and thread state are mirrored into UI views