feat(app): give composer track pills a segment per state

A mixed fan-out used to collapse the pill to its single most urgent
state, so a red dot beside "1 failed" over a child that was still
working read as the whole fan-out having stopped. Every state present
now gets its own mark and count, in the sidebar's status-group order.
This commit is contained in:
Mohamed Boudra
2026-08-18 21:51:25 +02:00
parent 5731f016c2
commit 25fbc939e0
17 changed files with 221 additions and 116 deletions
+16 -4
View File
@@ -16,11 +16,10 @@ export function isSidebarActiveAgent(input: AgentStateBucketInput): boolean {
}
// Most urgent first, for collapsing a project's workspaces into one badge. This is
// deliberately NOT the flat status-list order (STATUS_BUCKET_ORDER in
// hooks/sidebar-status-view-model.ts), which ranks "attention" above "running": on a
// deliberately NOT STATUS_BUCKET_ORDER below, which ranks "attention" above "running": on a
// collapsed project row we want an actively-working project to keep showing the loader,
// so "running" outranks "attention" here. Blocked (needs_input) and failed still win over
// both; done stays last.
// so "running" outranks "attention" here. needs_input and failed still win over both;
// done stays last.
const STATUS_BUCKET_PRIORITY: readonly SidebarStateBucket[] = [
"needs_input",
"failed",
@@ -29,6 +28,19 @@ const STATUS_BUCKET_PRIORITY: readonly SidebarStateBucket[] = [
"done",
];
/**
* The order states are listed in when all of them are shown side by side rather than collapsed
* into one — the sidebar's status groups, and the subagent pill's segments. Anything the user has
* to act on comes before anything that is still moving on its own.
*/
export const STATUS_BUCKET_ORDER: readonly SidebarStateBucket[] = [
"needs_input",
"failed",
"attention",
"running",
"done",
] as const;
/**
* Collapses many workspace status buckets into the single most urgent one, so a
* collapsed project row can stand in for the child rows it hides.