Cold-storage warehouse + searchable recall for Claude Code session transcripts. Every compacted, retired, or old session you ever ran — moved to a vault, indexed by full-text search, and one command away from being pulled back into context.
~/.claude/projects/ accumulates a JSONL transcript for every Claude Code session you ever start. After a few months it's gigabytes, your shell autocompletes for-ever, and the interesting sessions — the ones you'd want to recall and resume — are buried under hundreds of throwaway ones. Compaction lossy-summarises them; rotation deletes them outright.
You want all of it, forever, but you want it off your laptop, scannable, and rehydratable on demand.
chronicle sweeps old sessions out of ~/.claude/projects/, copies them onto a network/SSD vault you point it at (default /Volumes/storage/chronicle), and writes an FTS5-indexed SQLite catalog to ~/.chronicle/index.db.
chronicle archive # sweep sessions older than 30 days
chronicle search "wellrx foamer"
chronicle rehydrate 1b3f... # copy back into ~/.claude/projects so /resume sees it
The transcripts are never deleted — they're moved. The catalog stores per-session metadata (project, timestamps, message count, callsign, tool usage, files touched, compacted summary if present, full FTS over user/assistant prose) so you can answer "which session was that wellrx foamer thing?" in milliseconds.
$ chronicle archive
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┃ CHRONICLE ▸ v0.1.0 ┃
┃ scanned 187 · archived 184 · skipped 3 ┃
┃ vault: /Volumes/storage/chronicle ┃
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$ chronicle stats
sessions : 184 (archived=184 rehydrated=0)
messages : 412,338
size on disk : 612.4MB
oldest : 2025-12-04T18:11:02Z
newest : 2026-05-12T07:44:51Z
top projects :
58 -Users-daniel
31 -Users-daniel-AI-wellrx_REDESIGN
18 -Users-daniel-GIT-callsign
...
$ chronicle search "wellrx foamer diff pressure"
⸺ 7f3b… 2026-04-21T18:02:11 -Users-daniel-AI-wellrx_REDESIGN
…FSC 600 is a foamer (not corrosion/scale); decline alerts use «diff pressure»…
▸ /Volumes/storage/chronicle/sessions/2026/04/-Users-daniel-AI-wellrx_REDESIGN/7f3b...jsonl
$ chronicle rehydrate 7f3b...
rehydrated → /Users/daniel/.claude/projects/-Users-daniel-AI-wellrx_REDESIGN/7f3b...jsonl
open in Claude Code via /resume 7f3b... (or read the JSONL directly)
git clone https://github.com/heyfinal/chronicle ~/GIT/chronicle
cd ~/GIT/chronicle
./install.shThat:
- creates a venv at
~/.local/share/chronicle/venv - symlinks
~/.local/bin/chronicle - installs a launchd plist that runs
chronicle archivedaily at 04:17 - creates
~/.chronicle/(index db, logs) - runs
chronicle initto bring up the vault dir on whatever SMB/SSD you point at
Uninstall: ./install.sh --uninstall (keeps ~/.chronicle/ and the vault — only removes the binary, venv, and launchd job).
Default vault is /Volumes/storage/chronicle. Override with CHRONICLE_VAULT=/some/other/path or edit ~/.chronicle/config.toml:
vault_path = "/Volumes/storage/chronicle"
age_days = 30
keep_recent_per_project = 3┌──────────────────────────────┐ ┌────────────────────────────────────┐
│ ~/.claude/projects/ │ │ $CHRONICLE_VAULT │
│ └─ -Users-daniel-AI-X/ │ │ └─ sessions/ │
│ ├─ 7f3b…jsonl (8 MB) │ │ └─ 2026/04/ │
│ └─ 1c2a…jsonl (3 MB) │ ──────▶ │ └─ -Users-daniel-AI-X/ │
└──────────────────────────────┘ move │ ├─ 7f3b…jsonl │
+verify│ └─ 7f3b…meta.json │
(sha256)└────────────────────────────────────┘
│
▼
┌───────────────────────────┐
│ ~/.chronicle/index.db │
│ sessions (metadata) │
│ sessions_fts (FTS5) │
└───────────────────────────┘
Design choices:
- Move-with-verify, never copy-and-leave: source files are removed only after the destination sha256 matches.
.meta.jsonnext to each transcript in the vault so the vault is fully self-describing —chronicle index --rebuildwill recreate the SQLite index from scratch if it's lost.- Local SQLite, vault as plain files. SQLite over SMB is hazardous; the index lives at
~/.chronicle/index.db(WAL mode) and points to vault paths. The vault holds only flat files. - FTS5 full-text over the user-facing prose: first user message, last user message, compacted summary text, project path, tools used, files touched, callsign (when set).
- Per-project recency floor. By default the 3 most-recent sessions per project stay live (override with
--keep-recent). - Idempotent. Re-running
chronicle archiveafter a partial run picks up where it left off.
chronicle init # create vault dir + ~/.chronicle/index.db
chronicle archive [--age N] [--keep-recent K] [--all] [--dry-run] [--vault PATH]
chronicle index [--rebuild] # rescan vault & sync sqlite index
chronicle list [--project P] [--status S] [--limit N] [--json]
chronicle search "FTS5 EXPR" [--project P] [--limit N] [--json]
chronicle recall "FTS5 EXPR" [--project P] [--limit N] [--include-summary] [--markdown]
chronicle context UUID [--json] # paste-ready markdown for one session
chronicle show UUID [--json]
chronicle rehydrate UUID # copy back into ~/.claude/projects/
chronicle stats [--json]
chronicle agent [--markdown] # AI-agent capabilities + guide (JSON by default)
chronicle path # resolved vault + db paths + writability
chronicle purge UUID [--delete-vault]
search accepts the full SQLite FTS5 MATCH syntax:
chronicle search 'foamer NEAR/5 pressure'
chronicle search '"FSC 600"'
chronicle search 'wellrx AND (chemistry OR diff)'
chronicle search 'callsign:Frank'
chronicle is built for AI agents as a first-class consumer. Read AGENTS.md for the full integration guide.
The agent-targeted surface:
chronicle recall "QUERY"— FTS5 search + bundled summaries, JSON by default. The one command your agent usually wants.chronicle context UUID— paste-ready markdown context block for a single session.chronicle agent— emits the AI capabilities + usage guide as JSON (or--markdown).chronicle-mcp— stdio MCP server exposing every operation as a tool:chronicle_recall,chronicle_search,chronicle_show,chronicle_context,chronicle_list,chronicle_rehydrate,chronicle_stats,chronicle_agent_guide. Install withpip install 'chronicle[mcp]'—install.shauto-registers it in~/.claude.jsonwhen present.- Claude Code plugin —
plugin/manifest.jsonships a SessionStart-time skill that tells the model when and how to invoke chronicle. - Stable exit codes —
0ok,1partial,2vault unavailable,3invalid input,4not found,5vault file missing.
Typical flow inside an agent:
user: "what did we conclude about the wellrx foamer issue?"
agent: → chronicle_recall(query="wellrx foamer", include_summary=True, limit=3)
reads matches[0].summary, answers directly with that context, cites the uuid
user: "resume that Frank session from last week"
agent: → chronicle_recall(query="callsign:Frank", limit=5)
→ chronicle_rehydrate(uuid=matches[0].uuid)
tells the user: "Restored. Run /resume <uuid>"
Companion to callsign
If you're also running callsign, archived sessions retain the callsign in their metadata (callsign column + FTS). chronicle search 'callsign:Frank' will pull every session "Frank" ever ran.
- HTML report (
chronicle report > out.html) — timeline + per-project drill-down. - Inline compacted-summary regeneration via local LLM for sessions that pre-date compaction.
- iMessage hook so
iMsg chronicle: search Xfrom your phone returns matches. - Optional encrypted vault (age/gpg) for off-site archives.
PRs welcome.
MIT — see LICENSE.