story-kit: start 59_story_current_work_panel
This commit is contained in:
@@ -73,7 +73,16 @@ function StatusBadge({ status }: { status: AgentStatusValue }) {
|
||||
);
|
||||
}
|
||||
|
||||
function RosterBadge({ agent }: { agent: AgentConfigInfo }) {
|
||||
function RosterBadge({
|
||||
agent,
|
||||
activeStoryId,
|
||||
}: {
|
||||
agent: AgentConfigInfo;
|
||||
activeStoryId: string | null;
|
||||
}) {
|
||||
const isActive = activeStoryId !== null;
|
||||
const storyNumber = activeStoryId?.match(/^(\d+)/)?.[1];
|
||||
|
||||
return (
|
||||
<span
|
||||
style={{
|
||||
@@ -83,14 +92,56 @@ function RosterBadge({ agent }: { agent: AgentConfigInfo }) {
|
||||
padding: "2px 8px",
|
||||
borderRadius: "6px",
|
||||
fontSize: "0.7em",
|
||||
background: "#ffffff08",
|
||||
color: "#888",
|
||||
border: "1px solid #333",
|
||||
background: isActive ? "#58a6ff18" : "#ffffff08",
|
||||
color: isActive ? "#58a6ff" : "#888",
|
||||
border: isActive ? "1px solid #58a6ff44" : "1px solid #333",
|
||||
transition: "background 0.3s, color 0.3s, border-color 0.3s",
|
||||
}}
|
||||
title={agent.role || agent.name}
|
||||
title={
|
||||
isActive
|
||||
? `Working on #${storyNumber ?? activeStoryId}`
|
||||
: `${agent.role || agent.name} — idle`
|
||||
}
|
||||
>
|
||||
<span style={{ fontWeight: 600, color: "#aaa" }}>{agent.name}</span>
|
||||
{agent.model && <span style={{ color: "#666" }}>{agent.model}</span>}
|
||||
{isActive && (
|
||||
<span
|
||||
style={{
|
||||
width: "5px",
|
||||
height: "5px",
|
||||
borderRadius: "50%",
|
||||
background: "#58a6ff",
|
||||
animation: "pulse 1.5s infinite",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{!isActive && (
|
||||
<span
|
||||
style={{
|
||||
width: "5px",
|
||||
height: "5px",
|
||||
borderRadius: "50%",
|
||||
background: "#555",
|
||||
flexShrink: 0,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<span style={{ fontWeight: 600, color: isActive ? "#58a6ff" : "#aaa" }}>
|
||||
{agent.name}
|
||||
</span>
|
||||
{agent.model && (
|
||||
<span style={{ color: isActive ? "#7ab8ff" : "#666" }}>
|
||||
{agent.model}
|
||||
</span>
|
||||
)}
|
||||
{isActive && storyNumber && (
|
||||
<span style={{ color: "#7ab8ff", marginLeft: "2px" }}>
|
||||
#{storyNumber}
|
||||
</span>
|
||||
)}
|
||||
{!isActive && (
|
||||
<span style={{ color: "#444", fontStyle: "italic" }}>idle</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -519,7 +570,7 @@ export function AgentPanel() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Roster badges */}
|
||||
{/* Roster badges — show all configured agents with idle/active state */}
|
||||
{roster.length > 0 && (
|
||||
<div
|
||||
style={{
|
||||
@@ -528,9 +579,24 @@ export function AgentPanel() {
|
||||
gap: "4px",
|
||||
}}
|
||||
>
|
||||
{roster.map((a) => (
|
||||
<RosterBadge key={`roster-${a.name}`} agent={a} />
|
||||
))}
|
||||
{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;
|
||||
return (
|
||||
<RosterBadge
|
||||
key={`roster-${a.name}`}
|
||||
agent={a}
|
||||
activeStoryId={activeStoryId}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user