90 lines
3.0 KiB
Markdown
90 lines
3.0 KiB
Markdown
# Data Architecture
|
|||
|
|
|
||
|
|
## State Model
|
||
|
|
|
||
|
|
The single source of truth is `AppStateRest` (`src/app/state/rest.rs`):
|
||
|
|
|
||
|
|
```
|
||
|
|
AppStateRest
|
||
|
|
├── session: SessionRuntime (hive_mind state, convergence flag)
|
||
|
|
├── runtime: RuntimeState (mode, provider status)
|
||
|
|
├── chat: ChatState (messages, scroll)
|
||
|
|
├── input: InputState (text, cursor, autocomplete)
|
||
|
|
├── settings: Settings (provider, model, temperature, concise_output)
|
||
|
|
├── config: AppConfig (endpoints, credentials)
|
||
|
|
├── scroll: ScrollState (per-panel offset)
|
||
|
|
├── diff: DiffState (edit review)
|
||
|
|
├── tools: Vec with outputs
|
||
|
|
├── statusline, sidebar, etc.
|
||
|
|
└── toasts: pending notifications
|
||
|
|
```
|
||
|
|
|
||
|
|
**Mutation rules** (per CLAUDE.md):
|
||
|
|
- Mutated in-place from exactly two locations: `actions/mod.rs` (apply_action) and `controller/input.rs` (key handlers)
|
||
|
|
- Read-only from every other module
|
||
|
|
- No generic update function — direct field mutation only
|
||
|
|
|
||
|
|
## Persistence
|
||
|
|
|
||
|
|
### SQLite Message Log (`src/model/msglog/`)
|
||
|
|
|
||
|
|
| File | Purpose |
|
||
|
|
|------|---------|
|
||
|
|
| `schema.rs` | Table definitions (messages, sessions) |
|
||
|
|
| `mod.rs` | CRUD operations |
|
||
|
|
| `query.rs` | Query helpers (search, filter) |
|
||
|
|
| `blobs.rs` | Large message blob storage |
|
||
|
|
| `summary.rs` | Conversation summary cache |
|
||
|
|
|
||
|
|
Schema uses `rusqlite` (bundled) with per-session isolation — each session gets its own database.
|
||
|
|
|
||
|
|
### Memory System (`src/model/memory.rs`)
|
||
|
|
|
||
|
|
File-based memory stored under `~/.claude/projects/<project>/memory/`:
|
||
|
|
|
||
|
|
- Each memory is one markdown file with frontmatter (name, description, type)
|
||
|
|
- Types: `user`, `feedback`, `project`, `reference`
|
||
|
|
- Memory index in MEMORY.md
|
||
|
|
- Export/import for lesson sharing
|
||
|
|
- PID-file session lock prevents concurrent access
|
||
|
|
|
||
|
|
### Settings & Config (`src/model/`)
|
||
|
|
|
||
|
|
| File | Purpose |
|
||
|
|
|------|---------|
|
||
|
|
| `settings.rs` | Serialized user preferences (provider, model, theme) |
|
||
|
|
| `app_config.rs` | Provider endpoints, API key resolution from env |
|
||
|
|
| `session.rs` | Current session metadata |
|
||
|
|
| `conversation.rs` | In-memory conversation state |
|
||
|
|
| `editlog.rs` | Append-only JSONL edit audit trail |
|
||
|
|
|
||
|
|
### Edit Log
|
||
|
|
|
||
|
|
`src/model/editlog.rs` records every file mutation:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{"ts": 123, "tool": "edit", "path": "src/main.rs",
|
||
|
|
"reason": "fix bug", "content_sha256": "abc123",
|
||
|
|
"bytes_delta": 15, "origin": "chat", "session_id": "sess-1"}
|
||
|
|
```
|
||
|
|
|
||
|
|
Max 5000 entries held in memory before pruning oldest.
|
||
|
|
|
||
|
|
## Context Management (`src/app/runtime/context/`)
|
||
|
|
|
||
|
|
| Module | Purpose |
|
||
|
|
|--------|---------|
|
||
|
|
| `tokens.rs` | Token counting via `tiktoken-rs` |
|
||
|
|
| `window.rs` | Token window resolution (fit within model context) |
|
||
|
|
| `dedup.rs` | Deduplication of repeated tool outputs |
|
||
|
|
| `squash.rs` | Compression of large JSON tool results |
|
||
|
|
| `shaping.rs` | Message dropping when context exceeds limits |
|
||
|
|
|
||
|
|
## IPC Data Flow
|
||
|
|
|
||
|
|
```
|
||
|
|
Daemon State ──diff──▶ serialize ──frame──▶ socket ──▶ Client
|
||
|
|
│
|
||
|
|
Client State ◀── apply_diff ◀── deserialize ◀──── socket ─┘
|
||
|
|
```
|