# bruceyongli/supercalm architecture

> Architecture diagram of the GitHub repository bruceyongli/supercalm, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/bruceyongli/supercalm
- Repository: https://github.com/bruceyongli/supercalm

## Overview

#### Purpose and entry points
Supercalm is a self-hosted Node.js control plane for persistent `claude`, `codex`, and `agy` coding-agent sessions. It serves a browser/PWA dashboard, exposes HTTP/SSE APIs, and mediates human or autonomous responses. Runtime entry is `src/server.js`; operational entry points include `bin/aios`, `bin/install-service`, and `bin/expose`.

#### HTTP server and browser surfaces
`src/server.js` is the loopback HTTP router, static-file host, and SSE endpoint provider. The primary browser shell is `web/app.html` and `web/app.js`; session interaction and terminal/state rendering are concentrated in `web/session.js`, `web/session-viewport.js`, and `web/story-view.js`. Phone-specific use is a separate PWA surface at `web/phone.html` and `web/phone.js`.

Control flow is browser → REST/SSE → server → session/store/agent subsystems. Browser clients receive dashboard changes and raw terminal streams rather than directly accessing tmux.

#### Project, session, and terminal lifecycle
Projects and sessions are modeled and persisted through `src/project_graph.js`, `src/sessions.js`, and `src/session_storage.js`. `src/sessions.js` owns tmux launch, discovery, capture/tailing, keystrokes, input delivery, resizing, and lifecycle polling. It spawns CLI agents in project working directories, creating a hard boundary between the web/API plane and host command execution.

Terminal output is classified by `src/detect.js` and `src/detect_classify.js` into working, waiting-for-input, or exited states. Hook signals from agent CLIs enter through `src/hooks.js`, improving lifecycle precision beyond terminal heuristics.

#### Stateful event and evidence layer
SQLite-backed durable state is centered on `src/store.js`, with session-oriented persistence in `src/session_storage.js` and projected UI/session state in `src/session_projection.js`. Records include projects, sessions, events, messages, and push subscriptions. `src/records.js` and `src/story.js` organize durable session history into reviewable timelines/transcripts.

This boundary allows tmux processes to survive server/browser disconnects while the dashboard can reconstruct current state and historical evidence.

#### Supervisor autonomy pipeline
The supervisor is an opt-in, per-session decision system rooted at `src/agents/supervisor.js`. Its staged control loop spans observation (`src/agents/supervisor/observe.js`), interpretation and decision (`src/agents/supervisor/interpret.js`, `src/agents/supervisor/decide.js`), dispatch/effects (`src/agents/supervisor/dispatch.js`, `src/agents/supervisor/effects.js`), and verification (`src/agents/supervisor/verify.js`).

It applies policy and safety gates before acting: `src/agents/supervisor/event_gate.js`, `src/agents/supervisor/send_policy.js`, and `src/agents/supervisor/context_guard.js`. It retains approved operational judgment and task context via `src/agents/supervisor/project_memory.js` and `src/agents/supervisor/decision_records.js`. The critical boundary is that claimed agent progress must be verified against available terminal, worktree, diff, or other evidence before completion is accepted.

#### Model, voice, and notification integrations
Agent/model selection and optional proxy access are handled by `src/model_providers.js`, `src/model_proxy.js`, and `src/llm.js`; Supercalm consumes external model infrastructure rather than managing the proxy fleet. Optional speech input routes through `src/voice.js`, `src/stt_codex.js`, and `src/spark.js`, which integrate an ffmpeg-assisted recording/transcription flow. TTS is isolated in `src/tts.js` and `src/voice_providers.js`.

Waiting transitions can notify remote devices through `src/push.js` using web-push/VAPID. These integrations are configurable and intended to degrade gracefully when unavailable.

#### Host deployment, safety, and updates
The service requires Node 22+, tmux, and optionally ffmpeg; it binds locally and is intended to be published through Tailscale Serve or an authenticated reverse proxy. Runtime configuration is centralized in `src/config.js`. Deployment and release guardrails live in `src/deploy_orchestrator.js`, `src/deploy_breaker.js`, and `src/update_core.js`; operational wrappers are `bin/deploy` and `bin/update`.

Host-side command execution is constrained by explicit integration and safety layers such as `src/capabilities.js`, `src/db_guard.js`, and `scripts/aios-command-guard.sh`. Git-based update/release flow and local-only binding reinforce the personal, self-hosted trust boundary.

Main entry points: [`src/server.js`](https://github.com/bruceyongli/supercalm/blob/main/src/server.js) (HTTP, static, REST & SSE), [`src/store.js`](https://github.com/bruceyongli/supercalm/blob/main/src/store.js) (Durable SQLite state), [`src/detect.js`](https://github.com/bruceyongli/supercalm/blob/main/src/detect.js) (Terminal state detection), [`src/agents/supervisor/dispatch.js`](https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/dispatch.js) (Dispatch effects)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_browser["Browser surfaces"]
  node_dashboard["Dashboard shell<br/>browser UI<br/>[app.js]"]
  node_session_ui["Session terminal &amp; story UI<br/>browser UI<br/>[session.js]"]
  node_phone["Phone PWA<br/>browser UI<br/>[phone.js]"]
end

subgraph group_control["Control plane"]
  node_server{{"HTTP, static, REST &amp; SSE<br/>Node server<br/>[server.js]"}}
  node_project_graph["Projects &amp; session model<br/>domain model<br/>[project_graph.js]"]
  node_store[("Durable SQLite state<br/>SQLite store<br/>[store.js]")]
  node_session_storage["Session persistence<br/>storage layer<br/>[session_storage.js]"]
  node_projection["UI session projection<br/>state projection"]
  node_story["Reviewable session history<br/>timeline builder<br/>[story.js]"]
  node_deployment["Deploy, update &amp; safety<br/>host operations"]
end

subgraph group_runtime["Session runtime"]
  node_sessions{{"tmux session lifecycle<br/>host execution boundary<br/>[sessions.js]"}}
  node_detection["Terminal state detection<br/>classifier<br/>[detect.js]"]
  node_hooks["Agent hook signals<br/>CLI integration<br/>[hooks.js]"]
end

subgraph group_supervisor["Autonomy pipeline"]
  node_supervisor_core{{"Opt-in supervisor<br/>decision controller<br/>[supervisor.js]"}}
  node_observe["Observe<br/>pipeline stage<br/>[observe.js]"]
  node_decide["Interpret &amp; decide<br/>pipeline stage<br/>[decide.js]"]
  node_safety["Policy &amp; context gates<br/>safety layer<br/>[send_policy.js]"]
  node_dispatch["Dispatch effects<br/>pipeline stage<br/>[dispatch.js]"]
  node_verify["Evidence verification<br/>pipeline stage<br/>[verify.js]"]
end

subgraph group_integrations["Optional integrations"]
  node_models["Model &amp; proxy access<br/>external model adapter<br/>[model_providers.js]"]
  node_voice["Speech input and TTS<br/>voice adapter<br/>[voice.js]"]
  node_push["Remote push notifications<br/>web-push adapter<br/>[push.js]"]
end

node_dashboard -->|"REST/SSE"| node_server
node_session_ui -->|"REST/SSE and terminal stream"| node_server
node_phone -->|"REST/SSE"| node_server
node_server -->|"projects and sessions"| node_project_graph
node_server -->|"session commands"| node_sessions
node_server -->|"dashboard state"| node_projection
node_server -->|"history views"| node_story
node_project_graph -->|"persist"| node_session_storage
node_sessions -->|"terminal output"| node_detection
node_hooks -->|"lifecycle signals"| node_detection
node_session_storage -->|"SQLite records"| node_store
node_store -->|"project current state"| node_projection
node_store -->|"events and messages"| node_story
node_detection -->|"state changes"| node_supervisor_core
node_supervisor_core -->|"observe"| node_observe
node_observe -->|"evidence"| node_decide
node_decide -->|"proposed action"| node_safety
node_safety -->|"approved action"| node_dispatch
node_dispatch -->|"agent input/effects"| node_sessions
node_dispatch -->|"claimed progress"| node_verify
node_verify -->|"verified outcome"| node_store
node_server -.->|"model selection"| node_models
node_server -.->|"speech requests"| node_voice
node_detection -.->|"waiting transition"| node_push
node_deployment -.->|"deploy and update"| node_server

click node_server "https://github.com/bruceyongli/supercalm/blob/main/src/server.js"
click node_dashboard "https://github.com/bruceyongli/supercalm/blob/main/web/app.js"
click node_session_ui "https://github.com/bruceyongli/supercalm/blob/main/web/session.js"
click node_phone "https://github.com/bruceyongli/supercalm/blob/main/web/phone.js"
click node_project_graph "https://github.com/bruceyongli/supercalm/blob/main/src/project_graph.js"
click node_sessions "https://github.com/bruceyongli/supercalm/blob/main/src/sessions.js"
click node_detection "https://github.com/bruceyongli/supercalm/blob/main/src/detect.js"
click node_hooks "https://github.com/bruceyongli/supercalm/blob/main/src/hooks.js"
click node_store "https://github.com/bruceyongli/supercalm/blob/main/src/store.js"
click node_session_storage "https://github.com/bruceyongli/supercalm/blob/main/src/session_storage.js"
click node_projection "https://github.com/bruceyongli/supercalm/blob/main/src/session_projection.js"
click node_story "https://github.com/bruceyongli/supercalm/blob/main/src/story.js"
click node_supervisor_core "https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor.js"
click node_observe "https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/observe.js"
click node_decide "https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/decide.js"
click node_safety "https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/send_policy.js"
click node_dispatch "https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/dispatch.js"
click node_verify "https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/verify.js"
click node_models "https://github.com/bruceyongli/supercalm/blob/main/src/model_providers.js"
click node_voice "https://github.com/bruceyongli/supercalm/blob/main/src/voice.js"
click node_push "https://github.com/bruceyongli/supercalm/blob/main/src/push.js"
click node_deployment "https://github.com/bruceyongli/supercalm/blob/main/src/deploy_orchestrator.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_dashboard,node_session_ui,node_phone toneBlue
class node_server,node_project_graph,node_store,node_session_storage,node_projection,node_story,node_deployment toneAmber
class node_sessions,node_detection,node_hooks toneMint
class node_supervisor_core,node_observe,node_decide,node_safety,node_dispatch,node_verify toneRose
class node_models,node_voice,node_push toneIndigo
```

## Components

### Browser surfaces

- [Dashboard shell](https://github.com/bruceyongli/supercalm/blob/main/web/app.js): browser UI · `web/app.js`
- [Session terminal & story UI](https://github.com/bruceyongli/supercalm/blob/main/web/session.js): browser UI · `web/session.js`
- [Phone PWA](https://github.com/bruceyongli/supercalm/blob/main/web/phone.js): browser UI · `web/phone.js`

### Control plane

- [HTTP, static, REST & SSE](https://github.com/bruceyongli/supercalm/blob/main/src/server.js): Node server · Loopback control-plane entry point. · `src/server.js`
- [Projects & session model](https://github.com/bruceyongli/supercalm/blob/main/src/project_graph.js): domain model · `src/project_graph.js`
- [Durable SQLite state](https://github.com/bruceyongli/supercalm/blob/main/src/store.js): SQLite store · Persists projects, sessions, events, messages, and subscriptions. · `src/store.js`
- [Session persistence](https://github.com/bruceyongli/supercalm/blob/main/src/session_storage.js): storage layer · `src/session_storage.js`
- [UI session projection](https://github.com/bruceyongli/supercalm/blob/main/src/session_projection.js): state projection · `src/session_projection.js`
- [Reviewable session history](https://github.com/bruceyongli/supercalm/blob/main/src/story.js): timeline builder · `src/story.js`
- [Deploy, update & safety](https://github.com/bruceyongli/supercalm/blob/main/src/deploy_orchestrator.js): host operations · Applies deployment and release guardrails. · `src/deploy_orchestrator.js`

### Session runtime

- [tmux session lifecycle](https://github.com/bruceyongli/supercalm/blob/main/src/sessions.js): host execution boundary · Launches and controls CLI agents in project directories. · `src/sessions.js`
- [Terminal state detection](https://github.com/bruceyongli/supercalm/blob/main/src/detect.js): classifier · `src/detect.js`
- [Agent hook signals](https://github.com/bruceyongli/supercalm/blob/main/src/hooks.js): CLI integration · `src/hooks.js`

### Autonomy pipeline

- [Opt-in supervisor](https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor.js): decision controller · `src/agents/supervisor.js`
- [Observe](https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/observe.js): pipeline stage · `src/agents/supervisor/observe.js`
- [Interpret & decide](https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/decide.js): pipeline stage · `src/agents/supervisor/decide.js`
- [Policy & context gates](https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/send_policy.js): safety layer · `src/agents/supervisor/send_policy.js`
- [Dispatch effects](https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/dispatch.js): pipeline stage · `src/agents/supervisor/dispatch.js`
- [Evidence verification](https://github.com/bruceyongli/supercalm/blob/main/src/agents/supervisor/verify.js): pipeline stage · Requires terminal, worktree, diff, or other evidence before accepting completion. · `src/agents/supervisor/verify.js`

### Optional integrations

- [Model & proxy access](https://github.com/bruceyongli/supercalm/blob/main/src/model_providers.js): external model adapter · `src/model_providers.js`
- [Speech input and TTS](https://github.com/bruceyongli/supercalm/blob/main/src/voice.js): voice adapter · Optional ffmpeg-assisted transcription and speech output. · `src/voice.js`
- [Remote push notifications](https://github.com/bruceyongli/supercalm/blob/main/src/push.js): web-push adapter · `src/push.js`

## Connections

- Dashboard shell → HTTP, static, REST & SSE: REST/SSE
- Session terminal & story UI → HTTP, static, REST & SSE: REST/SSE and terminal stream
- Phone PWA → HTTP, static, REST & SSE: REST/SSE
- HTTP, static, REST & SSE → Projects & session model: projects and sessions
- HTTP, static, REST & SSE → tmux session lifecycle: session commands
- HTTP, static, REST & SSE → UI session projection: dashboard state
- HTTP, static, REST & SSE → Reviewable session history: history views
- Projects & session model → Session persistence: persist
- tmux session lifecycle → Terminal state detection: terminal output
- Agent hook signals → Terminal state detection: lifecycle signals
- Session persistence → Durable SQLite state: SQLite records
- Durable SQLite state → UI session projection: project current state
- Durable SQLite state → Reviewable session history: events and messages
- Terminal state detection → Opt-in supervisor: state changes
- Opt-in supervisor → Observe: observe
- Observe → Interpret & decide: evidence
- Interpret & decide → Policy & context gates: proposed action
- Policy & context gates → Dispatch effects: approved action
- Dispatch effects → tmux session lifecycle: agent input/effects
- Dispatch effects → Evidence verification: claimed progress
- Evidence verification → Durable SQLite state: verified outcome
- HTTP, static, REST & SSE → Model & proxy access: model selection
- HTTP, static, REST & SSE → Speech input and TTS: speech requests
- Terminal state detection → Remote push notifications: waiting transition
- Deploy, update & safety → HTTP, static, REST & SSE: deploy and update
