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.
This commit is contained in:
2026-07-29 17:07:45 +07:00
commit 57dc91585d
783 changed files with 221743 additions and 0 deletions
@@ -0,0 +1,17 @@
{
"name": "ccam-sessions",
"description": "Search, inspect, replay, and manage Claude Code sessions tracked by the Agent Monitor dashboard — find sessions by project, model, status, or date; reconstruct event timelines; walk transcripts turn-by-turn; roll up activity per working directory; and identify stale or empty sessions before cleanup.",
"version": "1.0.0",
"author": {
"name": "Nguyễn Ngọc Trí Vĩ",
"url": "https://git.smartgift.io.vn/Smartgift-AI"
},
"homepage": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor",
"repository": {
"type": "git",
"url": "https://git.smartgift.io.vn/Smartgift-AI/Claude-Code-Monitor.git"
},
"license": "MIT",
"keywords": ["sessions", "search", "transcript", "replay", "timeline", "cleanup", "claude-code"],
"categories": ["sessions", "monitoring", "devtools"]
}
@@ -0,0 +1,84 @@
---
name: session-investigator
description: >
Investigates a single Claude Code session end-to-end from Agent Monitor data:
status, model, cost, the recursive agent tree (subagent_type/depth/parent), the
full event chain (PreToolUse/PostToolUse/Stop/SubagentStop/Compaction/APIError/
TurnDuration), transcript highlights, and anomalies. Cross-references workflow
intelligence (orchestration DAG, error propagation by depth) to explain what
the session actually did and where it went wrong.
model: sonnet
tools:
- Bash
- Read
- Grep
---
# Session Investigator
You are a session forensics analyst for the Claude Code Agent Monitor. Given one
session ID (or "latest"), you reconstruct exactly what happened in that session
and produce a data-backed investigation report. You query the dashboard API at
`http://localhost:4820` using `curl -s http://localhost:4820/api/...`. You read
only — you never mutate data.
## Available Data Sources
| Endpoint | Returns |
|----------|---------|
| `GET /api/sessions/:id` | full session detail: status, model, cwd, started_at, ended_at, cost, metadata (thinking_blocks, turn_count, total_turn_duration_ms, usage_extras), nested agents + events |
| `GET /api/sessions/:id/transcript` | ordered transcript messages (user / assistant / tool) for the session |
| `GET /api/events?session_id=X` | events: event_type, tool_name, summary, data, timestamp |
| `GET /api/agents` | agent (subagent) records: status, type, depth, parent — filter to this session |
| `GET /api/pricing/cost/:id` | per-session cost: total_cost, breakdown[{ model, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, cost, matched_rule }] |
| `GET /api/workflows/:id` | 11 datasets: stats, orchestration (DAG), toolFlow, effectiveness, patterns, modelDelegation, errorPropagation (by depth), concurrency, complexity, compaction, cooccurrence |
## Analysis Framework
1. **Resolve the target.** If given a session ID, `GET /api/sessions/:id`. If the
user says "latest"/"last", `GET /api/sessions?limit=1` first to grab the id,
then fetch the detail. Record status, model, cwd, started_at, ended_at, and the
metadata block (thinking_blocks, turn_count, total_turn_duration_ms).
2. **Cost.** `GET /api/pricing/cost/:id`. Report total_cost and the per-model
breakdown across the four token types. Note the `matched_rule` so the user
knows which pricing pattern applied.
3. **Agent tree.** Pull agents for the session (from `/api/sessions/:id` nested
agents, cross-checked against `/api/agents`). Build the parent→child tree using
`parent` and `depth`; annotate each node with type/subagent_type and status.
Flag any agent left in a non-terminal status or with no terminating SubagentStop.
4. **Event chain.** `GET /api/events?session_id=X`. Order by timestamp. Compute the
PreToolUse vs PostToolUse balance (should be ~1:1). Mark APIError and any Stop
that lacks a clean prior PostToolUse. Surface the longest tool durations.
5. **Workflow intelligence.** `GET /api/workflows/:id`. Use `orchestration` for the
DAG shape, `errorPropagation` to see at which depth failures originated and
cascaded, `compaction` for context-pressure impact, and `complexity` for an
overall difficulty score.
6. **Transcript highlights.** `GET /api/sessions/:id/transcript`. Skim the turns;
quote the opening user intent, the key assistant decisions, and any tool failure
or error message — do not dump the whole transcript.
7. **Anomalies.** Out-of-order events, >30s timeline gaps, duplicate agent states,
token spikes preceding Compaction, retries of the same tool, and stale active
status with an old last event.
## Output Standards
- Cite real numbers pulled from the API — never fabricate counts, tokens, or costs.
- Format currency in USD to 4 decimal places.
- Use ▲/▼ for deltas (e.g. PreToolUse ▲ 41 vs PostToolUse 38, ▲ 3).
- Lead with a one-line verdict (CLEAN / DEGRADED / FAILED), then a header block
(id, status, model, duration, turn_count, cost) and an agent tree, an event
timeline, and a numbered findings list with a root-cause hypothesis when errors
are present.
## Constraints
- Read-only advisory role — never modify data.
- Only use data returned by the API — never fabricate metrics.
- If the dashboard is unreachable, tell the user to start it with `npm start` from
the repo root.
@@ -0,0 +1,32 @@
---
description: Search Agent Monitor sessions by cwd, model, or status and print the top matches.
argument-hint: "[query]"
---
Search Claude Code sessions tracked by the Agent Monitor and print the top matches.
The query is **$ARGUMENTS** — any mix of a project / cwd substring, a model
(`opus`/`sonnet`/`haiku` or a model-id fragment), and a status
(`active`/`working`/`completed`/`error`). If empty, just show the most recent sessions.
Fetch the session list (each carries an inline `cost` field):
```
curl -s "http://localhost:4820/api/sessions?limit=200"
```
Then:
1. Filter in-memory: keep sessions whose `cwd` contains the project term (case-insensitive),
whose `model` contains the model term, and whose `status` equals the status term —
apply only the terms present in `$ARGUMENTS`.
2. Sort matches by `cost` descending if the query mentions cost/expensive, otherwise by
`started_at` descending (most recent first).
3. Print the top 10 as a numbered list, one line each:
`<rank>. <id short> — <status> — <model> — <cwd basename> — $<cost to 4dp> — <started_at>`
4. End with the match count and the summed cost of the shown matches.
Currency as USD to 4 decimal places. If nothing matches, say so and list the distinct
cwds/models that DO exist (from the returned data) so the user can refine — do not invent
results. If the dashboard is unreachable, tell the user to start it with `npm start` from
the repo root.
+27
View File
@@ -0,0 +1,27 @@
---
description: List the N most recent Claude Code sessions from the Agent Monitor.
argument-hint: "[N]"
---
List the most recent Claude Code sessions tracked by the Agent Monitor.
`N` = **$ARGUMENTS** (default `10` if empty).
Fetch the most recent sessions (the API returns them most-recently-updated first):
```
curl -s "http://localhost:4820/api/sessions?limit=$ARGUMENTS"
```
This returns a session list; each entry has id, status, model, cwd, started_at,
ended_at, cost, and metadata (turn_count, total_turn_duration_ms).
Then print the sessions as a numbered list, one line each, in the order returned:
`<rank>. <id short> — <status> — <model> — <cwd basename> — <turn_count> turns — $<cost to 4dp> — <started_at>`
After the list, print the summed cost of the listed sessions and a one-line status
tally (e.g. `7 completed · 2 active · 1 error`).
Currency as USD to 4 decimal places. Keep it terse, no preamble. If the dashboard is
unreachable, tell the user to start it with `npm start` from the repo root.
+31
View File
@@ -0,0 +1,31 @@
---
description: Summarize one Agent Monitor session by id — header plus a concise transcript recap.
argument-hint: "[session-id]"
---
Produce a concise recap of one Claude Code session tracked by the Agent Monitor.
The session id is **$ARGUMENTS**. If empty, resolve the latest:
`curl -s "http://localhost:4820/api/sessions?limit=1"` and use its `id`.
Fetch the session header and its transcript:
```
curl -s "http://localhost:4820/api/sessions/$ARGUMENTS"
curl -s "http://localhost:4820/api/sessions/$ARGUMENTS/transcript"
```
The first returns the session detail (status, model, cwd, started_at, ended_at, cost,
metadata: turn_count, thinking_blocks, total_turn_duration_ms). The second returns the
ordered transcript messages (user / assistant / tool).
Then print, concisely:
1. **Header** — one block: `id · model · status · cwd basename · turn_count turns · $<cost to 4dp> · <started_at → ended_at>`.
2. **Recap** — 510 bullets walking the conversation in order: the user's goal, the key
assistant actions and tools used, any tool failures, and how it ended. Summarize each
message in one line; do not paste large payloads (truncate past ~200 chars with `…`).
Currency as USD to 4 decimal places. If the transcript is empty, say the session has no
stored transcript rather than inventing turns. If the dashboard is unreachable, tell the
user to start it with `npm start` from the repo root.
@@ -0,0 +1,62 @@
---
description: >
Roll up Claude Code sessions by working directory (project) from Agent Monitor
data — session count, total cost, total tokens, and last-active timestamp per cwd
— so per-project activity can be compared at a glance. Use when summarizing where
effort and spend went across projects.
---
# CWD Rollup
Aggregate session activity per working directory (project).
## Input
The user provides: **$ARGUMENTS**
- Empty → roll up **all** working directories.
- A path / project substring → restrict the rollup to matching cwds.
- `top N` → keep only the N highest-cost (or highest-count) projects.
## Data Sources
| Endpoint | Returns |
|----------|---------|
| `GET /api/run/cwds` | the distinct working directories that have sessions — the rollup key set |
| `GET /api/sessions?limit=N` | session list: id, status, model, cwd, started_at, ended_at, cost, metadata (usage_extras with token counts) |
| `GET /api/pricing/cost` | fleet cost: total_cost, breakdown[{ model, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, cost, matched_rule }] — for the fleet total to compute each cwd's share |
## Report Sections
### 1. Key set
`GET /api/run/cwds` for the canonical list of working directories. Apply the
`$ARGUMENTS` filter (substring match) if one was given.
### 2. Pull sessions
`GET /api/sessions?limit=1000`. Bucket sessions by `cwd`.
### 3. Aggregate per cwd
For each working directory compute:
- **sessions** — count.
- **cost** — sum of the inline `cost` field across the bucket.
- **tokens** — sum of input / output / cache-read / cache-write from each session's
metadata `usage_extras` (sum the four into a total, and keep input + output as the
"billable text" subtotal).
- **last active** — the max `started_at` (or `ended_at`) in the bucket.
- **models** — the distinct models seen.
### 4. Share of fleet
`GET /api/pricing/cost` for `total_cost`; show each cwd's cost as a percentage of the
fleet total.
### 5. Ranking
Sort by cost descending by default (or count if the user asked); apply `top N`.
## Output
Markdown table: `project (cwd basename) | sessions | total tokens | cost | % of fleet | last active | models`.
Currency as USD to 4 decimal places; token counts with thousands separators; sort
cost-descending. Add a final TOTAL row summing the columns. Only count tokens that
the session metadata actually carries — if `usage_extras` is absent for a session,
note it as excluded rather than guessing. If the dashboard is unreachable, tell the
user to start it with `npm start` from the repo root.
@@ -0,0 +1,76 @@
---
description: >
Identify stale and empty Claude Code sessions in the Agent Monitor and explain the
cleanup endpoint (POST /api/settings/cleanup), always showing the exact list of
what WOULD be removed before anything is deleted. Cleanup permanently deletes data,
so this skill previews first and requires explicit user confirmation. Use when
tidying the monitoring database.
---
# Session Cleanup
Find prune-worthy sessions and explain cleanup — preview first, delete only on
explicit confirmation.
## Input
The user provides: **$ARGUMENTS**
- Empty / `preview` → only show what would be removed (the safe default).
- `confirm` → the user has reviewed the preview and explicitly authorizes deletion.
- An optional staleness threshold (e.g. `older than 7d`) for what counts as stale.
## Data Sources
| Endpoint | Returns |
|----------|---------|
| `GET /api/sessions?limit=N` | session list: id, status, model, cwd, started_at, ended_at, cost, metadata (turn_count, total_turn_duration_ms) |
| `GET /api/stats` | totals: total_sessions, active_sessions, total_events, events_today, sessions_by_status, agents_by_status |
| `POST /api/settings/cleanup` | runs the cleanup routine and returns what was removed — DESTRUCTIVE, only after confirmation |
## Report Sections
### 1. Baseline
`GET /api/stats` — record total_sessions, sessions_by_status, total_events. This is
the before-state to compare against.
### 2. Identify candidates
`GET /api/sessions?limit=1000`. Flag sessions that are:
- **Empty** — zero events and `turn_count` 0 / null and `cost` 0 (started but never
did anything).
- **Stale active** — `status` active/working but last activity older than the
threshold (default 24h), i.e. never cleanly stopped.
- **Truncated** — no `ended_at` and no recent events.
### 3. Preview table (ALWAYS shown)
List every candidate with the reason it qualifies. State the total count and confirm
that **nothing has been deleted yet**.
### 4. Explain the endpoint
Describe `POST /api/settings/cleanup`: it prunes empty / orphaned sessions and their
dangling events server-side and returns a summary of removed rows. Make clear this
is **permanent** and **not reversible** from the dashboard.
### 5. Execute only on confirmation
If — and only if — `$ARGUMENTS` is `confirm` (or the user has explicitly approved
this run), call `POST /api/settings/cleanup`, then re-read `/api/stats` and report
the before → after delta. Otherwise stop after the preview and tell the user to
re-run with `confirm`.
## Output
A preview Markdown table: `id (short) | status | reason | cwd basename | started_at | cost`,
then a one-line count and the explicit "nothing deleted — re-run with `confirm` to
proceed" notice. On a confirmed run, add a before → after summary using ▲/▼ on the
counts. Currency as USD to 4 decimal places.
## Safety
- This is the ONLY skill in the plugin that mutates data, and only via the one
documented endpoint.
- NEVER call `POST /api/settings/cleanup` without an explicit `confirm` from the
user in this turn — previewing is the default.
- Never widen scope to `POST /api/settings/clear-data` or any other destructive
endpoint; cleanup of stale/empty sessions only.
- If the dashboard is unreachable, tell the user to start it with `npm start` from
the repo root.
@@ -0,0 +1,64 @@
---
description: >
Find Claude Code sessions tracked by the Agent Monitor by project (cwd), model,
status, or date, then rank the matches by cost or recency. Pulls the session list
and the distinct cwd / facet values so filters use real values rather than guesses.
Use when locating a session — "find my EstateWise sessions", "which Opus runs
errored this week", "most expensive sessions in /repo".
---
# Session Search
Locate Claude Code sessions in the Agent Monitor by project, model, status, or date.
## Input
The user provides: **$ARGUMENTS**
A free-form query naming any combination of:
- **project / cwd** — a working-directory path or basename (e.g. `EstateWise`, `/Users/.../repo`)
- **model** — `opus`, `sonnet`, `haiku`, or a full model id substring
- **status** — `active`, `working`, `completed`, `error`
- **date** — `today`, `this week`, or an ISO date / range matched against `started_at`
- **ranking** — `by cost` (default when cost is mentioned) or `recent` (default otherwise)
If the query is empty, return the most recent sessions ranked by recency.
## Data Sources
| Endpoint | Returns |
|----------|---------|
| `GET /api/sessions?limit=N` | session list: id, status, model, cwd, started_at, ended_at, cost, metadata (thinking_blocks, turn_count, total_turn_duration_ms, usage_extras) |
| `GET /api/run/cwds` | the distinct working directories that have sessions — use to resolve a fuzzy project name to exact cwd values |
| `GET /api/events/facets` | distinct facet values (event types, tool names, models, statuses) for validating filters |
## Report Sections
### 1. Resolve filters
Fetch `/api/run/cwds` and `/api/events/facets` to map the user's loose terms to
real values: pick the cwd(s) whose path contains the project term, confirm the
model substring exists, and validate the status against known statuses. State
which concrete filters you settled on.
### 2. Pull candidates
`GET /api/sessions?limit=200` (raise the limit if the date window is wide). Filter
in-memory by cwd, model (substring, case-insensitive), status, and `started_at`
date window.
### 3. Rank
Sort by `cost` descending when the user asked "by cost"; otherwise by `started_at`
descending (most recent first). Keep the top 20 unless the user asked for more.
### 4. Matches
One row per session.
### 5. Summary
Count of matches, summed cost across matches, and the model / status distribution.
## Output
Markdown table: `# | id (short) | status | model | cwd (basename) | started_at | cost`.
Currency as USD to 4 decimal places; token / count fields with thousands separators.
If a filter resolved to zero rows, say so and show the closest available values
(e.g. the cwds that *do* exist) rather than fabricating results. If the dashboard
is unreachable, tell the user to start it with `npm start` from the repo root.
@@ -0,0 +1,61 @@
---
description: >
Render an ordered timeline of one Claude Code session's events (every event type)
with per-event durations and tool names, reconstructed from Agent Monitor data.
Pairs PreToolUse with PostToolUse to compute tool durations and surfaces gaps,
errors, and compaction points. Use when reconstructing what happened in a session
step by step.
---
# Session Timeline
Reconstruct the chronological event timeline of a single Claude Code session.
## Input
The user provides: **$ARGUMENTS**
- A **session ID** to time-line, or
- "latest" / "last" for the most recent session.
## Data Sources
| Endpoint | Returns |
|----------|---------|
| `GET /api/sessions/:id` | session header: status, model, cwd, started_at, ended_at, cost, metadata (thinking_blocks, turn_count, total_turn_duration_ms) — and nested events |
| `GET /api/events?session_id=X` | the full event stream: event_type (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, Notification, Compaction, APIError, TurnDuration), tool_name, summary, data, timestamp |
## Report Sections
### 1. Resolve & header
If "latest", `GET /api/sessions?limit=1` to get the id, then `GET /api/sessions/:id`.
Print a one-line header: id, status, model, cwd basename, started_at → ended_at,
turn_count, total_turn_duration_ms, cost.
### 2. Build the ordered timeline
`GET /api/events?session_id=X`. Sort strictly by `timestamp`. For each event emit a
row with: relative offset from `started_at` (e.g. `+00:03.412`), event_type,
tool_name (when present), and a one-line `summary`.
### 3. Compute durations
Pair each `PreToolUse` with its matching `PostToolUse` (same tool_name, next
occurrence) and show the tool's wall-clock duration. For `TurnDuration` events use
the recorded duration directly. Flag any `PreToolUse` with no matching `PostToolUse`
as **unclosed**.
### 4. Annotate notable points
Mark `APIError` (❌), `Compaction` (⚠️ context compressed), `SubagentStop`
(subagent finished), `Notification` (), and any timeline gap > 30s between
consecutive events as an idle window.
### 5. Tallies
Event count by type, total tool time vs. session wall time, and the longest single
tool call.
## Output
A Markdown table — `offset | event_type | tool_name | duration | summary` — in
strict timestamp order, preceded by the header line and followed by the tallies.
Durations in ms or `mm:ss.mmm`; currency as USD to 4 decimal places. Never invent a
duration when a PostToolUse is missing — label it `unclosed`. If the dashboard is
unreachable, tell the user to start it with `npm start` from the repo root.
@@ -0,0 +1,58 @@
---
description: >
Walk a Claude Code session transcript turn-by-turn from Agent Monitor data,
summarizing each user, assistant, and tool message in order so a long conversation
can be reviewed quickly. Anchors the recap to the session header (model, cost,
turn_count). Use when reviewing what was actually said and done in a conversation.
---
# Transcript Replay
Replay a session transcript one turn at a time with a concise summary of each message.
## Input
The user provides: **$ARGUMENTS**
- A **session ID** to replay, or
- "latest" / "last" for the most recent session.
- Optionally a turn range (e.g. `1-10`) or `errors` to focus on tool failures.
## Data Sources
| Endpoint | Returns |
|----------|---------|
| `GET /api/sessions/:id/transcript` | ordered transcript messages: role (user / assistant / tool), content, tool_name and tool result where applicable, timestamps |
| `GET /api/sessions/:id` | session header: status, model, cwd, started_at, ended_at, cost, metadata (thinking_blocks, turn_count, total_turn_duration_ms) |
## Report Sections
### 1. Header
`GET /api/sessions/:id`. Print id, model, cwd basename, status, turn_count,
thinking_blocks, total_turn_duration_ms, and cost in one block.
### 2. Turn-by-turn walk
`GET /api/sessions/:id/transcript`. Iterate messages in order. For each turn emit
one compact entry:
- **user** — the request in one sentence (quote the literal ask only if short).
- **assistant** — the decision / action taken, plus which tools it invoked.
- **tool** — the tool name and a one-line result (success value or the error text);
do not paste large tool payloads.
Group an assistant message with the tool calls it triggered so each "turn" reads as
intent → action → result.
### 3. Thread highlights
After the walk, pull out: the original goal, the key turning points, any tool
failures or retries, and how the session ended (resolved / errored / abandoned).
## Output
A numbered turn list (`Turn N — <role>: <one-line summary>`), grouped intent →
action → result, preceded by the header block and followed by the highlights.
Truncate any quoted content past ~200 chars with `…`. Currency as USD to 4 decimal
places. Summarize faithfully — never invent message content that is not in the
transcript. If the transcript endpoint returns empty, say the session has no stored
transcript (it may predate transcript capture or need a reimport) rather than
fabricating turns. If the dashboard is unreachable, tell the user to start it with
`npm start` from the repo root.