Supervise several agents at once
One daemon already saw every session; the dashboard only ever showed one of them well. Under four parallel agents it failed in specific ways, each fixed here: - Sessions were identified by workspace basename, so two agents in one repo were indistinguishable. The daemon now hands out a small ordinal badge in arrival order and the web UI colours each agent by it — rows, timeline lines, and approval cards, which previously asked you to approve `rm -rf` "in remote-grok" without saying which one. - `currentTool` held a single call, so parallel tools overwrote each other. It is now a list; durations are matched FIFO per tool name, since hook payloads carry no call id. - One 400-event ring, evicted oldest-first, let a chatty agent blank everyone else's history. Eviction now takes from whichever session holds the most of the ring. - Sessions sorted by recency jumped under a moving thumb. They are ordered waiting -> error -> working -> idle -> ended, ties on badge, so an agent keeps its slot. - Events carry no workspace root, so a restart came back with a full timeline and an empty roster. The session map is persisted to sessions.json (debounced, flushed on shutdown, 12h cutoff on load). In-flight tools are dropped on the way out: they belonged to a process that no longer exists. - Snapshot pushes now back off to 1s once a snapshot exceeds 24KB, since full-snapshot SSE cost scales with agent count. - Pending approvals are ordered by which expires first, not by arrival. `glance status` and /local/status report the roster by state. e2e suite: 220 passed, 0 failed.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* A fixed colour per agent, keyed on the badge the daemon hands out.
|
||||
*
|
||||
* Labels are workspace basenames, so two agents working in the same repo read identically.
|
||||
* Colour plus #N is what makes a row in the overview, a line in the timeline and an approval
|
||||
* card recognisably the same agent without reading anything.
|
||||
*
|
||||
* Written as whole class names on purpose: Tailwind scans the source text, so a class
|
||||
* assembled from a template string at runtime would not survive the build.
|
||||
*/
|
||||
|
||||
export interface SessionColor {
|
||||
dot: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
const PALETTE: SessionColor[] = [
|
||||
{ dot: "bg-sky-500", text: "text-sky-600 dark:text-sky-400" },
|
||||
{ dot: "bg-violet-500", text: "text-violet-600 dark:text-violet-400" },
|
||||
{ dot: "bg-emerald-500", text: "text-emerald-600 dark:text-emerald-400" },
|
||||
{ dot: "bg-amber-500", text: "text-amber-600 dark:text-amber-400" },
|
||||
{ dot: "bg-rose-500", text: "text-rose-600 dark:text-rose-400" },
|
||||
{ dot: "bg-cyan-500", text: "text-cyan-600 dark:text-cyan-400" },
|
||||
{ dot: "bg-fuchsia-500", text: "text-fuchsia-600 dark:text-fuchsia-400" },
|
||||
{ dot: "bg-lime-500", text: "text-lime-600 dark:text-lime-400" },
|
||||
];
|
||||
|
||||
export function sessionColor(badge: number): SessionColor {
|
||||
const index = Math.max(0, Math.floor(badge) - 1) % PALETTE.length;
|
||||
return PALETTE[index];
|
||||
}
|
||||
Reference in New Issue
Block a user