# Claude Code Monitor Internal SmartGift build. Local-first dashboard for Claude Code: hooks POST every tool call to an Express + SQLite server, a React UI updates over WebSocket, and **lanes** track parallel agent work through a pipeline. Internal build — all rights reserved. ## What it does - **Sessions, agents, events.** Everything Claude Code emits, recorded and searchable: tool calls, token usage, cost, subagent trees, transcripts. - **Lanes.** One lane per working directory, surviving session restarts. A lane moves through pipeline stages and the dashboard shows where it is. - **Stage detection.** The stage is inferred from the tool stream, so a session that never calls `ccam stage` still shows progress — rendered dashed amber and never as done, because an inference is not evidence. - **Run Claude from the browser.** Spawn a session in a lane's directory, stream its output, send follow-ups, resume any past session. - **Analytics, alerts, Kanban and a workflow view**, plus an MCP server and a CLI. ## Requirements Node **>= 20** (`engines` in `package.json`). Node **24** is what the test suites are verified on — node 25 currently breaks 6 server tests through a better-sqlite3 ABI mismatch and 20 client tests through a global `localStorage` change. ## Install as a Claude Code plugin Two commands on a machine that has nothing but Claude Code, no clone and no `npm run setup`: ``` /plugin marketplace add Smartgift-AI/Claude-Code-Monitor /plugin install ccam@claude-code-agent-monitor-plugins ``` The first session start installs the hooks, boots the server, puts `ccam` on PATH and connects the MCP tools; it runs detached, so the session never waits on it. `/ccam-doctor` reports the state, `/ccam-open` builds the UI and prints the URL, `/ccam-update` refreshes after a plugin update. This path needs Node **>= 22.5** (no native `better-sqlite3`, so the server uses `node:sqlite`). Details, including what to delete on uninstall: [`docs/PLUGINS.md`](docs/PLUGINS.md). ## Install from a checkout ```bash npm run setup # root, client and vscode-extension dependencies npm run build # builds the client into client/dist npm start # serves the built client and the API on :4820 ``` Open . Development, with hot reload: ```bash npm run dev # server on :4820, Vite client on :5173 ``` `DASHBOARD_PORT` overrides the port, `DASHBOARD_CLIENT_DIST` overrides where the built UI is served from (defaults to `client/dist`; the plugin install points it at its own runtime directory). `postinstall` writes the Claude Code hook entries that feed the dashboard — do not run it when the `ccam` plugin is installed, or every event is counted twice. ## The CLI `ccam` is linked by `npm run setup`; otherwise call `node bin/ccam.js`. ```bash ccam status # is the dashboard up ccam start # start it in the background and wait for healthy ccam sessions # recent sessions ccam lanes # lanes with stage and progress ccam stage # declare the current lane's stage ccam tail # live event feed ``` `ccam --help` lists the rest. ## Lanes A lane is a working directory the dashboard watches. Two kinds: - **adopted** — a directory you already had. The dashboard only reads it; it is never reset or deleted. - **managed** — a git worktree the dashboard created under `LANES_ROOT`. It owns the full lifecycle and may reset or remove it, behind a three-check destroy guard and a counted preflight the caller has to echo back. ```bash ccam lanes add --cwd /path/to/repo --title "My feature" # adopt ccam lanes add --repo /path/to/repo --slug my-feature # managed worktree ``` The declared stage comes from `ccam stage`. The inferred stage comes from tool events and expires after `DETECTION_TTL_MS` (default 5 minutes), so a lane can move backwards between work sessions. Detection never writes the declared stage, and an inferred node never renders as done. A lane can also run **its own application stack**, isolated per lane, when its repository declares a profile at `/.ccam/profile/` — a `profile.env` of declarations plus shell hooks the dashboard calls. Each lane gets a slot, and its ports and per-lane directories derive from it: ```bash ccam lanes up # boot the stack of the lane owning this directory ccam lanes runtime # slot, ports, service health ccam lanes logs api # tail a service log ccam lanes down ``` Services are fully detached, so restarting the dashboard never stops a running lane. This is resource namespacing on the host, not a container: lanes run as the same user and share the network. [`docs/LANES.md`](docs/LANES.md) has the pipeline model, the destroy guard, the preflight contract, the Workspace page, `GET /api/lanes/:id/git`, and the full runtime/profile contract. ## Tests ```bash npm run test:server # node:test npm run test:client # Vitest ``` Both must be green before a commit; the pre-commit hook runs them plus Prettier. ## Layout | Path | What | |---|---| | `server/` | Express API, SQLite schema, hook ingest, lane and worktree libraries | | `client/` | React 18 + Vite + Tailwind dashboard | | `bin/ccam.js` | CLI | | `mcp/` | MCP server exposing read-only dashboard tools | | `docs/` | Architecture, API, lanes, database | | `plugins/` | Claude Code plugins shipped with the dashboard | ## Docs - [`ARCHITECTURE.md`](ARCHITECTURE.md) — request flow, schema, WebSocket surface - [`docs/LANES.md`](docs/LANES.md) — lanes, pipelines, stage detection - [`docs/API.md`](docs/API.md) — REST endpoints (`openapi.yaml` is generated) - [`docs/DATABASE.md`](docs/DATABASE.md) — tables and migrations - [`INSTALL.md`](INSTALL.md) - [`CLAUDE.md`](CLAUDE.md) — the rules an agent working in this repo must follow