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:
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* @file Tests for agentOriginLabel - verifies the parent-chain walk that
|
||||
* renders nested subagent attribution as "main › coder › explorer", so
|
||||
* tool events triggered by deeply nested subagents identify their full
|
||||
* lineage instead of collapsing to just the leaf agent.
|
||||
*
|
||||
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { agentOriginLabel, projectFromCwd, type AgentInfo } from "../event-grouping";
|
||||
|
||||
function makeMap(entries: Array<[string, AgentInfo]>): Map<string, AgentInfo> {
|
||||
return new Map(entries);
|
||||
}
|
||||
|
||||
describe("agentOriginLabel - parent chain walk", () => {
|
||||
it("returns 'main' for the main agent itself", () => {
|
||||
const map = makeMap([
|
||||
["sess-main", { type: "main", subagent_type: null, name: "Main", parent_agent_id: null }],
|
||||
]);
|
||||
expect(agentOriginLabel("sess-main", map)).toBe("main");
|
||||
});
|
||||
|
||||
it("renders 'main › coder' for a direct child of main", () => {
|
||||
const map = makeMap([
|
||||
["sess-main", { type: "main", subagent_type: null, name: "Main", parent_agent_id: null }],
|
||||
[
|
||||
"sub-coder",
|
||||
{
|
||||
type: "subagent",
|
||||
subagent_type: "coder",
|
||||
name: "Coder",
|
||||
parent_agent_id: "sess-main",
|
||||
},
|
||||
],
|
||||
]);
|
||||
expect(agentOriginLabel("sub-coder", map)).toBe("main › coder");
|
||||
});
|
||||
|
||||
it("renders 'main › coder › explorer' for a 2-deep subagent", () => {
|
||||
const map = makeMap([
|
||||
["sess-main", { type: "main", subagent_type: null, name: "Main", parent_agent_id: null }],
|
||||
[
|
||||
"sub-coder",
|
||||
{
|
||||
type: "subagent",
|
||||
subagent_type: "coder",
|
||||
name: "Coder",
|
||||
parent_agent_id: "sess-main",
|
||||
},
|
||||
],
|
||||
[
|
||||
"sub-explorer",
|
||||
{
|
||||
type: "subagent",
|
||||
subagent_type: "explorer",
|
||||
name: "Explorer",
|
||||
parent_agent_id: "sub-coder",
|
||||
},
|
||||
],
|
||||
]);
|
||||
expect(agentOriginLabel("sub-explorer", map)).toBe("main › coder › explorer");
|
||||
});
|
||||
|
||||
it("falls back to single-segment when the map is undefined (legacy callers)", () => {
|
||||
const info: AgentInfo = {
|
||||
type: "subagent",
|
||||
subagent_type: "coder",
|
||||
name: "Coder",
|
||||
parent_agent_id: "sess-main",
|
||||
};
|
||||
expect(agentOriginLabel("sub-coder", info)).toBe("coder");
|
||||
});
|
||||
|
||||
it("uses subagent name when subagent_type is null", () => {
|
||||
const map = makeMap([
|
||||
["sess-main", { type: "main", subagent_type: null, name: "Main", parent_agent_id: null }],
|
||||
[
|
||||
"sub-1",
|
||||
{
|
||||
type: "subagent",
|
||||
subagent_type: null,
|
||||
name: "Helper",
|
||||
parent_agent_id: "sess-main",
|
||||
},
|
||||
],
|
||||
]);
|
||||
expect(agentOriginLabel("sub-1", map)).toBe("main › Helper");
|
||||
});
|
||||
|
||||
it("breaks cleanly on a parent-chain cycle", () => {
|
||||
// Pathological: a → b → a. Should not loop forever.
|
||||
const map = makeMap([
|
||||
[
|
||||
"a",
|
||||
{
|
||||
type: "subagent",
|
||||
subagent_type: "a",
|
||||
name: "A",
|
||||
parent_agent_id: "b",
|
||||
},
|
||||
],
|
||||
[
|
||||
"b",
|
||||
{
|
||||
type: "subagent",
|
||||
subagent_type: "b",
|
||||
name: "B",
|
||||
parent_agent_id: "a",
|
||||
},
|
||||
],
|
||||
]);
|
||||
const result = agentOriginLabel("a", map);
|
||||
expect(result).toBe("b › a");
|
||||
});
|
||||
|
||||
it("returns null for null agentId regardless of map shape", () => {
|
||||
expect(agentOriginLabel(null, makeMap([]))).toBeNull();
|
||||
expect(agentOriginLabel(null, undefined)).toBeNull();
|
||||
});
|
||||
|
||||
it("falls back to 'main' for IDs ending in -main when no info is available", () => {
|
||||
expect(agentOriginLabel("session-xyz-main", makeMap([]))).toBe("main");
|
||||
});
|
||||
});
|
||||
|
||||
describe("projectFromCwd - session-cwd fallback for the dir prefix", () => {
|
||||
it("returns the last path segment of a POSIX cwd", () => {
|
||||
expect(projectFromCwd("/Users/dev/WebstormProjects/Claude-Code-Agent-Monitor")).toBe(
|
||||
"Claude-Code-Agent-Monitor"
|
||||
);
|
||||
});
|
||||
|
||||
it("ignores a trailing slash", () => {
|
||||
expect(projectFromCwd("/Users/dev/my-app/")).toBe("my-app");
|
||||
});
|
||||
|
||||
it("handles Windows backslash paths", () => {
|
||||
expect(projectFromCwd("C:\\Users\\dev\\my-app")).toBe("my-app");
|
||||
});
|
||||
|
||||
it("returns null for null, undefined, or empty cwd", () => {
|
||||
expect(projectFromCwd(null)).toBeNull();
|
||||
expect(projectFromCwd(undefined)).toBeNull();
|
||||
expect(projectFromCwd("")).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user