Skip to content

Architecture

This document explains how Lore captures, stores, and links AI coding sessions.

┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ AI Tools │ │ Lore │ │ Git Repo │
│ │ │ │ │ │
│ Claude Code │────▶│ Watchers │ │ .git/ │
│ Aider │ │ (parsers) │ │ │
│ Gemini CLI │ │ │ │ │ │
│ Continue.dev │ │ ▼ │ │ │
│ Cline │ │ SQLite DB │◀───▶│ Commits │
│ ... │ │ (sessions, │ │ │
└─────────────────┘ │ messages, │ └─────────────────┘
│ links) │
└─────────────────┘

Each supported AI tool has a dedicated watcher that knows how to:

  1. Find session files on disk
  2. Parse the tool’s specific format (JSONL, JSON, Markdown)
  3. Extract messages with roles, timestamps, and content
  4. 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.

Lore uses SQLite for all persistent storage:

~/.lore/
├── lore.db # SQLite database
├── config.yaml # User configuration
└── logs/ # Daemon logs

sessions - Core session data

ColumnTypeDescription
idUUIDPrimary key
toolTEXTTool name (e.g., “claude-code”)
tool_versionTEXTTool version if available
modelTEXTAI model used
started_atDATETIMESession start time
ended_atDATETIMESession end time
working_directoryTEXTProject directory
git_branchTEXTActive branch
message_countINTNumber of messages
source_pathTEXTOriginal file path (for dedup)
machine_idUUIDMachine identifier

messages - Conversation content

ColumnTypeDescription
idUUIDPrimary key
session_idUUIDForeign key to sessions
parent_idUUIDFor threaded conversations
roleTEXTuser, assistant, system
contentJSONMessage content (text, tool use, etc.)
timestampDATETIMEMessage time
message_indexINTOrder in conversation

session_links - Commit associations

ColumnTypeDescription
idUUIDPrimary key
session_idUUIDForeign key to sessions
commit_shaTEXTGit commit SHA
link_typeTEXTcommit, branch, remote
confidenceFLOATAuto-link confidence (0-1)
created_byTEXTuser, auto, hook

Additional tables: tags, annotations, summaries, machines, messages_fts (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:

Terminal window
lore search "authentication middleware"

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:

  1. Watches directories for all enabled tools
  2. Debounces rapid file changes
  3. Incrementally parses only new content
  4. Updates session git_branch when it changes

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 search
  • lore_get_session - Get session by ID
  • lore_list_sessions - List with filters
  • lore_get_context - Recent sessions for repo
  • lore_get_linked_sessions - Sessions for a commit
1. User runs: lore import
2. Registry returns enabled watchers
3. Each watcher scans for session files
4. Parser converts tool format → internal model
5. Deduplication check (by source_path)
6. Insert session + messages into database
7. FTS index updated automatically
1. User runs: lore link abc123 --commit HEAD
2. Resolve session ID prefix → full UUID
3. Resolve git ref → commit SHA
4. Create session_link record
5. Link appears in: lore show, lore blame, MCP
1. User runs: lore search "auth"
2. Query FTS5 index with filters
3. Rank results by relevance
4. Group by session
5. Format output (text/json)
  1. Local-first: All data stays on your machine
  2. Tool-agnostic: Same data model regardless of AI tool
  3. Git-integrated: Sessions are meaningful in the context of commits
  4. Incremental: Daemon only processes new content
  5. Queryable: Everything is searchable and filterable