# latent-spaces/sottochat architecture

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

- Interactive diagram: https://gitdiagram.com/latent-spaces/sottochat
- Repository: https://github.com/latent-spaces/sottochat

## Overview

sottochat is a local, read-only companion for long-running Claude Code, Claude app, and Codex sessions. Its main workflow discovers sessions, tails and parses their transcripts, groups events into turns, then serves a live inbox and per-session Q&A where developers can prepare copyable replies. Separate branches provide background turn summaries, authentication guidance, settings, persisted chat state, and token accounting. The supplied source excerpts and index establish the server’s dependencies, but do not expose every route or runtime callback; uncertain links are omitted.

Main entry points: [`src/server.ts`](https://github.com/latent-spaces/sottochat/blob/main/src/server.ts) (HTTP + WS server), [`src/tailer.ts`](https://github.com/latent-spaces/sottochat/blob/main/src/tailer.ts) (Transcript tailer), [`src/registry.ts`](https://github.com/latent-spaces/sottochat/blob/main/src/registry.ts) (Session registry), [`src/claude-discovery.ts`](https://github.com/latent-spaces/sottochat/blob/main/src/claude-discovery.ts) (Claude discovery)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_discovery["Session discovery"]
  node_registry["Session registry<br/>[registry.ts]"]
  node_claude_discovery["Claude discovery"]
  node_codex_discovery["Codex discovery<br/>[codex-discovery.ts]"]
  node_processes["Process discovery"]
end

subgraph group_transcripts["Transcript processing"]
  node_transcripts[("Local transcripts")]
  node_tailer["Transcript tailer<br/>[tailer.ts]"]
  node_claude_parser["Claude JSONL parser<br/>[jsonl.ts]"]
  node_codex_parser["Codex JSONL parser<br/>[codex-jsonl.ts]"]
  node_turns["Turn grouping<br/>[turns.ts]"]
end

subgraph group_experience["Developer experience"]
  node_browser["Browser UI<br/>[app.js]"]
  node_settings_ui["Settings UI<br/>[settings.js]"]
  node_reply_card["Reply card<br/>[to-agent.js]"]
  node_chat["Session Q&amp;A<br/>[chat-agent.ts]"]
  node_static_assets["Static asset serving<br/>[static-assets.ts]"]
end

subgraph group_runtime["Runtime services"]
  node_server["HTTP + WS server<br/>[server.ts]"]
  node_observer["Background summaries<br/>[observer.ts]"]
  node_settings["Settings<br/>[settings.ts]"]
  node_auth["Claude auth<br/>[auth-check.ts]"]
  node_persistence[("Chat persistence<br/>[persistence.ts]")]
  node_usage[("Usage ledger<br/>[usage-ledger.ts]")]
end

node_developer(("Developer"))
node_anthropic["Anthropic SDK"]

node_developer -->|"uses"| node_browser
node_browser -->|"requests state"| node_server
node_settings_ui -->|"updates settings"| node_server
node_server -->|"serves assets"| node_static_assets
node_server -->|"refreshes sessions"| node_registry
node_registry -->|"queries"| node_claude_discovery
node_registry -->|"queries"| node_codex_discovery
node_claude_discovery -->|"checks processes"| node_processes
node_codex_discovery -->|"checks processes"| node_processes
node_claude_discovery -->|"finds sessions"| node_transcripts
node_codex_discovery -->|"finds sessions"| node_transcripts
node_server -->|"starts tailing"| node_tailer
node_tailer -->|"reads files"| node_transcripts
node_tailer -->|"parses records"| node_claude_parser
node_tailer -->|"parses records"| node_codex_parser
node_server -->|"groups events"| node_turns
node_turns -->|"uses event types"| node_claude_parser
node_server -->|"sends questions"| node_chat
node_chat -->|"queries model"| node_anthropic
node_server -->|"feeds summaries"| node_observer
node_observer -->|"queries model"| node_anthropic
node_observer -->|"records usage"| node_usage
node_chat -->|"records usage"| node_usage
node_server -->|"reads and saves"| node_settings
node_server -->|"loads sessions"| node_persistence
node_server -->|"checks credentials"| node_auth
node_browser -->|"prepares reply"| node_reply_card
node_developer -->|"copies reply"| node_reply_card

click node_browser "https://github.com/latent-spaces/sottochat/blob/main/public/assets/app.js"
click node_settings_ui "https://github.com/latent-spaces/sottochat/blob/main/public/assets/settings.js"
click node_reply_card "https://github.com/latent-spaces/sottochat/blob/main/public/assets/to-agent.js"
click node_server "https://github.com/latent-spaces/sottochat/blob/main/src/server.ts"
click node_registry "https://github.com/latent-spaces/sottochat/blob/main/src/registry.ts"
click node_claude_discovery "https://github.com/latent-spaces/sottochat/blob/main/src/claude-discovery.ts"
click node_codex_discovery "https://github.com/latent-spaces/sottochat/blob/main/src/codex-discovery.ts"
click node_processes "https://github.com/latent-spaces/sottochat/blob/main/src/process-discovery.ts"
click node_tailer "https://github.com/latent-spaces/sottochat/blob/main/src/tailer.ts"
click node_claude_parser "https://github.com/latent-spaces/sottochat/blob/main/src/jsonl.ts"
click node_codex_parser "https://github.com/latent-spaces/sottochat/blob/main/src/codex-jsonl.ts"
click node_turns "https://github.com/latent-spaces/sottochat/blob/main/src/turns.ts"
click node_chat "https://github.com/latent-spaces/sottochat/blob/main/src/chat-agent.ts"
click node_observer "https://github.com/latent-spaces/sottochat/blob/main/src/observer.ts"
click node_settings "https://github.com/latent-spaces/sottochat/blob/main/src/settings.ts"
click node_auth "https://github.com/latent-spaces/sottochat/blob/main/src/auth-check.ts"
click node_persistence "https://github.com/latent-spaces/sottochat/blob/main/src/persistence.ts"
click node_usage "https://github.com/latent-spaces/sottochat/blob/main/src/usage-ledger.ts"
click node_static_assets "https://github.com/latent-spaces/sottochat/blob/main/src/static-assets.ts"

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_registry,node_claude_discovery,node_codex_discovery,node_processes toneBlue
class node_transcripts,node_tailer,node_claude_parser,node_codex_parser,node_turns toneAmber
class node_browser,node_settings_ui,node_reply_card,node_chat,node_static_assets toneMint
class node_server,node_observer,node_settings,node_auth,node_persistence,node_usage toneRose
class node_developer,node_anthropic toneIndigo
```

## Components

### Session discovery

- [Session registry](https://github.com/latent-spaces/sottochat/blob/main/src/registry.ts): `src/registry.ts`
- [Claude discovery](https://github.com/latent-spaces/sottochat/blob/main/src/claude-discovery.ts): `src/claude-discovery.ts`
- [Codex discovery](https://github.com/latent-spaces/sottochat/blob/main/src/codex-discovery.ts): `src/codex-discovery.ts`
- [Process discovery](https://github.com/latent-spaces/sottochat/blob/main/src/process-discovery.ts): `src/process-discovery.ts`

### Transcript processing

- **Local transcripts**
- [Transcript tailer](https://github.com/latent-spaces/sottochat/blob/main/src/tailer.ts): `src/tailer.ts`
- [Claude JSONL parser](https://github.com/latent-spaces/sottochat/blob/main/src/jsonl.ts): `src/jsonl.ts`
- [Codex JSONL parser](https://github.com/latent-spaces/sottochat/blob/main/src/codex-jsonl.ts): `src/codex-jsonl.ts`
- [Turn grouping](https://github.com/latent-spaces/sottochat/blob/main/src/turns.ts): `src/turns.ts`

### Developer experience

- [Browser UI](https://github.com/latent-spaces/sottochat/blob/main/public/assets/app.js): `public/assets/app.js`
- [Settings UI](https://github.com/latent-spaces/sottochat/blob/main/public/assets/settings.js): `public/assets/settings.js`
- [Reply card](https://github.com/latent-spaces/sottochat/blob/main/public/assets/to-agent.js): `public/assets/to-agent.js`
- [Session Q&A](https://github.com/latent-spaces/sottochat/blob/main/src/chat-agent.ts): `src/chat-agent.ts`
- [Static asset serving](https://github.com/latent-spaces/sottochat/blob/main/src/static-assets.ts): `src/static-assets.ts`

### Runtime services

- [HTTP + WS server](https://github.com/latent-spaces/sottochat/blob/main/src/server.ts): `src/server.ts`
- [Background summaries](https://github.com/latent-spaces/sottochat/blob/main/src/observer.ts): `src/observer.ts`
- [Settings](https://github.com/latent-spaces/sottochat/blob/main/src/settings.ts): `src/settings.ts`
- [Claude auth](https://github.com/latent-spaces/sottochat/blob/main/src/auth-check.ts): `src/auth-check.ts`
- [Chat persistence](https://github.com/latent-spaces/sottochat/blob/main/src/persistence.ts): `src/persistence.ts`
- [Usage ledger](https://github.com/latent-spaces/sottochat/blob/main/src/usage-ledger.ts): `src/usage-ledger.ts`

### Other components

- **Developer**
- **Anthropic SDK**

## Connections

- Developer → Browser UI: uses (evidence: `README.md`)
- Browser UI → HTTP + WS server: requests state (evidence: `README.md`)
- Settings UI → HTTP + WS server: updates settings (evidence: `README.md`)
- HTTP + WS server → Static asset serving: serves assets (evidence: `src/server.ts`)
- HTTP + WS server → Session registry: refreshes sessions (evidence: `src/server.ts`)
- Session registry → Claude discovery: queries (evidence: `src/registry.ts`)
- Session registry → Codex discovery: queries (evidence: `src/registry.ts`)
- Claude discovery → Process discovery: checks processes (evidence: `src/claude-discovery.ts`)
- Codex discovery → Process discovery: checks processes (evidence: `src/codex-discovery.ts`)
- Claude discovery → Local transcripts: finds sessions (evidence: `README.md`)
- Codex discovery → Local transcripts: finds sessions (evidence: `README.md`)
- HTTP + WS server → Transcript tailer: starts tailing (evidence: `src/server.ts`)
- Transcript tailer → Local transcripts: reads files (evidence: `src/tailer.ts`)
- Transcript tailer → Claude JSONL parser: parses records (evidence: `src/tailer.ts`)
- Transcript tailer → Codex JSONL parser: parses records (evidence: `src/tailer.ts`)
- HTTP + WS server → Turn grouping: groups events (evidence: `src/server.ts`)
- Turn grouping → Claude JSONL parser: uses event types (evidence: `src/turns.ts`)
- HTTP + WS server → Session Q&A: sends questions (evidence: `src/server.ts`)
- Session Q&A → Anthropic SDK: queries model (evidence: `src/chat-agent.ts`)
- HTTP + WS server → Background summaries: feeds summaries (evidence: `src/server.ts`)
- Background summaries → Anthropic SDK: queries model (evidence: `src/observer.ts`)
- Background summaries → Usage ledger: records usage (evidence: `src/observer.ts`)
- Session Q&A → Usage ledger: records usage (evidence: `src/chat-agent.ts`)
- HTTP + WS server → Settings: reads and saves (evidence: `src/server.ts`)
- HTTP + WS server → Chat persistence: loads sessions (evidence: `src/server.ts`)
- HTTP + WS server → Claude auth: checks credentials (evidence: `src/server.ts`)
- Browser UI → Reply card: prepares reply (evidence: `README.md`)
- Developer → Reply card: copies reply (evidence: `README.md`)
