nntrivi2001 2f39f4ec98 feat(run): wire Workspace to TerminalView, delete the stream-json Run feature
Combines three tasks that couldn't land as separate commits: the
pre-commit hook's full test run crashes on any intermediate state
where Workspace.tsx still imports the files being deleted, so the
deletion (old RunConsole/useRunStream/run-spawner/stream-json-parser),
the RunSetup/RunHistory type adjustments, and this file's own
TerminalView wiring had to be staged together and committed as one
hook-passable unit.

- Delete RunConsole.tsx, useRunStream.ts, server/lib/run-spawner.js,
  server/lib/stream-json-parser.js and their tests (Task 8).
- Adjust RunSetup.tsx/RunHistory.tsx to the tmux-backed RunHandle/
  RunStartArgs/DashboardRunHistoryItem shapes, remove mode selection
  UI (Task 9).
- Swap Workspace.tsx's chat-bubble run console for TerminalView
  (xterm.js over /ws-pty/:runId), drop the stream-json envelope
  plumbing, update Start/Resume to the new RunStartArgs payload.
  Create onStartFromSetup handler to work with RunSetup's new callback
  shape. Remove mode state and related plumbing. Remove send/followUp
  state (no longer using old RunConsole chat interface).
- Add promptPlaceholderTerminal i18n key to support RunSetup's new
  placeholder text (Task 10).
- Update Workspace.test.tsx to mock TerminalView component.
- Regenerate screens.snapshot.test.tsx snapshot (only Workspace run
  panel changes: terminal container instead of chat bubbles).
2026-08-12 11:58:38 +07:00

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.

Install from a checkout

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 http://localhost:4820.

Development, with hot reload:

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.

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 <name>      # 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.
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 <repo>/.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:

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 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

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

S
Description
No description provided
Readme 72 MiB
Languages
JavaScript 52%
TypeScript 45.2%
HTML 1.3%
Shell 0.6%
CSS 0.4%
Other 0.4%