story-kit: merge 81_story_agent_roster_badges_show_availability_state
This commit is contained in:
@@ -374,3 +374,74 @@ describe("AgentPanel fade-out", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("RosterBadge availability state", () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
Element.prototype.scrollIntoView = vi.fn();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
mockedAgents.getAgentConfig.mockResolvedValue(ROSTER);
|
||||||
|
mockedAgents.listAgents.mockResolvedValue([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows a green dot for an idle agent", async () => {
|
||||||
|
render(<AgentPanel />);
|
||||||
|
|
||||||
|
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("");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows green badge styling for an idle agent", async () => {
|
||||||
|
render(<AgentPanel />);
|
||||||
|
|
||||||
|
const badge = await screen.findByTestId("roster-badge-coder-1");
|
||||||
|
// JSDOM normalizes #3fb95015 to rgba(63, 185, 80, 0.082) and #3fb950 to rgb(63, 185, 80)
|
||||||
|
expect(badge.style.background).toBe("rgba(63, 185, 80, 0.082)");
|
||||||
|
expect(badge.style.color).toBe("rgb(63, 185, 80)");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows a blue pulsing dot for an active agent", async () => {
|
||||||
|
const agentList: AgentInfo[] = [
|
||||||
|
{
|
||||||
|
story_id: "81_active",
|
||||||
|
agent_name: "coder-1",
|
||||||
|
status: "running",
|
||||||
|
session_id: null,
|
||||||
|
worktree_path: null,
|
||||||
|
base_branch: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||||
|
|
||||||
|
render(<AgentPanel />);
|
||||||
|
|
||||||
|
const dot = await screen.findByTestId("roster-dot-coder-1");
|
||||||
|
// JSDOM normalizes #58a6ff to rgb(88, 166, 255)
|
||||||
|
expect(dot.style.background).toBe("rgb(88, 166, 255)");
|
||||||
|
expect(dot.style.animation).toBe("pulse 1.5s infinite");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("shows blue badge styling for an active agent", async () => {
|
||||||
|
const agentList: AgentInfo[] = [
|
||||||
|
{
|
||||||
|
story_id: "81_active",
|
||||||
|
agent_name: "coder-1",
|
||||||
|
status: "running",
|
||||||
|
session_id: null,
|
||||||
|
worktree_path: null,
|
||||||
|
base_branch: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
mockedAgents.listAgents.mockResolvedValue(agentList);
|
||||||
|
|
||||||
|
render(<AgentPanel />);
|
||||||
|
|
||||||
|
const badge = await screen.findByTestId("roster-badge-coder-1");
|
||||||
|
// JSDOM normalizes #58a6ff18 to rgba(88, 166, 255, 0.094) and #58a6ff to rgb(88, 166, 255)
|
||||||
|
expect(badge.style.background).toBe("rgba(88, 166, 255, 0.094)");
|
||||||
|
expect(badge.style.color).toBe("rgb(88, 166, 255)");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -105,19 +105,20 @@ function RosterBadge({
|
|||||||
padding: "2px 8px",
|
padding: "2px 8px",
|
||||||
borderRadius: "6px",
|
borderRadius: "6px",
|
||||||
fontSize: "0.7em",
|
fontSize: "0.7em",
|
||||||
background: isActive ? "#58a6ff18" : "#ffffff08",
|
background: isActive ? "#58a6ff18" : "#3fb95015",
|
||||||
color: isActive ? "#58a6ff" : "#888",
|
color: isActive ? "#58a6ff" : "#3fb950",
|
||||||
border: isActive ? "1px solid #58a6ff44" : "1px solid #333",
|
border: isActive ? "1px solid #58a6ff44" : "1px solid #3fb95040",
|
||||||
transition: "background 0.3s, color 0.3s, border-color 0.3s",
|
transition: "background 0.3s, color 0.3s, border-color 0.3s",
|
||||||
}}
|
}}
|
||||||
title={
|
title={
|
||||||
isActive
|
isActive
|
||||||
? `Working on #${storyNumber ?? activeStoryId}`
|
? `Working on #${storyNumber ?? activeStoryId}`
|
||||||
: `${agent.role || agent.name} — idle`
|
: `${agent.role || agent.name} — available`
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{isActive && (
|
{isActive && (
|
||||||
<span
|
<span
|
||||||
|
data-testid={`roster-dot-${agent.name}`}
|
||||||
style={{
|
style={{
|
||||||
width: "5px",
|
width: "5px",
|
||||||
height: "5px",
|
height: "5px",
|
||||||
@@ -130,20 +131,23 @@ function RosterBadge({
|
|||||||
)}
|
)}
|
||||||
{!isActive && (
|
{!isActive && (
|
||||||
<span
|
<span
|
||||||
|
data-testid={`roster-dot-${agent.name}`}
|
||||||
style={{
|
style={{
|
||||||
width: "5px",
|
width: "5px",
|
||||||
height: "5px",
|
height: "5px",
|
||||||
borderRadius: "50%",
|
borderRadius: "50%",
|
||||||
background: "#555",
|
background: "#3fb950",
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span style={{ fontWeight: 600, color: isActive ? "#58a6ff" : "#aaa" }}>
|
<span
|
||||||
|
style={{ fontWeight: 600, color: isActive ? "#58a6ff" : "#3fb950" }}
|
||||||
|
>
|
||||||
{agent.name}
|
{agent.name}
|
||||||
</span>
|
</span>
|
||||||
{agent.model && (
|
{agent.model && (
|
||||||
<span style={{ color: isActive ? "#7ab8ff" : "#666" }}>
|
<span style={{ color: isActive ? "#7ab8ff" : "#5ab96a" }}>
|
||||||
{agent.model}
|
{agent.model}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
@@ -153,7 +157,7 @@ function RosterBadge({
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{!isActive && (
|
{!isActive && (
|
||||||
<span style={{ color: "#444", fontStyle: "italic" }}>idle</span>
|
<span style={{ color: "#5ab96a", fontStyle: "italic" }}>available</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user