Contributing
Contributions are welcome! This guide covers how to set up your development environment, understand the project structure, and submit a pull request.
Prerequisites
- Rust 1.75+ (
rustuprecommended) - Node.js 20+ and npm 10+ (for the web dashboard)
- Git
Dev setup
1. Clone the repository
git clone https://github.com/Codestz/claude-hindsight
cd claude-hindsight
2. Install web dependencies
cd web && npm install && cd ..
3. Build the web dashboard
The Rust build script (build.rs) expects the web assets to be built before compiling. Run:
cd web && npm run build && cd ..
4. Build and run Hindsight
cargo run -- serve
For faster iteration during web development, run both servers simultaneously:
# Terminal 1 — Rust backend
cargo run -- serve
# Terminal 2 — Vite dev server (proxies API calls to :7227)
cd web && npm run dev
Tip: The Vite dev server runs on
:5173and proxies/api/*requests to the Rust backend on:7227. Hot module replacement works for React components.
5. Run tests
cargo test
6. Lint
cargo clippy -- -D warnings
cd web && npm run lint
Project structure
claude-hindsight/
Cargo.toml Rust workspace manifest
build.rs Embeds web/dist/ at compile time
src/ Rust source
main.rs Entry point, CLI dispatch
lib.rs Library exports
error.rs Shared error types (thiserror)
agents/ Agent discovery and parsing
analyzer/ Session analysis and metrics
api/ JSON response types
commands/ CLI subcommand implementations
config/ Configuration file (TOML) handling
otel/ OTLP telemetry receiver
parser/ JSONL session file parser
search/ Full-text search (SQLite FTS5)
server/ HTTP server and API route handlers
routes/ Individual route handlers
storage/ SQLite index management
tui/ Terminal UI (ratatui + crossterm)
watcher/ File watcher for live session tailing
web/ React dashboard (Vite + React Router)
src/
pages/ React Router page components
components/ Shared UI components
lib/ API client, types, utilities
site/ Astro docs & landing page
tests/ Integration tests
Formula/ Homebrew formula
Code standards
Rust
- Follow standard Rust idioms; run
cargo clippybefore committing - Use
thiserrorfor error types,anyhowfor application-level errors - No
unwrap()in library code — propagate errors with? - Document public items with
///doc comments
TypeScript / React
- Functional components only
- Minimal dependencies — avoid adding new npm packages unless necessary
- No
anytypes - Follow existing patterns for API calls (see
web/src/lib/)
Commit messages
Use conventional commits:
feat: add session export to CSV
fix: handle empty JSONL files in indexer
docs: update architecture diagram
chore: bump dependency versions
Submitting a pull request
- Fork the repository and create a branch from
main - Make your changes, following the code standards above
- Ensure
cargo testandcargo clippy -- -D warningspass - Ensure
cd web && npm run buildsucceeds (the rust-embed step requires built assets) - Open a pull request with a clear description of the change and why it’s needed
Reporting issues
Use GitHub Issues. Please include:
- Claude Hindsight version (
claude-hindsight --version) - OS and architecture
- Steps to reproduce
- Expected vs actual behavior
How it works
For those curious about the internals, here’s a plain-English overview of how Hindsight works end-to-end.
Reading session data
Claude Code records every session as a newline-delimited JSON (JSONL) file in ~/.claude/projects/<project-slug>/<session-id>.jsonl. Each line is a JSON object — a “node” — representing one event: a user message, an assistant response, a tool call, a tool result, a thinking block, or a sub-agent spawn.
Hindsight reads these files using a streaming parser (src/parser/) that processes one node at a time, so even sessions with thousands of nodes load quickly.
The SQLite index
On claude-hindsight init, Hindsight scans all configured project directories and builds a local SQLite database at ~/.local/share/claude-hindsight/index.db.
The schema is intentionally flat to allow fast single-query analytics:
sessions— one row per JSONL file: session ID, project, model, token counts, cost, timestamps, error counttool_uses— denormalized tool call records for fast frequency queriessession_fts— SQLite FTS5 virtual table for full-text search over message content
claude-hindsight reindex uses file modification timestamps to skip sessions that haven’t changed, making incremental updates fast.
Single-binary embed
The web dashboard is a Vite + React Router application built to static files. At Rust compile time, rust-embed bundles the entire web/dist/ directory into the binary as read-only byte slices.
At runtime, the embedded HTTP server (axum) serves these static assets from memory alongside the JSON API — no Node.js required.
OTLP telemetry
The integrate command installs Claude Code hooks that fire on every tool call. The PreToolUse hook calls claude-hindsight hook tool-use, which emits an OTLP span to the local daemon on port 7228.
The daemon (src/otel/) is a minimal OTLP receiver that translates incoming spans into activity timeline events and stores them for the dashboard’s /activity feed.
Key dependencies
axum, rusqlite, rust-embed, ratatui, tokio, serde, clap, opentelemetry.