Chronicle
A Rust CLI that hooks into Claude Code to record every agent action, with a ratatui TUI dashboard for session replay, time-travel debugging, and file restoration.
https://github.com/user-attachments/assets/eec01413-85d0-4a69-b1f4-41147cb5d2de
Note: This demo shows a simple restore — a use case already covered by Claude Code's built-in
/rewindcommand. The difference is that/rewindonly restores between prompts, while Chronicle lets you restore to any point within a session, including between individual tool calls within a single prompt.
What it does
Chronicle captures every tool call Claude Code makes — every file edit, bash command, read, grep, and more — storing them in a local SQLite database with compressed file snapshots. You can then browse the full session timeline, inspect diffs, and restore your codebase to any point in time.
Claude Code hooks → chronicle daemon → SQLite → TUI dashboard
Use cases
- Session replay — review what an agent did after it's done
- Undo/rollback — restore files to any point in the session
- Post-mortem debugging — find exactly when something went wrong
- Real-time monitoring — watch agent actions as they happen
Installation
From crates.io
From source
The binary will be at target/release/chronicle. Add it to your PATH:
# or
Requirements
- Rust 1.70+ (uses edition 2021)
- macOS or Linux (Unix sockets required)
- Claude Code installed
Quick start
# In any project directory where you use Claude Code:
This will:
- Create a
.chronicle/directory with a SQLite database - Install Claude Code hooks in
.claude/settings.local.json - Start the chronicle daemon in the background
- Add
.chronicle/to.gitignore
Then start Claude Code in the same directory:
Every action is now recorded automatically.
# Open the TUI dashboard
# or just:
CLI commands
| Command | Description |
|---|---|
chronicle init |
Initialize chronicle in the current project |
chronicle or chronicle tui |
Launch the TUI dashboard |
chronicle sessions |
List all recorded sessions |
chronicle restore <event-id> |
Restore files to a specific point in time |
chronicle hooks show |
Show installed hook configuration |
chronicle hooks remove |
Remove hooks and stop daemon |
chronicle daemon start |
Start the daemon manually |
chronicle daemon stop |
Stop the daemon |
chronicle daemon status |
Check if daemon is running |
TUI dashboard
The dashboard has three panels:
┌─ Timeline (40%) ──────────┬─ Detail (60%) ──────────────────┐
│ 14:23:01 [E] Edit main.rs │ Event: PostToolUse (id: 42) │
│ 14:23:02 [B] Bash cargo.. │ Tool: Edit │
│ 14:23:05 [R] Read lib.rs │ │
│ 14:23:06 [W] Write app.rs │ File: src/main.rs │
│ 14:23:08 [G] Grep pattern │ --- a │
│ 14:23:10 [>] UserPrompt.. │ +++ b │
│>>14:23:12 [E] Edit cli.rs │ @@ -1,3 +1,5 @@ │
│ 14:23:15 [B] Bash cargo.. │ +use anyhow::Result; │
│ │ fn main() { │
├────────────────────────────┴─────────────────────────────────┤
│ Session: abc123def │ Events: 42 │ q:quit j/k:navigate r:rest│
└──────────────────────────────────────────────────────────────┘
Keybindings
| Key | Action |
|---|---|
j / k or arrows |
Navigate timeline |
g / G |
Jump to first / last event |
r |
Restore files to selected event (with confirmation) |
q / Esc |
Quit |
Event icons
| Icon | Tool/Event |
|---|---|
E |
Edit |
W |
Write |
B |
Bash |
R |
Read |
G |
Grep |
g |
Glob |
A |
Agent (subagent) |
> |
User prompt |
^ |
Session start |
$ |
Session end |
File-modifying events (Edit, Write) are highlighted in yellow.
Restore
Chronicle uses the snapshot-at model: when you restore to an event, all tracked files are returned to the state they were in at that point in the session.
Restores are:
- Atomic — files are written to temp paths first, then renamed into place
- Reversible — a
RestoreCheckpointevent is created before every restore, so you can undo a restore by restoring to the checkpoint - Confirmed — the TUI shows a confirmation dialog listing all files that would change
CLI restore
# Show what would happen
# Output:
# Restore plan:
# OVERWRITE src/main.rs
# CREATE src/new_file.rs
# DELETE src/old_file.rs
# Proceed? (y/N)
Architecture
Claude Code hooks (shell scripts)
│
│ JSON via Unix socket
▼
chronicle daemon (tokio, background process)
│
├── Event processor (parse, enrich, store)
│ │
│ ▼
│ SQLite (WAL mode) ── .chronicle/chronicle.db
│
└── Broadcast channel (for live TUI updates)
How hooks work
Chronicle installs hooks in .claude/settings.local.json (project-local, not shared). Each hook runs a shell script that pipes Claude Code's JSON event data to the daemon via a Unix socket.
Hooks are best-effort — they always exit 0 and never block Claude Code. If the daemon is down, events are silently dropped (logged to .chronicle/relay.log).
Captured events
| Event | What's recorded |
|---|---|
SessionStart / SessionEnd |
Session lifecycle |
PreToolUse / PostToolUse |
Every tool call with input/output |
PostToolUseFailure |
Tool errors |
UserPromptSubmit |
User messages |
SubagentStart / SubagentStop |
Agent spawns |
Stop |
Assistant's final message |
File snapshots
For file-modifying tools (Edit, Write), chronicle captures:
- File content before the change (at PreToolUse)
- File content after the change (flushed when the next event arrives, or at PostToolUse if delivered)
- A unified diff for display
- Both snapshots are zstd-compressed
Storage
.chronicle/
chronicle.db # SQLite database (WAL mode)
chronicle.sock # Unix domain socket
daemon.pid # Daemon PID file
relay.log # Hook relay error log (1 MB max)
hooks/ # Hook shell scripts
Daemon lifecycle
- Starts automatically with
chronicle initorchronicle tui - Auto-exits after 30 minutes of inactivity
- Handles SIGTERM for clean shutdown
- PID tracked in
.chronicle/daemon.pid
Uninstall
# Remove hooks and stop daemon
# Delete chronicle data (optional)
Development
# Run tests
# Run with logging
RUST_LOG=debug
# Build release
License
MIT