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,416 @@
/**
* @file Tests for human-readable session names and the transcript rename
* marker. Covers:
* - TranscriptCache surfacing the latest custom-title / ai-title.
* - The hook ingestor syncing sessions.name from the transcript title, with
* custom-title winning and ai-title only filling placeholder names.
* - GET /:id/transcript surfacing custom-title (/rename) as a synthetic
* `session_event` marker, deduped, with ai-title excluded.
* - GET /:id/transcript surfacing mid-turn queued user messages
* (attachment/queued_command) as user rows, with queue-operation
* bookkeeping and other attachment subtypes dropped.
* Uses Node's built-in test runner with temp CLAUDE_HOME / DASHBOARD_DATA_DIR.
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
const { describe, it, before, after } = require("node:test");
const assert = require("node:assert/strict");
const path = require("path");
const fs = require("fs");
const os = require("os");
const http = require("http");
const STAMP = `sess-name-${Date.now()}-${process.pid}`;
const TMP = path.join(os.tmpdir(), STAMP);
const CLAUDE_HOME = path.join(TMP, "home");
const DATA_DIR = path.join(TMP, "data");
const TEST_DB = path.join(TMP, "dashboard.db");
process.env.DASHBOARD_DB_PATH = TEST_DB;
process.env.CLAUDE_HOME = CLAUDE_HOME;
process.env.DASHBOARD_DATA_DIR = DATA_DIR;
const { createApp, startServer } = require("../index");
const { db, stmts } = require("../db");
const TranscriptCache = require("../lib/transcript-cache");
const enc = (cwd) => cwd.replace(/[^a-zA-Z0-9]/g, "-");
const PROJECTS = path.join(CLAUDE_HOME, "projects");
function jsonl(lines) {
return lines.map((o) => JSON.stringify(o)).join("\n") + "\n";
}
function writeTranscript(cwd, sessionId, lines) {
const p = path.join(PROJECTS, enc(cwd), `${sessionId}.jsonl`);
fs.mkdirSync(path.dirname(p), { recursive: true });
fs.writeFileSync(p, jsonl(lines));
return p;
}
function req(method, urlPath, body) {
return new Promise((resolve, reject) => {
const url = new URL(urlPath, BASE);
const payload = body ? JSON.stringify(body) : null;
const r = http.request(
{
hostname: url.hostname,
port: url.port,
path: url.pathname + url.search,
method,
headers: payload
? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(payload) }
: {},
},
(res) => {
let b = "";
res.on("data", (c) => (b += c));
res.on("end", () => {
let parsed;
try {
parsed = JSON.parse(b || "{}");
} catch {
parsed = b;
}
resolve({ status: res.statusCode, body: parsed });
});
}
);
r.on("error", reject);
if (payload) r.write(payload);
r.end();
});
}
let server;
let BASE;
before(async () => {
const app = createApp();
server = await startServer(app, 0);
BASE = `http://127.0.0.1:${server.address().port}`;
});
after(() => {
if (server) server.close();
if (db) db.close();
try {
fs.rmSync(TMP, { recursive: true, force: true });
} catch {
/* ignore */
}
});
describe("TranscriptCache — title extraction", () => {
it("returns the latest custom-title and ai-title (last value wins)", () => {
const cwd = "/tmp/cam-name-cache";
const sid = "cache-titles";
const p = writeTranscript(cwd, sid, [
{ type: "ai-title", aiTitle: "Auto one", sessionId: sid },
{ type: "user", message: { role: "user", content: "hi" } },
{ type: "ai-title", aiTitle: "Auto two", sessionId: sid },
{ type: "custom-title", customTitle: "my-feature", sessionId: sid },
]);
const r = new TranscriptCache().extract(p);
assert.equal(r.customTitle, "my-feature");
assert.equal(r.aiTitle, "Auto two");
});
it("returns a result for a transcript that has ONLY a title line", () => {
const cwd = "/tmp/cam-name-only";
const sid = "only-title";
const p = writeTranscript(cwd, sid, [
{ type: "custom-title", customTitle: "title-only", sessionId: sid },
]);
const r = new TranscriptCache().extract(p);
assert.ok(r, "result should not be null");
assert.equal(r.customTitle, "title-only");
});
});
describe("hook ingestor — sessions.name sync from transcript", () => {
it("sets the name to the custom-title on the next hook event", async () => {
const cwd = "/tmp/cam-name-custom";
const sid = "11111111-2222-3333-4444-555555555555";
const tpath = writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "hello" } },
{ type: "custom-title", customTitle: "auth-refactor", sessionId: sid },
]);
const res = await req("POST", "/api/hooks/event", {
hook_type: "Stop",
data: { session_id: sid, cwd, transcript_path: tpath },
});
assert.equal(res.status, 200);
const row = stmts.getSession.get(sid);
assert.equal(row.name, "auth-refactor");
});
it("fills a placeholder name with the ai-title when there is no custom-title", async () => {
const cwd = "/tmp/cam-name-ai";
const sid = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee";
const tpath = writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "hello" } },
{ type: "ai-title", aiTitle: "Investigate flaky test", sessionId: sid },
]);
await req("POST", "/api/hooks/event", {
hook_type: "Stop",
data: { session_id: sid, cwd, transcript_path: tpath },
});
const row = stmts.getSession.get(sid);
assert.equal(row.name, "Investigate flaky test");
});
it("does not let an ai-title clobber a user-chosen name, but a custom-title does", async () => {
const cwd = "/tmp/cam-name-precedence";
const sid = "99999999-8888-7777-6666-555555555555";
// Seed a real, user-chosen name via the sessions API.
await req("POST", "/api/sessions", { id: sid, name: "keep-me", cwd });
// An ai-title must NOT overwrite the user-chosen name.
let tpath = writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "x" } },
{ type: "ai-title", aiTitle: "Auto generated", sessionId: sid },
]);
await req("POST", "/api/hooks/event", {
hook_type: "Stop",
data: { session_id: sid, cwd, transcript_path: tpath },
});
assert.equal(stmts.getSession.get(sid).name, "keep-me");
// But an explicit /rename (custom-title) always wins.
tpath = writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "x" } },
{ type: "ai-title", aiTitle: "Auto generated", sessionId: sid },
{ type: "custom-title", customTitle: "renamed-explicitly", sessionId: sid },
]);
await req("POST", "/api/hooks/event", {
hook_type: "Stop",
data: { session_id: sid, cwd, transcript_path: tpath },
});
assert.equal(stmts.getSession.get(sid).name, "renamed-explicitly");
});
});
describe("GET /:id/transcript — rename markers", () => {
it("surfaces custom-title as a deduped session_event and excludes ai-title", async () => {
const cwd = "/tmp/cam-rename-marker";
const sid = "deadbeef-0000-1111-2222-333333333333";
writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "first" } },
{ type: "ai-title", aiTitle: "noise 1", sessionId: sid },
{ type: "custom-title", customTitle: "feature-x", sessionId: sid },
{ type: "ai-title", aiTitle: "noise 2", sessionId: sid },
// Duplicate custom-title with the SAME value — must be deduped away.
{ type: "custom-title", customTitle: "feature-x", sessionId: sid },
{
type: "assistant",
message: { role: "assistant", content: [{ type: "text", text: "ok" }] },
},
{ type: "custom-title", customTitle: "feature-y", sessionId: sid },
]);
// Register the session so the endpoint doesn't 404.
await req("POST", "/api/sessions", { id: sid, cwd });
const res = await req("GET", `/api/sessions/${sid}/transcript?limit=200`);
assert.equal(res.status, 200);
const events = res.body.messages.filter((m) => m.type === "session_event");
const titles = events.map((e) => e.title);
// feature-x once (dupe collapsed), then feature-y. No ai-title leaks in.
assert.deepEqual(titles, ["feature-x", "feature-y"]);
assert.ok(
events.every((e) => e.event_kind === "rename"),
"every marker is a rename"
);
assert.ok(
!res.body.messages.some((m) => m.type === "session_event" && /noise/.test(m.title || "")),
"ai-title values are never surfaced in the transcript stream"
);
});
});
describe("GET /:id/transcript — local slash-command output (system/local_command)", () => {
it("surfaces /color command + its stdout, skips empty + noise system lines", async () => {
const cwd = "/tmp/cam-local-cmd";
const sid = "c010rrrr-1111-2222-3333-444444444444";
writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "hi" } },
// /color, current Claude Code shape: command + output as system/local_command
{
type: "system",
subtype: "local_command",
content:
"<command-name>/color</command-name>\n <command-message>color</command-message>\n <command-args></command-args>",
sessionId: sid,
},
{ type: "agent-color", agentColor: "cyan", sessionId: sid },
{
type: "system",
subtype: "local_command",
content: "<local-command-stdout>Session color set to: cyan</local-command-stdout>",
sessionId: sid,
},
// /clear writes a content-less local_command line — must NOT become a row
{ type: "system", subtype: "local_command", content: "", sessionId: sid },
// unrelated system subtype — pure noise, must be dropped
{ type: "system", subtype: "turn_duration", durationMs: 1200, sessionId: sid },
]);
await req("POST", "/api/sessions", { id: sid, cwd });
const res = await req("GET", `/api/sessions/${sid}/transcript?limit=200`);
assert.equal(res.status, 200);
const texts = res.body.messages.flatMap((m) =>
m.content.filter((c) => c.type === "text").map((c) => c.text)
);
assert.ok(
texts.some((tx) => tx.includes("<command-name>/color</command-name>")),
"the /color command invocation is surfaced"
);
assert.ok(
texts.some((tx) => tx.includes("Session color set to: cyan")),
"the /color stdout is surfaced"
);
// Empty local_command (/clear) and turn_duration noise produce no message.
assert.ok(
!texts.some((tx) => /turn_duration|durationMs/.test(tx)),
"non-local_command system subtypes are not surfaced"
);
// Exactly two surfaced rows from the system lines (command + stdout), plus
// the one real user message — the empty + noise lines add nothing.
assert.equal(res.body.messages.length, 3);
});
});
describe("GET /:id/transcript — mid-turn queued user messages (attachment/queued_command)", () => {
it("surfaces a queued_command attachment as a user message; drops queue-operation and other attachments", async () => {
const cwd = "/tmp/cam-queued-msg";
const sid = "aaaa1111-2222-3333-4444-555566667777";
writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "start the docs sweep" } },
{
type: "assistant",
message: { role: "assistant", content: [{ type: "text", text: "working on it" }] },
},
// A message typed while Claude was mid-turn is journaled as queue-operation
// bookkeeping plus a queued_command attachment — there is NO user line.
{
type: "queue-operation",
operation: "enqueue",
content: "doc sweep too pls",
sessionId: sid,
},
{
type: "queue-operation",
operation: "remove",
content: "doc sweep too pls",
sessionId: sid,
},
{
type: "attachment",
attachment: {
type: "queued_command",
prompt: "doc sweep too pls",
commandMode: "prompt",
origin: { kind: "human" },
timestamp: "2026-07-16T02:40:45.596Z",
},
timestamp: "2026-07-16T02:40:45.596Z",
sessionId: sid,
},
// Non-queued_command attachments are harness noise — must NOT surface.
{
type: "attachment",
attachment: { type: "task_reminder", content: "reminder noise" },
sessionId: sid,
},
// A content-less queued_command must not become an empty row either.
{
type: "attachment",
attachment: { type: "queued_command", prompt: " ", origin: { kind: "human" } },
sessionId: sid,
},
]);
await req("POST", "/api/sessions", { id: sid, cwd });
const res = await req("GET", `/api/sessions/${sid}/transcript?limit=200`);
assert.equal(res.status, 200);
const queued = res.body.messages.filter((m) =>
m.content.some((c) => c.type === "text" && c.text === "doc sweep too pls")
);
assert.equal(queued.length, 1, "the mid-turn message surfaces exactly once");
assert.equal(queued[0].type, "user");
assert.equal(
queued[0].sender,
"user",
"a human-typed queued message is attributed to the user"
);
assert.equal(queued[0].timestamp, "2026-07-16T02:40:45.596Z");
assert.ok(
!res.body.messages.some((m) =>
m.content.some((c) => c.type === "text" && /reminder noise/.test(c.text || ""))
),
"non-queued_command attachments stay hidden"
);
// start + working + the queued message; queue-operation lines, the noise
// attachment, and the blank prompt add nothing.
assert.equal(res.body.messages.length, 3);
});
it("attributes harness-injected queued_command lines (task-notifications) to system, not the user", async () => {
const cwd = "/tmp/cam-queued-sys";
const sid = "bbbb1111-2222-3333-4444-555566667777";
writeTranscript(cwd, sid, [
{ type: "user", message: { role: "user", content: "kick off the agents" } },
// Background-agent task-notification delivered through the SAME queue as
// typed messages — real shape: attachment has NO origin field at all.
{
type: "attachment",
attachment: {
type: "queued_command",
prompt:
"<task-notification>\n<task-id>a30201bfc90e18271</task-id>\n<status>completed</status>\n</task-notification>",
commandMode: "prompt",
timestamp: "2026-07-16T02:47:36.000Z",
},
timestamp: "2026-07-16T02:47:36.000Z",
sessionId: sid,
},
// Banner-prefixed variant must also be system.
{
type: "attachment",
attachment: {
type: "queued_command",
prompt: "[SYSTEM NOTIFICATION - NOT USER INPUT]\nautomated background-task event",
commandMode: "prompt",
},
sessionId: sid,
},
// Explicit non-human origin → system too.
{
type: "attachment",
attachment: {
type: "queued_command",
prompt: "sdk enqueued follow-up",
origin: { kind: "sdk" },
},
sessionId: sid,
},
// Missing origin but plain human-looking text stays user (older builds).
{
type: "attachment",
attachment: { type: "queued_command", prompt: "and update the docs" },
sessionId: sid,
},
]);
await req("POST", "/api/sessions", { id: sid, cwd });
const res = await req("GET", `/api/sessions/${sid}/transcript?limit=200`);
assert.equal(res.status, 200);
const bySnippet = (s) =>
res.body.messages.find((m) =>
m.content.some((c) => c.type === "text" && (c.text || "").includes(s))
);
assert.equal(bySnippet("<task-notification>").sender, "system");
assert.equal(bySnippet("[SYSTEM NOTIFICATION").sender, "system");
assert.equal(bySnippet("sdk enqueued follow-up").sender, "system");
assert.equal(bySnippet("and update the docs").sender, "user");
});
});