Files
AgentHub/README.vi.md
T
nntrivi2001 fd7f57929c fix(lanes): auto-detect and report stage for codex lanes (issue 11)
A lane on the 16-node `ship-feature` template showed an untouched pipeline
map and never declared a stage. Four independent causes, fixed at their
shared choke points:

1. Codex emits no hooks, so `touchLaneFromHook` — the only caller of
   `stage-detect.detect()`, and correctly pinned to `claude` — could never
   see a `codex` lane. New `server/lib/codex-ingest.js` tails Codex's own
   rollout journals (`$CODEX_HOME/sessions/**/rollout-*.jsonl`), maps its
   tool calls onto the hook-shaped `{tool_name, tool_input}` the matcher
   already understands, and feeds the existing detect path plus an
   idle/running status mirror under the same guard hooks use. Polled every
   `DASHBOARD_CODEX_POLL_MS` ms (default 15000, `0` disables).
2. `resolveLaneArg` matched on cwd alone, so with a claude and a codex lane
   at one directory (the composite `idx_lanes_cwd_tool`) a `ccam stage`
   call could drive the sibling lane's card. It now resolves by
   `--lane` → `CCAM_LANE_ID` → `--tool`/harness marker → owning lane, and
   errors naming both candidates rather than picking one. Every pane the
   dashboard starts carries `CCAM_LANE_ID` (`tmux new-session -e`, or an
   assignment prefix when typing into a live shell pane).
3. `recordDetection`'s declared-wins veto had no exit: a lane left at the
   pipeline's last node rejected every detection for the rest of its life.
   A declaration on the LAST node no longer vetoes — the pipeline is over
   there, so a later detection is new work. Nothing else is relaxed, and
   detection still never writes `stage` nor renders `done`.
4. The run console pre-filled the pipeline's Claude slash command into
   codex panes, which Codex reads as prose — so the skill that would have
   called `ccam stage` never ran. Claude lanes only now.

A codex lane's *declared* stage still depends on the session calling
`ccam stage`; `AGENTS.md` is the only lever CCAM has, so it now says so.

Verified: server 1345/1345, client 441/441, and end-to-end against a real
codex lane row (detected_stage/detected_signal set, declared stage
untouched, no node rendered done).
2026-08-27 16:38:23 +07:00

8.1 KiB

Claude Code Monitor

Bản build nội bộ SmartGift. Dashboard local-first cho Claude Code: hooks POST mỗi tool call lên server Express + SQLite, React UI cập nhật qua WebSocket, và lane (làn đường) theo dõi công việc song song của agent qua một pipeline.

Internal build — all rights reserved.

(Bản dịch tiếng Việt của README.md, tham khảo — README.md gốc là bản chính thức.)

Làm được gì

  • Session, agent, event. Mọi thứ Claude Code emit ra, ghi lại và tìm kiếm được: tool call, token usage, cost, cây subagent, transcript.
  • Lane. Mỗi working directory một lane, sống sót qua session restart. Lane đi qua các pipeline stage và dashboard hiển thị nó đang ở đâu.
  • Stage detection. Stage được suy luận (infer) từ tool stream, nên một session không bao giờ gọi ccam stage vẫn hiển thị progress — render dạng viền chấm màu hổ phách (amber) và không bao giờ hiện done, vì suy luận không phải bằng chứng.
  • Chạy Claude Code hoặc Codex từ trình duyệt. Một terminal thật (tmux + PTY thật, render bằng xterm.js) gắn vào thư mục của lane — đúng cái TUI bạn thấy ở máy, tương tác đầy đủ, resume được, và attach được từ terminal thật qua ccam lanes shell. Chạy CLI nào là thiết lập riêng của từng lane.
  • Analytics (tab trong dashboard), alert và workflow view, cộng thêm MCP server và CLI.

Yêu cầu

Node >= 20 (engines trong package.json). Node 24 là bản test suite được verify — node 25 hiện đang làm gãy 6 test server do lệch ABI better-sqlite3 và 20 test client do thay đổi global localStorage.

Cài như Claude Code plugin

Hai lệnh, trên máy chỉ có Claude Code, không cần clone repo, không cần npm run setup:

/plugin marketplace add Smartgift-AI/Claude-Code-Monitor
/plugin install ccam@claude-code-agent-monitor-plugins

Lần session-start đầu tiên sẽ cài hooks, boot server, đưa ccam vào PATH và kết nối MCP tools; chạy detached nên session không phải chờ. /ccam-doctor báo trạng thái, /ccam-open build UI và in URL, /ccam-update refresh sau khi plugin update. Đường này cần Node >= 22.5 (không dùng better-sqlite3 native, server dùng node:sqlite). Chi tiết, kể cả những gì cần xóa lúc uninstall: docs/PLUGINS.md.

Cài từ checkout

npm run setup          # cài dependency cho root, client và vscode-extension
npm run build           # build client vào client/dist
npm start                # serve client đã build + API trên :4820

Mở http://localhost:4820.

Development, có hot reload:

npm run dev             # server trên :4820, Vite client trên :5173

DASHBOARD_PORT override port, DASHBOARD_CLIENT_DIST override nơi UI đã build được serve (mặc định client/dist; bản cài qua plugin trỏ vào runtime directory riêng của nó). postinstall ghi các hook entry Claude Code để nạp dữ liệu cho dashboard — đừng chạy nó khi plugin ccam đã cài, không thì mỗi event bị đếm hai lần.

CLI

ccam được link sẵn bởi npm run setup; không thì gọi node bin/ccam.js.

ccam status             # dashboard có đang chạy không
ccam start               # start ngầm (background) và chờ tới khi healthy
ccam sessions            # session gần đây
ccam lanes                # danh sách lane kèm stage và progress
ccam lanes pipeline      # pipeline template của lane này, hoặc đổi nó
ccam stage <name>        # khai báo stage hiện tại của lane
ccam tail                 # xem live event feed

ccam --help liệt kê phần còn lại.

Lane

Lane là một working directory mà dashboard theo dõi. Hai loại:

  • adopted (nhận nuôi) — một thư mục bạn đã có sẵn. Dashboard chỉ đọc nó; không bao giờ reset hay xóa.
  • managed (tự quản lý) — git worktree do dashboard tạo dưới LANES_ROOT. Dashboard sở hữu toàn bộ vòng đời và có thể reset/xóa nó, phía sau một guard ba lớp kiểm tra khi hủy (destroy guard) và một bước preflight đếm số mà bên gọi phải echo lại.
ccam lanes add --cwd /path/to/repo --title "My feature"    # adopt
ccam lanes add --repo /path/to/repo --slug my-feature      # managed worktree

Mỗi lane còn mang theo CLI điều khiển nó — claude (mặc định) hoặc codex — chọn trong modal Add lane và cố định suốt vòng đời của lane. Lane Codex có panel chạy với các lựa chọn riêng của Codex (sandbox, approval, reasoning effort) và resume bằng codex resume --last. Codex không bắn hook của dashboard này, nên lane Codex vẫn ghi lịch sử chạy nhưng không xuất hiện ở Sessions và Analytics. Stage detection thì vẫn chạy, đọc từ rollout journal của chính Codex trên đĩa ($CODEX_HOME/sessions/**/rollout-*.jsonl, poll mỗi DASHBOARD_CODEX_POLL_MS ms, mặc định 15000) — thứ lane Codex không tự có là stage khai báo, vì chỉ chính session đó mới gọi được ccam stage.

Stage khai báo (declared) đến từ ccam stage. Stage suy luận (inferred) đến từ tool event và hết hạn sau DETECTION_TTL_MS (mặc định 5 phút), nên lane có thể lùi lại giữa các work session. Detection không bao giờ ghi đè stage khai báo, và node suy luận không bao giờ render thành done.

Pipeline template của lane có thể đổi sau khi tạo — ccam lanes pipeline <template> từ terminal, hoặc dùng picker chọn pipeline-template cạnh tiêu đề lane trong panel chi tiết của trang Workspace. Cả hai đều re-resolve lại stage đã khai báo hiện tại của lane theo node-list của template mới, và cảnh báo nếu nó không còn khớp node nào.

Lane cũng có thể chạy application stack riêng của nó, cô lập theo từng lane, khi repository của nó khai báo một profile tại <repo>/.ccam/profile/ — một file profile.env khai báo cộng shell hooks mà dashboard gọi. Mỗi lane được cấp một slot, port và thư mục riêng theo lane được suy ra từ đó:

ccam lanes up            # boot stack của lane sở hữu thư mục hiện tại
ccam lanes runtime       # slot, port, tình trạng service
ccam lanes logs api      # tail log của một service
ccam lanes down

Service chạy hoàn toàn detached, nên restart dashboard không bao giờ dừng lane đang chạy. Đây là namespacing tài nguyên trên host, không phải container: các lane chạy chung user và share network.

docs/LANES.md có mô hình pipeline, destroy guard, hợp đồng (contract) preflight, trang Workspace, GET /api/lanes/:id/git, và toàn bộ hợp đồng runtime/profile.

Test

npm run test:server    # node:test
npm run test:client    # Vitest

Cả hai phải xanh (pass) trước khi commit; pre-commit hook chạy chúng cộng thêm Prettier.

Cấu trúc thư mục

Đường dẫn Là gì
server/ Express API, schema SQLite, hook ingest, thư viện lane và worktree
client/ Dashboard React 18 + Vite + Tailwind
bin/ccam.js CLI
mcp/ MCP server expose các tool đọc dữ liệu dashboard (read-only)
docs/ Architecture, API, lanes, database
plugins/ Các Claude Code plugin đi kèm dashboard

Tài liệu