|
| 1 | +# CodeForge Dashboard |
| 2 | + |
| 3 | +Session analytics dashboard for Claude Code. Parses JSONL session files into a SQLite database and serves a Svelte 5 SPA for browsing sessions, conversations, plans, tasks, agents, and memory. |
| 4 | + |
| 5 | +> **v0.1.0** — Ships with CodeForge v2.1.1. |
| 6 | +
|
| 7 | +## Quick Start |
| 8 | + |
| 9 | +```bash |
| 10 | +# Development — starts the Bun backend (port 5173) |
| 11 | +bun run dev |
| 12 | + |
| 13 | +# Development — starts only the Vite frontend dev server |
| 14 | +bun run dev:web |
| 15 | + |
| 16 | +# Build the SPA for production |
| 17 | +bun run build |
| 18 | + |
| 19 | +# Preview the production build |
| 20 | +bun run preview |
| 21 | + |
| 22 | +# Run tests |
| 23 | +bun test |
| 24 | +``` |
| 25 | + |
| 26 | +Requires [Bun](https://bun.sh) >= 1.0.0. |
| 27 | + |
| 28 | +## Architecture |
| 29 | + |
| 30 | +The dashboard is a three-layer pipeline: |
| 31 | + |
| 32 | +1. **Parser** (`src/parser/`) — Reads `~/.claude/` session JSONL files, detects projects, extracts messages/tokens/tool calls, and writes everything into a local SQLite database at `~/.codeforge/data/dashboard.db`. |
| 33 | +2. **Server** (`src/server/`) — A `Bun.serve` HTTP server that exposes a REST API over the database, watches for file changes via SSE, and runs memory analysis. |
| 34 | +3. **Web** (`src/web/`) — A Svelte 5 SPA built with SvelteKit's static adapter. Routes, components, and shared state live here. |
| 35 | + |
| 36 | +## Tech Stack |
| 37 | + |
| 38 | +| Layer | Technology | |
| 39 | +|-------|------------| |
| 40 | +| Runtime | Bun | |
| 41 | +| Frontend | Svelte 5, SvelteKit (static adapter) | |
| 42 | +| Styling | TailwindCSS 4 | |
| 43 | +| Charts | LayerChart (d3-scale) | |
| 44 | +| Database | SQLite (bun:sqlite, WAL mode) | |
| 45 | +| Markdown | marked + shiki | |
| 46 | +| Build | Vite 8 | |
| 47 | +| Language | TypeScript 5 | |
| 48 | + |
| 49 | +## API Reference |
| 50 | + |
| 51 | +All endpoints are defined in `src/server/routes/api.ts`. |
| 52 | + |
| 53 | +### GET Endpoints |
| 54 | + |
| 55 | +| Path | Description | |
| 56 | +|------|-------------| |
| 57 | +| `/api/projects` | List all projects | |
| 58 | +| `/api/projects/:id` | Project detail | |
| 59 | +| `/api/sessions` | List sessions (filterable by project, model, since; paginated) | |
| 60 | +| `/api/sessions/:id` | Session detail (tokens, files touched, cost, agents) | |
| 61 | +| `/api/sessions/:id/messages` | Session messages (supports incremental fetch via afterId) | |
| 62 | +| `/api/sessions/:id/plan` | Plan associated with session | |
| 63 | +| `/api/sessions/:id/context` | Context snapshots (memories, rules) for session | |
| 64 | +| `/api/sessions/:id/tasks` | Tasks for the session's team | |
| 65 | +| `/api/sessions/:id/agents` | Subagents spawned by session | |
| 66 | +| `/api/analytics/global` | Global analytics (filterable by date range) | |
| 67 | +| `/api/analytics/project/:id` | Per-project analytics | |
| 68 | +| `/api/plans` | List all plans | |
| 69 | +| `/api/plans/:slug/history` | Plan version history | |
| 70 | +| `/api/tasks` | List all task teams | |
| 71 | +| `/api/agents` | List all agents across sessions | |
| 72 | +| `/api/context` | All context files (memories, rules) | |
| 73 | +| `/api/search` | Full-text search across messages (query, project, role filters) | |
| 74 | +| `/api/ingestion/status` | Parser ingestion status | |
| 75 | +| `/api/memory/runs` | List memory analysis runs | |
| 76 | +| `/api/memory/runs/:id` | Memory run detail (events, result) | |
| 77 | +| `/api/memory/observations` | List observations (filterable by project, category, status) | |
| 78 | +| `/api/memory/observations/:id/history` | Observation change history | |
| 79 | +| `/api/memory/memories` | List approved memories | |
| 80 | +| `/api/memory/stats` | Memory statistics | |
| 81 | +| `/api/memory/stats-by-project` | Observation stats grouped by project | |
| 82 | + |
| 83 | +### POST Endpoints |
| 84 | + |
| 85 | +| Path | Description | |
| 86 | +|------|-------------| |
| 87 | +| `/api/memory/analyze` | Trigger memory analysis for a session | |
| 88 | +| `/api/memory/maintain` | Trigger maintenance for a project | |
| 89 | +| `/api/memory/analyze-project` | Trigger project-wide analysis | |
| 90 | +| `/api/memory/observations/:id/approve` | Promote observation to memory | |
| 91 | +| `/api/memory/observations/:id/dismiss` | Dismiss an observation | |
| 92 | +| `/api/memory/memories/:id/revoke` | Revoke an approved memory | |
| 93 | + |
| 94 | +## Database Schema |
| 95 | + |
| 96 | +The SQLite database (`~/.codeforge/data/dashboard.db`) uses WAL mode. Core tables defined in `src/parser/db.ts`: |
| 97 | + |
| 98 | +| Table | Purpose | |
| 99 | +|-------|---------| |
| 100 | +| `projects` | Detected project paths and names | |
| 101 | +| `sessions` | One row per session — tokens, timestamps, git branch, parent/agent info | |
| 102 | +| `messages` | Individual messages with role, tokens, model, and raw JSON | |
| 103 | +| `messages_fts` | FTS5 virtual table for full-text search | |
| 104 | +| `tool_calls` | Tool invocations extracted from assistant messages | |
| 105 | +| `files_touched` | Files read/written/edited per session | |
| 106 | +| `history_entries` | Session history with display text and project | |
| 107 | +| `file_changes` | Write/edit operations with content diffs | |
| 108 | +| `plan_snapshots` | Plan content captured at points in time | |
| 109 | +| `context_snapshots` | CLAUDE.md, memory, and rule file snapshots | |
| 110 | +| `file_snapshots` | Arbitrary file content snapshots | |
| 111 | +| `subagents` | Agent spawns linked to parent sessions | |
| 112 | +| `memory_runs` | Memory analysis run metadata and results | |
| 113 | +| `observations` | Extracted observations with status lifecycle | |
| 114 | +| `memories` | Promoted memories with category and confidence | |
| 115 | +| `run_observations` | Join table: runs to observations | |
| 116 | +| `observation_history` | Audit log of observation changes | |
| 117 | + |
| 118 | +## Project Structure |
| 119 | + |
| 120 | +``` |
| 121 | +dashboard/ |
| 122 | + bin/codeforge-dashboard # CLI entry point (bash) |
| 123 | + src/ |
| 124 | + parser/ # Session file parsing and database |
| 125 | + db.ts # Schema, migrations, connection management |
| 126 | + types.ts # TypeScript interfaces for messages/sessions |
| 127 | + queries.ts # All database query functions |
| 128 | + server/ # Bun HTTP server |
| 129 | + index.ts # Server entry point |
| 130 | + routes/api.ts # REST API route handlers |
| 131 | + memory-analyzer.js # AI-powered memory extraction |
| 132 | + memory-sync.js # Sync memories to MEMORY.md files |
| 133 | + web/ # Svelte 5 SPA |
| 134 | + routes/ # SvelteKit file-based routes |
| 135 | + lib/ # Shared components and utilities |
| 136 | + app.html # HTML template |
| 137 | + tests/ |
| 138 | + parser/ # Parser unit tests |
| 139 | + server/ # API and server tests |
| 140 | + mockups/ # Static HTML mockups for design validation |
| 141 | + svelte.config.js # SvelteKit config (static adapter) |
| 142 | + package.json |
| 143 | +``` |
| 144 | + |
| 145 | +## Design Decisions |
| 146 | + |
| 147 | +- **Read-only** — The dashboard never writes to `~/.claude/` session files. All state lives in its own SQLite database. |
| 148 | +- **Dark mode only** — No light theme. Simplifies the CSS and matches terminal-centric workflows. |
| 149 | +- **Svelte 5 runes** — Uses `$state`, `$derived`, `$effect` instead of Svelte stores. Global `runes: true` is NOT set in `svelte.config.js` (LayerChart incompatibility). |
| 150 | +- **Fork, don't import** — Patterns from `cli/` are forked into the dashboard. The CLI is never imported as a dependency. |
| 151 | +- **ISO 8601 UTC** — All timestamps stored and displayed in UTC. |
| 152 | +- **Static SPA adapter** — SvelteKit builds to a static `index.html` with client-side routing, served by the Bun backend. |
| 153 | +- **Session ID prefix matching** — API endpoints accept partial session IDs and resolve them via prefix match. |
| 154 | + |
| 155 | +## Testing |
| 156 | + |
| 157 | +```bash |
| 158 | +bun test |
| 159 | +``` |
| 160 | + |
| 161 | +Tests live in `tests/` and cover: |
| 162 | + |
| 163 | +| File | Coverage | |
| 164 | +|------|----------| |
| 165 | +| `tests/parser/analytics.test.ts` | Token analytics and aggregation | |
| 166 | +| `tests/parser/cost.test.ts` | Cost estimation logic | |
| 167 | +| `tests/parser/project-detector.test.ts` | Project path detection | |
| 168 | +| `tests/parser/session-reader.test.ts` | JSONL session file parsing | |
| 169 | +| `tests/server/api.test.ts` | API route handlers | |
| 170 | +| `tests/server/event-bus.test.ts` | SSE event bus | |
| 171 | +| `tests/server/file-snapshots.test.ts` | File snapshot capture | |
| 172 | + |
| 173 | +## License |
| 174 | + |
| 175 | +GPL-3.0 — see [LICENSE](../LICENSE.txt). |
0 commit comments