Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,7 @@ body.resizing-row {
.team-status-dot.status-working { background: #e0af68; }
.team-status-dot.status-idle { background: var(--green); }
.team-status-dot.status-unknown { background: var(--green); }
.team-status-dot.status-empty { background: var(--muted); }
.collapsed-team-status {
width: 28px;
padding: 2px;
Expand Down
8 changes: 6 additions & 2 deletions app/src/agentStatus.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ describe("applyStateChange", () => {
});

describe("aggregateTeamStatus", () => {
it("returns unknown for an empty set", () => {
expect(aggregateTeamStatus([])).toBe("unknown");
it("returns empty for a team with no panes", () => {
expect(aggregateTeamStatus([])).toBe("empty");
});

it("returns unknown for a pane whose agent type isn't recognized", () => {
expect(aggregateTeamStatus([status("unknown")])).toBe("unknown");
});

it("lets one blocked pane beat every other state", () => {
Expand Down
11 changes: 10 additions & 1 deletion app/src/agentStatus.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
export type RawState = "idle" | "working" | "blocked" | "unknown";
export type PaneStatus = { state: RawState };
export type PaneStatusMap = Record<string, PaneStatus>;
// A team's aggregate is either one of the pane states, or "empty" — no
// agent has ever been started for that team. "unknown" (a pane exists but
// classify() doesn't recognize its agent type) is deliberately a distinct
// value from "empty" (no pane exists at all): #406 made "unknown" render
// green like idle, since an unhandled type isn't an anomaly, but a team
// nobody has started anything in isn't "idle" — it should read as inert
// gray instead of implying live, healthy agents.
export type TeamAggregateState = RawState | "empty";

export function applyStateChange(map: PaneStatusMap, paneId: string, newState: RawState): PaneStatusMap {
if (map[paneId]?.state === newState) return map;
return { ...map, [paneId]: { state: newState } };
}

export function aggregateTeamStatus(statuses: PaneStatus[]): RawState {
export function aggregateTeamStatus(statuses: PaneStatus[]): TeamAggregateState {
if (statuses.length === 0) return "empty";
const priority: Record<RawState, number> = {
blocked: 3,
working: 2,
Expand Down
Loading