Files
Claude-Code-Monitor/CLAUDE.md
T
nntrivi2001 8c1d46df6c feat: Claude Code Monitor — lanes, pipelines and a merged workspace
Internal SmartGift build of a Claude Code monitoring dashboard.

Lanes: a durable unit of parallel agent work, one per working directory,
tracked across session restarts. Managed lanes are git worktrees the
dashboard provisions and can reset or remove behind a three-check destroy
guard and a counted preflight; adopted lanes are directories you already
own and are never destroyable.

Pipelines: a lane moves through pipeline stages. A stage the agent declares
with evidence renders green; a stage inferred from the tool-event stream
renders dashed amber and never counts as done. Detection is forward-only
within a 30-minute window, and never writes the declared stage.

Workspace: one page at /run with a lane grid, the selected lane's pipeline,
and a full Claude console behind a disclosure.
2026-07-30 14:26:10 +07:00

6.9 KiB

Claude Code Working Guide

Project mission

  • Maintain a reliable local-first dashboard for Claude Code session monitoring.
  • Preserve real-time behavior (hooks -> API -> SQLite -> WebSocket -> UI).
  • Keep MCP integration production-ready for local use (mcp/).

Repo map

  • server/: Express API, hook ingestion, SQLite access, websocket broadcast (includes optional git upstream checks and routes/updates.js, plus lib/workflow-ingest.js which ingests on-disk Workflow-tool run journals — fleets that emit no hooks).
  • client/: React + Vite UI.
  • scripts/: hook installer/handler, import, seed, cleanup utilities. (Update detection lives server-side in server/lib/update-check.js; the dashboard never restarts itself — users run the printed command, surfaced in the UI and by ccam update-check.)
  • mcp/: local MCP server exposing dashboard operations as tools.

Lanes

A lane is a durable unit of parallel agent work — one working directory, many Claude Code sessions over time. Lanes are keyed by cwd, not session_id, so they survive session restarts and allow the dashboard to show a pipeline that persists across runs.

Key points:

  • Sessions are bound to lanes by longest path-boundary prefix match on their cwd (set in hook data from claude CLI).
  • A lane's stage is declared by the driving Claude session (via ccam stage <stage> [--evidence "..."]), not inferred by the dashboard.
  • The console never writes a lane's stage. Declared stages come from ccam stage (a skill calling the CLI command), and inferred stages come from tool-event detection only. The UI's run console and the Workspace page never call POST /api/lanes/:id/stage — that boundary exists because the console observes tool calls but cannot see their outcomes. A lane's stage is the session's truth about progress; the console's observation of tool execution would not be proof of completion.
  • A detection expires, an evidence rule does not. recordDetection skips its forward-only comparison once detected_at is older than DETECTION_TTL_MS (default 30 min), so a lane can move backwards between work sessions. That window changes only WHICH detection is current — it never relaxes declared-wins (an agent's own claim has no expiry) and never lets an inferred node render done.
  • Working-copy facts live at GET /api/lanes/:id/git, never inside GET /api/lanes. That endpoint shells out to git three times; the lane list is polled and re-broadcast on every hook. A cwd that is not a readable repo returns {available:false} with HTTP 200 — a normal state, not a fault. Cards fetch it themselves every 30s and fail silently.
  • The Workspace console collapses with CSS, never by unmounting. Unmounting RunConsole disposes the run subscription and drops a live run's rendered history.
  • CCAM does not orchestrate: no chaining, no queue, no retry logic, no gate evaluation. The session in control makes all decisions; the dashboard records the claimed stage and shows evidence.
  • Pipeline templates are JSON files (server/data/pipelines/) with node definitions; custom templates override built-ins when DASHBOARD_PIPELINES_DIR is set.
  • Nodes render in five states: failed (rejected), current (now), done (with evidence), passed-no-evidence (claimed or skipped, amber), pending (not reached).
  • Liveness: a silent watcher (stage matching /watch|poll/) is dead after LANE_DEAD_SEC seconds (default 300); a silent idle lane is at rest, not dead.
  • Never rm -rf a lane. Destructive lane operations (reset, remove, purge) go through server/lib/worktree.js/server/lib/lanes.js, never a raw filesystem delete — that's what keeps the three-check destroy guard and the DB bookkeeping in lockstep.
  • Never build a git command as a shell string. Lane git operations use execFile("git", [...args]) with an explicit argument array (see server/lib/worktree.js's git() helper), never a concatenated/interpolated string passed to a shell.
  • Adopted lanes are not destroyable. A lane with kind === "adopted" may never have its worktree reset or removed; "removing" one only drops the dashboard's own record of it. This is enforced in code (assertDestroyable's first check) — do not add a path that bypasses it.

See docs/LANES.md for full guide: stage reporting, custom templates, lane actions, and the five node states.

Non-negotiable engineering rules

  • Preserve existing behavior unless explicitly asked to change it.
  • Prefer minimal, reversible diffs.
  • Never silently weaken safety controls around destructive actions.
  • Keep docs updated when behavior, commands, file locations, or workflows change — apply the update-project-docs skill automatically at the end of every change-set that alters behavior, config, interfaces, events, schema, CLI commands, or features (do not wait to be asked).
  • Every applicable source file you create or update (.js/.ts/.tsx/.cjs/.mjs/.py/.sh/.css) must start with the copyright/authorship header — file overview + the exact line @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>. Formats and audit script: .claude/skills/file-headers/ (verify with bash .claude/skills/file-headers/scripts/check-headers.sh). This binds every coding agent (Claude Code, Codex, or others).

Commands you should know

  • Setup: npm run setup
  • Dev: npm run dev
  • Prod build/start: npm run build then npm start
  • Server tests: npm run test:server
  • Client tests: npm run test:client
  • MCP install/build/start: npm run mcp:install, npm run mcp:build, npm run mcp:start
  • MCP typecheck: npm run mcp:typecheck
  • CLI (after setup): ccam <command> — terminal access to the full dashboard surface (bin/ccam.js; ccam help lists commands)

Testing and verification policy

  • Backend changes: run npm run test:server before finishing.
  • Frontend changes: run npm run test:client when relevant. This includes per-screen render snapshots (client/src/pages/__tests__/screens.snapshot.test.tsx). If a UI change is intentional, review the snapshot diff and regenerate baselines with cd client && npx vitest run -u; never blindly update snapshots to make tests pass.
  • MCP changes: run npm run mcp:typecheck and npm run mcp:build.
  • If you cannot run a verification step, state exactly what was not run and why.

Change guidelines by area

  • API routes: preserve response shapes unless change is requested and documented.
  • Database: avoid schema changes without migration-safe logic.
  • Hooks: keep fail-safe and non-blocking behavior.
  • WebSocket: keep message types stable and backward-compatible.
  • Documentation: include exact commands and paths; keep markdown examples runnable.

Agent behavior

  • Explore first, then implement.
  • For larger tasks, propose/check a short plan before broad edits.
  • Use file-specific rules in .claude/rules/ when working in scoped areas.
  • Use project skills from .claude/skills/ for repeatable workflows.
  • Use .claude/agents/ subagents for focused review or investigation passes.