Architecture
This document explains how Lore captures, stores, and links AI coding sessions.
Overview
Section titled “Overview”┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐│ AI Tools │ │ Lore │ │ Git Repo ││ │ │ │ │ ││ Claude Code │────▶│ Watchers │ │ .git/ ││ Aider │ │ (parsers) │ │ ││ Gemini CLI │ │ │ │ │ ││ Continue.dev │ │ ▼ │ │ ││ Cline │ │ SQLite DB │◀───▶│ Commits ││ ... │ │ (sessions, │ │ │└─────────────────┘ │ messages, │ └─────────────────┘ │ links) │ └─────────────────┘Components
Section titled “Components”Watchers
Section titled “Watchers”Each supported AI tool has a dedicated watcher that knows how to:
- Find session files on disk
- Parse the tool’s specific format (JSONL, JSON, Markdown)
- Extract messages with roles, timestamps, and content
- Convert to Lore’s internal data model
Watchers implement a common trait:
pub trait Watcher { fn name(&self) -> &str; fn session_paths(&self) -> Vec<PathBuf>; fn parse_session(&self, path: &Path) -> Result<Session>;}New tools can be supported by implementing this trait.
Storage
Section titled “Storage”Lore uses SQLite for all persistent storage:
~/.lore/├── lore.db # SQLite database├── config.yaml # User configuration└── logs/ # Daemon logsDatabase Schema
Section titled “Database Schema”sessions - Core session data
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| tool | TEXT | Tool name (e.g., “claude-code”) |
| tool_version | TEXT | Tool version if available |
| model | TEXT | AI model used |
| started_at | DATETIME | Session start time |
| ended_at | DATETIME | Session end time |
| working_directory | TEXT | Project directory |
| git_branch | TEXT | Active branch |
| message_count | INT | Number of messages |
| source_path | TEXT | Original file path (for dedup) |
| machine_id | UUID | Machine identifier |
messages - Conversation content
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| session_id | UUID | Foreign key to sessions |
| parent_id | UUID | For threaded conversations |
| role | TEXT | user, assistant, system |
| content | JSON | Message content (text, tool use, etc.) |
| timestamp | DATETIME | Message time |
| message_index | INT | Order in conversation |
session_links - Commit associations
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| session_id | UUID | Foreign key to sessions |
| commit_sha | TEXT | Git commit SHA |
| link_type | TEXT | commit, branch, remote |
| confidence | FLOAT | Auto-link confidence (0-1) |
| created_by | TEXT | user, auto, hook |
Additional tables: tags, annotations, summaries, machines, messages_fts (full-text search)
Full-Text Search
Section titled “Full-Text Search”Message content is indexed using SQLite FTS5:
CREATE VIRTUAL TABLE messages_fts USING fts5( content, content='messages', content_rowid='rowid');This enables fast full-text queries across all sessions:
lore search "authentication middleware"Daemon
Section titled “Daemon”The background daemon uses:
- notify crate for file system events
- tokio async runtime for concurrent watching
- Unix socket for IPC with CLI commands
┌─────────────────────────────────────────────────┐│ Daemon ││ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Watcher │ │ Watcher │ │ Watcher │ .. ││ │ claude │ │ aider │ │ gemini │ ││ └────┬─────┘ └────┬─────┘ └────┬─────┘ ││ │ │ │ ││ └─────────────┼─────────────┘ ││ │ ││ ▼ ││ ┌────────────┐ ││ │ Importer │ ││ └─────┬──────┘ ││ │ ││ ▼ ││ ┌────────────┐ ││ │ Database │ ││ └────────────┘ │└─────────────────────────────────────────────────┘The daemon:
- Watches directories for all enabled tools
- Debounces rapid file changes
- Incrementally parses only new content
- Updates session git_branch when it changes
MCP Server
Section titled “MCP Server”The MCP (Model Context Protocol) server exposes Lore data to AI tools:
┌─────────────────┐ stdio ┌─────────────────┐│ Claude Code │◀──────────────▶│ Lore MCP ││ (or other │ JSON-RPC │ Server ││ MCP client) │ │ │└─────────────────┘ └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Database │ └─────────────────┘Tools exposed via MCP:
lore_search- Full-text searchlore_get_session- Get session by IDlore_list_sessions- List with filterslore_get_context- Recent sessions for repolore_get_linked_sessions- Sessions for a commit
Data Flow
Section titled “Data Flow”Import Flow
Section titled “Import Flow”1. User runs: lore import2. Registry returns enabled watchers3. Each watcher scans for session files4. Parser converts tool format → internal model5. Deduplication check (by source_path)6. Insert session + messages into database7. FTS index updated automaticallyLink Flow
Section titled “Link Flow”1. User runs: lore link abc123 --commit HEAD2. Resolve session ID prefix → full UUID3. Resolve git ref → commit SHA4. Create session_link record5. Link appears in: lore show, lore blame, MCPSearch Flow
Section titled “Search Flow”1. User runs: lore search "auth"2. Query FTS5 index with filters3. Rank results by relevance4. Group by session5. Format output (text/json)Design Principles
Section titled “Design Principles”- Local-first: All data stays on your machine
- Tool-agnostic: Same data model regardless of AI tool
- Git-integrated: Sessions are meaningful in the context of commits
- Incremental: Daemon only processes new content
- Queryable: Everything is searchable and filterable