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,272 @@
/**
* @file RunSetup.test.tsx
* @description Pins the props-only boundary of `RunSetup` after its move out of
* `pages/Run.tsx` (where it was `ConfigCard`): every picker the panel owns —
* mode, prompt, cwd, model, permission mode, effort — reports its selection
* through the matching callback and nowhere else, `onStart` fires from the Run
* button, and a missing `claude` binary is surfaced purely from the
* `binaryFound` prop (the panel runs no probe of its own).
*
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
*/
import { MemoryRouter } from "react-router-dom";
import { fireEvent, render, screen } from "@testing-library/react";
import { beforeEach, describe, expect, it, vi } from "vitest";
import i18n from "i18next";
import { RunSetup } from "../RunSetup";
import type { CwdSuggestion } from "../../../lib/api";
vi.mock("../../../lib/api", async (importOriginal) => {
const actual = await importOriginal<Record<string, unknown>>();
const r = (value: unknown) => vi.fn().mockResolvedValue(value);
return {
...actual,
api: {
run: { files: r({ items: [] }) },
sessions: { list: r({ sessions: [], total: 0, limit: 100, offset: 0 }) },
ccConfig: { file: r({ text: "" }) },
},
};
});
const SUGGESTIONS: CwdSuggestion[] = [
{ kind: "home", path: "/Users/tester", label: "Home" },
{ kind: "recent", path: "/Users/tester/projects/other", label: "other" },
];
type Spies = ReturnType<typeof renderSetup>["spies"];
function renderSetup(overrides: Partial<React.ComponentProps<typeof RunSetup>> = {}) {
const spies = {
onModeChange: vi.fn(),
onPromptChange: vi.fn(),
onCwdChange: vi.fn(),
onModelChange: vi.fn(),
onPermissionModeChange: vi.fn(),
onEffortChange: vi.fn(),
onStart: vi.fn(),
onResumeSessionChange: vi.fn(),
onResumeFromHistory: vi.fn(),
};
const utils = render(
<MemoryRouter>
<RunSetup
mode="conversation"
prompt="do the thing"
cwd="/Users/tester"
cwdSuggestions={SUGGESTIONS}
model=""
permissionMode="acceptEdits"
effort=""
binaryFound
busy={false}
activeRuns={null}
resumeSession={null}
slashCommands={[]}
runHistory={[]}
{...spies}
{...overrides}
/>
</MemoryRouter>
);
return { ...utils, spies };
}
/** Open the `Select` whose trigger currently shows `currentLabel`, then pick
* the option labelled `optionLabel`. */
function pickFromSelect(currentLabel: string, optionLabel: string) {
fireEvent.click(screen.getByText(currentLabel));
fireEvent.click(screen.getByText(optionLabel));
}
/** Every callback except the named ones must stay untouched — a selection that
* leaks into a sibling prop is exactly the wiring bug a move can introduce. */
function onlyCalled(spies: Spies, ...called: (keyof Spies)[]) {
for (const [name, spy] of Object.entries(spies)) {
if (called.includes(name as keyof Spies)) continue;
expect(spy, `${name} should not have fired`).not.toHaveBeenCalled();
}
}
beforeEach(() => {
i18n.changeLanguage("en");
vi.clearAllMocks();
});
describe("RunSetup — selections report through callbacks", () => {
it("reports the mode from the one-shot / conversation options", () => {
const { spies } = renderSetup();
fireEvent.click(screen.getByText(i18n.t("run:mode.headless")));
expect(spies.onModeChange).toHaveBeenCalledWith("headless");
fireEvent.click(screen.getByText(i18n.t("run:mode.conversation")));
expect(spies.onModeChange).toHaveBeenLastCalledWith("conversation");
onlyCalled(spies, "onModeChange");
});
it("reports the prompt from the editor", () => {
const { spies } = renderSetup({ prompt: "" });
const box = screen.getByPlaceholderText(i18n.t("run:fields.promptPlaceholder"));
fireEvent.change(box, { target: { value: "review the diff" } });
expect(spies.onPromptChange).toHaveBeenCalledWith("review the diff");
onlyCalled(spies, "onPromptChange");
});
it("reports the cwd from typing and from a suggestion", () => {
const { spies } = renderSetup();
const input = screen.getByPlaceholderText(i18n.t("run:fields.cwdPlaceholder"));
fireEvent.change(input, { target: { value: "/tmp/pro" } });
expect(spies.onCwdChange).toHaveBeenCalledWith("/tmp/pro");
fireEvent.click(screen.getByText("/Users/tester/projects/other"));
expect(spies.onCwdChange).toHaveBeenLastCalledWith("/Users/tester/projects/other");
onlyCalled(spies, "onCwdChange");
});
it("reports the model from the picker, including a custom id", () => {
const { spies } = renderSetup();
pickFromSelect(i18n.t("run:fields.modelInheritLabel"), "Sonnet 4.6");
expect(spies.onModelChange).toHaveBeenCalledWith("sonnet");
// "Custom…" is a sentinel, not a model id — it must not be reported as one;
// the free-text box it reveals is what reports.
fireEvent.click(screen.getByText(i18n.t("run:fields.modelInheritLabel")));
fireEvent.click(screen.getByText(i18n.t("run:fields.modelCustom")));
expect(spies.onModelChange).toHaveBeenCalledTimes(1);
fireEvent.change(screen.getByPlaceholderText(i18n.t("run:fields.modelCustomPlaceholder")), {
target: { value: "claude-opus-5" },
});
expect(spies.onModelChange).toHaveBeenLastCalledWith("claude-opus-5");
onlyCalled(spies, "onModelChange");
});
it("reports the permission mode and the effort level", () => {
const { spies } = renderSetup();
pickFromSelect(i18n.t("run:fields.permissionAcceptEdits"), i18n.t("run:fields.permissionPlan"));
expect(spies.onPermissionModeChange).toHaveBeenCalledWith("plan");
pickFromSelect("Default (model decides)", "Medium");
expect(spies.onEffortChange).toHaveBeenCalledWith("medium");
onlyCalled(spies, "onPermissionModeChange", "onEffortChange");
});
it("fires onStart from the Run button", () => {
const { spies } = renderSetup();
fireEvent.click(screen.getByText(i18n.t("run:actions.start")));
expect(spies.onStart).toHaveBeenCalledTimes(1);
onlyCalled(spies, "onStart");
});
});
describe("RunSetup — missing binary and other blocked states", () => {
/** The Run button, found by its label rather than by DOM position. */
function runButton(): HTMLButtonElement {
return screen.getByText(i18n.t("run:actions.start")).closest("button") as HTMLButtonElement;
}
it("disables Run when the claude binary was not found", () => {
renderSetup({ binaryFound: false });
expect(runButton().disabled).toBe(true);
});
it("enables Run when the binary is found and the form is complete", () => {
renderSetup();
expect(runButton().disabled).toBe(false);
});
it("still disables Run without a prompt, without a cwd, or at the concurrency cap", () => {
const { unmount } = renderSetup({ prompt: " " });
expect(runButton().disabled).toBe(true);
unmount();
const noCwd = renderSetup({ cwd: "" });
expect(runButton().disabled).toBe(true);
noCwd.unmount();
renderSetup({
activeRuns: { items: [], activeCount: 2, maxConcurrent: 2 } as never,
});
expect(runButton().disabled).toBe(true);
expect(screen.getByText(i18n.t("run:concurrency.atCap", { max: 2 }))).toBeTruthy();
});
it("shows the Starting… label while busy", () => {
renderSetup({ busy: true });
expect(screen.getByText(i18n.t("run:actions.starting"))).toBeTruthy();
});
});
describe("RunSetup — resume picker scopes sessions to the selected lane", () => {
it("passes the lane's cwd as a filter and lists only that directory's sessions", async () => {
const { api } = await import("../../../lib/api");
vi.mocked(api.sessions.list).mockResolvedValue({
sessions: [
{ id: "sess-in-lane", cwd: "/Users/tester/lane-a", started_at: "", status: "completed" },
],
total: 1,
limit: 100,
offset: 0,
} as never);
renderSetup({ laneCwd: "/Users/tester/lane-a" });
fireEvent.click(screen.getByText(i18n.t("run:resume.resumeOption")));
fireEvent.click(screen.getByText(i18n.t("run:resume.pickSession")));
await screen.findByText("/Users/tester/lane-a");
// The API call itself is what enforces the scope - the server filters by
// cwd, so the picker must never fetch without one when a lane is selected.
expect(api.sessions.list).toHaveBeenCalledWith(
expect.objectContaining({ cwd: "/Users/tester/lane-a" })
);
});
it("lists everything when no lane is selected", async () => {
const { api } = await import("../../../lib/api");
renderSetup({ laneCwd: undefined });
fireEvent.click(screen.getByText(i18n.t("run:resume.resumeOption")));
fireEvent.click(screen.getByText(i18n.t("run:resume.pickSession")));
await new Promise((r) => setTimeout(r, 0));
expect(api.sessions.list).toHaveBeenCalledWith(expect.objectContaining({ cwd: undefined }));
});
it("re-fetches with the new cwd when the selected lane changes", async () => {
const { api } = await import("../../../lib/api");
const { rerender } = renderSetup({ laneCwd: "/Users/tester/lane-a" });
fireEvent.click(screen.getByText(i18n.t("run:resume.resumeOption")));
fireEvent.click(screen.getByText(i18n.t("run:resume.pickSession")));
await new Promise((r) => setTimeout(r, 0));
rerender(
<MemoryRouter>
<RunSetup
mode="conversation"
prompt="do the thing"
cwd="/Users/tester"
cwdSuggestions={SUGGESTIONS}
model=""
permissionMode="acceptEdits"
effort=""
binaryFound
busy={false}
activeRuns={null}
resumeSession={null}
slashCommands={[]}
runHistory={[]}
laneCwd="/Users/tester/lane-b"
onModeChange={vi.fn()}
onPromptChange={vi.fn()}
onCwdChange={vi.fn()}
onModelChange={vi.fn()}
onPermissionModeChange={vi.fn()}
onEffortChange={vi.fn()}
onStart={vi.fn()}
onResumeSessionChange={vi.fn()}
onResumeFromHistory={vi.fn()}
/>
</MemoryRouter>
);
await new Promise((r) => setTimeout(r, 0));
expect(api.sessions.list).toHaveBeenCalledWith(
expect.objectContaining({ cwd: "/Users/tester/lane-b" })
);
});
});