From fcf7984a89fa6faecb701c5e40834a2adbd09d84 Mon Sep 17 00:00:00 2001 From: Dave Date: Mon, 23 Feb 2026 21:34:59 +0000 Subject: [PATCH] story-kit: queue 100_story_test_coverage_http_context_rs_to_100 for QA --- ...ry_test_coverage_http_context_rs_to_100.md | 0 ...story_test_coverage_http_model_rs_to_80.md | 0 frontend/src/components/AgentPanel.test.tsx | 40 ++++++-- frontend/src/components/AgentPanel.tsx | 92 ++++--------------- 4 files changed, 53 insertions(+), 79 deletions(-) rename .story_kit/work/{1_upcoming => 3_qa}/100_story_test_coverage_http_context_rs_to_100.md (100%) rename .story_kit/work/{3_qa => 4_merge}/102_story_test_coverage_http_model_rs_to_80.md (100%) diff --git a/.story_kit/work/1_upcoming/100_story_test_coverage_http_context_rs_to_100.md b/.story_kit/work/3_qa/100_story_test_coverage_http_context_rs_to_100.md similarity index 100% rename from .story_kit/work/1_upcoming/100_story_test_coverage_http_context_rs_to_100.md rename to .story_kit/work/3_qa/100_story_test_coverage_http_context_rs_to_100.md diff --git a/.story_kit/work/3_qa/102_story_test_coverage_http_model_rs_to_80.md b/.story_kit/work/4_merge/102_story_test_coverage_http_model_rs_to_80.md similarity index 100% rename from .story_kit/work/3_qa/102_story_test_coverage_http_model_rs_to_80.md rename to .story_kit/work/4_merge/102_story_test_coverage_http_model_rs_to_80.md diff --git a/frontend/src/components/AgentPanel.test.tsx b/frontend/src/components/AgentPanel.test.tsx index d88e627..0b97891 100644 --- a/frontend/src/components/AgentPanel.test.tsx +++ b/frontend/src/components/AgentPanel.test.tsx @@ -98,7 +98,8 @@ describe("RosterBadge availability state", () => { expect(badge.style.color).toBe("rgb(170, 170, 170)"); }); - it("shows a green pulsing dot for an active agent", async () => { + // AC1: roster badge always shows idle (grey) even when agent is running + it("shows a static green dot for a running agent (roster always idle)", async () => { const agentList: AgentInfo[] = [ { story_id: "81_active", @@ -115,12 +116,13 @@ describe("RosterBadge availability state", () => { render(); const dot = await screen.findByTestId("roster-dot-coder-1"); - // JSDOM normalizes #3fb950 to rgb(63, 185, 80) expect(dot.style.background).toBe("rgb(63, 185, 80)"); - expect(dot.style.animation).toBe("pulse 1.5s infinite"); + // Roster is always idle — no pulsing animation + expect(dot.style.animation).toBe(""); }); - it("shows green badge styling for an active agent", async () => { + // AC1: roster badge always shows idle (grey) even when agent is running + it("shows grey (idle) badge styling for a running agent", async () => { const agentList: AgentInfo[] = [ { story_id: "81_active", @@ -137,8 +139,32 @@ describe("RosterBadge availability state", () => { render(); const badge = await screen.findByTestId("roster-badge-coder-1"); - // JSDOM normalizes #3fb95018 to rgba(63, 185, 80, 0.094) and #3fb950 to rgb(63, 185, 80) - expect(badge.style.background).toBe("rgba(63, 185, 80, 0.094)"); - expect(badge.style.color).toBe("rgb(63, 185, 80)"); + // Always idle: grey background and grey text + expect(badge.style.background).toBe("rgba(170, 170, 170, 0.094)"); + expect(badge.style.color).toBe("rgb(170, 170, 170)"); + }); + + // AC2: after agent completes and returns to roster, badge shows idle + it("shows idle state after agent status changes from running to completed", async () => { + const agentList: AgentInfo[] = [ + { + story_id: "81_completed", + agent_name: "coder-1", + status: "completed", + session_id: null, + worktree_path: null, + base_branch: null, + }, + ]; + mockedAgents.listAgents.mockResolvedValue(agentList); + + render(); + + const badge = await screen.findByTestId("roster-badge-coder-1"); + const dot = screen.getByTestId("roster-dot-coder-1"); + // Completed agent: badge is idle + expect(badge.style.background).toBe("rgba(170, 170, 170, 0.094)"); + expect(badge.style.color).toBe("rgb(170, 170, 170)"); + expect(dot.style.animation).toBe(""); }); }); diff --git a/frontend/src/components/AgentPanel.tsx b/frontend/src/components/AgentPanel.tsx index 47c135b..dbac329 100644 --- a/frontend/src/components/AgentPanel.tsx +++ b/frontend/src/components/AgentPanel.tsx @@ -29,17 +29,9 @@ const formatTimestamp = (value: Date | null): string => { }); }; -function RosterBadge({ - agent, - activeStoryId, -}: { - agent: AgentConfigInfo; - activeStoryId: string | null; -}) { +function RosterBadge({ agent }: { agent: AgentConfigInfo }) { const { registerRosterEl } = useLozengeFly(); const badgeRef = useRef(null); - const isActive = activeStoryId !== null; - const storyNumber = activeStoryId?.match(/^(\d+)/)?.[1]; // Register this element so fly animations know where to start/end useEffect(() => { @@ -59,58 +51,25 @@ function RosterBadge({ padding: "2px 8px", borderRadius: "6px", fontSize: "0.7em", - background: isActive ? "#3fb95018" : "#aaaaaa18", - color: isActive ? "#3fb950" : "#aaa", - border: isActive ? "1px solid #3fb95044" : "1px solid #aaaaaa44", - transition: "background 0.3s, color 0.3s, border-color 0.3s", + background: "#aaaaaa18", + color: "#aaa", + border: "1px solid #aaaaaa44", }} - title={ - isActive - ? `Working on #${storyNumber ?? activeStoryId}` - : `${agent.role || agent.name} — available` - } + title={`${agent.role || agent.name} — available`} > - {isActive && ( - - )} - {!isActive && ( - - )} - - {agent.name} - - {agent.model && ( - - {agent.model} - - )} - {isActive && storyNumber && ( - - #{storyNumber} - - )} - {!isActive && ( - available - )} + + {agent.name} + {agent.model && {agent.model}} + available ); } @@ -394,7 +353,7 @@ export function AgentPanel() { )} - {/* Roster badges — show all configured agents with idle/active state */} + {/* Roster badges — agents always display in idle state here */} {roster.length > 0 && (
{roster.map((a) => { - // Find the story this roster agent is currently working on (if any) - const activeEntry = Object.entries(agents).find( - ([, state]) => - state.agentName === a.name && - (state.status === "running" || state.status === "pending"), - ); - const activeStoryId = activeEntry - ? activeEntry[0].split(":")[0] - : null; const isHidden = hiddenRosterAgents.has(a.name); return ( - // Collapsing wrapper: smoothly shrinks when agent departs - // to a work item and expands when it returns.
- +
); })}