# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview `claudbg` is a Rust CLI tool for inspecting Claude Code sessions. It reads JSONL session files from `~/.claude/projects/`, caches them in a local libsql database (`~/.claude/claudbg.db`), and exposes commands to list, dump, and transcribe sessions and sub-agent runs. ## Development Environment The project uses Nix flakes with [crane](https://github.com/ipetkov/crane) for building. Enter the dev shell before working: ```bash nix develop ``` The dev shell provides: `rustToolchain` (stable + rust-analyzer + clippy), `cargo-watch`, `cargo-edit`, `clang`, `beans`, `jq`. Use `jq` for all JSON processing in shell commands — do not use `python3`. ## Common Commands ```bash # Build cargo build # Run cargo run -- # Tests cargo test # Single test cargo test # Watch mode (rebuild on changes) cargo watch -x build cargo watch -x test # Lint (deny warnings — same as CI) cargo clippy --all-targets -- --deny warnings # Format check cargo fmt --check # Format fix cargo fmt # Run all checks via Nix (matches CI) nix flake check ``` ## Planned Architecture The v0.1.0 milestone targets a working session inspector with these layers, in dependency order: ### 1. CLI Foundation (`src/main.rs`, `src/cli/`) - `clap` (derive) wires top-level subcommands: `sessions`, `agents`, `index`, `tui`, `query` - Global flags on every command: `--output [table|json|xml]` (default: table), `--verbose`, `--include ` (default: tools) - `AppError` enum + `Result` alias using `thiserror` - Short UUID display utility (8-char prefix) ### 2. Data Parsing & Models (`src/models/`) - Rust types (serde-deserializable) for the full JSONL schema: - `SessionEntry` enum: `user` / `assistant` / `system` / `progress` / `file-history-snapshot` / `queue-operation` - `AssistantContent` enum: `text` / `thinking` / `tool_use` - `UserContent` enum: `text` / `tool_result` / `image` - `Usage`, `ToolUseInput`, `SystemMessage` subtypes - Session file discovery: walk `~/.claude/projects/`, URL-decode directory names to recover project paths, return `SessionRef { session_id, project_path, file_path, modified_at }` - Sub-agent file discovery (parallel structure) - JSONL line-by-line reader - `SessionStats` computation: token counts, tool call breakdown by name, duration, model ### 3. Database & Caching (`src/db/`) - libsql (local file, async via tokio) at `~/.claude/claudbg.db` - **Normalized tables**: `sessions`, `messages`, `tool_uses` — used for queries and list views - **Denormalized table**: `raw_sessions (session_id PK, raw_jsonl TEXT, file_mtime, file_size)` — used for fast dump - **Lazy sync**: on any read command, check `file_mtime`/`file_size` against DB; re-parse and upsert if stale - **`index` subcommand**: force full resync of all discovered session files - `--clear` flag: drops and recreates the DB ### 4. Output Formatting (`src/output/`) - Trait-based renderers behind the `--output` flag - **Table** (default): `comfy-table` (in use — `render_table` in `src/output/table.rs`) - **JSON**: `serde_json` pretty-print - **XML**: hand-rolled or quick-xml ### 5. Sessions Commands (`src/commands/sessions/`) - `sessions list`: sorted most-recent-first; columns: short session ID, date, project path, model, message count; `--verbose` shows full UUID - `sessions dump `: table rows — `#`, timestamp, type, role, content preview (truncated); `--verbose` shows full content; accepts 8-char prefix or full UUID - `sessions transcribe `: header with `SessionStats`, then chat log (user text, assistant text/tool-use blocks, thinking blocks gated by `--include thinking`, tool output gated by `--include output`) - `--follow` flag: watch the session file and stream new entries as they arrive ### 6. Agents Commands (`src/commands/agents/`) - Mirror of sessions commands but for sub-agent JSONL files - `agents list `, `agents dump `, `agents transcribe`, `--follow` - **Note:** `discover_agents_for_session(session_file)` must look in `session_file.stem()/subagents/`, not `session_file.parent()/subagents/` ### 7. Stub Commands - `tui`: prints "coming soon!" - `query`: prints "coming soon!" ## Key Design Decisions - Session IDs are UUIDs; display as 8-char prefixes by default, full with `--verbose` - `~/.claude/projects/` directory names are URL-encoded project paths (e.g. `-run-media-pop-...` → `/run/media/pop/...`) - The DB acts as a read-through cache; the JSONL files on disk are the source of truth - All async runtime: tokio (full) - Dependency crate choices (from beans tickets): `clap` (derive), `tokio` (full), `serde` + `serde_json`, `libsql`, `chrono`, `uuid`, `thiserror`, `comfy-table` or `tabled` ## JSONL Schema Notes - Field names in Claude Code JSONL are **camelCase** — serde fields need `#[serde(rename = "...")]`: - `durationMs` (not `duration_ms`) — on top-level `system` entries - `sessionId` (not `session_id`) — on all entries - `parentUuid`, `promptId`, `gitBranch`, etc. - Sub-agent files live at `//subagents/agent-.jsonl` — the session UUID is **also a directory** alongside `.jsonl`; `subagents/` is inside that directory, not next to the `.jsonl` ## Issue Tracking This project uses `beans` for issue tracking. Always use `beans` instead of TodoWrite for task management. See `beans --help` for usage.