fix(app): subagents track display + archive flicker

- Bucket finished subagents as `done` instead of `attention`; drop
  "needs attention" segment from the section header — subagents are
  transient and don't carry an unread state worth surfacing.
- Gate the subagents selector on the existing pending-archive query so
  optimistic archives survive authoritative agent snapshots that wipe
  the local `archivedAt`. Last subagent archived now cleanly hides the
  whole track via the existing empty-rows guard.
This commit is contained in:
Mohamed Boudra
2026-05-09 16:28:09 +07:00
parent 34df55a10a
commit 3eda7dd15b
7 changed files with 253 additions and 80 deletions
+9 -15
View File
@@ -212,7 +212,7 @@ describe("SubagentsSection", () => {
});
describe("header copy", () => {
it("renders '2 subagents' when two rows have no running and no attention state", () => {
it("renders '2 subagents' when two rows are not running", () => {
render([row({ id: "child-a" }), row({ id: "child-b" })]);
expect(queryByTestId("subagents-section-header")?.textContent).toBe("2 subagents");
});
@@ -228,14 +228,12 @@ describe("SubagentsSection", () => {
);
});
it("renders '1 subagent · 1 needs attention' for a single attention row", () => {
it("renders '1 subagent' for a finished row that still requires attention upstream", () => {
render([row({ id: "child-a", requiresAttention: true })]);
expect(queryByTestId("subagents-section-header")?.textContent).toBe(
"1 subagent · 1 needs attention",
);
expect(queryByTestId("subagents-section-header")?.textContent).toBe("1 subagent");
});
it("renders '5 subagents · 2 running · 1 needs attention' when both suffixes apply", () => {
it("renders '5 subagents · 2 running' when finished rows require attention upstream", () => {
render([
row({ id: "a", status: "running" }),
row({ id: "b", status: "running" }),
@@ -244,31 +242,27 @@ describe("SubagentsSection", () => {
row({ id: "e" }),
]);
expect(queryByTestId("subagents-section-header")?.textContent).toBe(
"5 subagents · 2 running · 1 needs attention",
"5 subagents · 2 running",
);
});
});
it("counts attention only from amber (idle + requiresAttention) rows", () => {
it("ignores requiresAttention for non-running header copy", () => {
render([
row({ id: "a", status: "error", requiresAttention: false }),
row({ id: "b", status: "idle", requiresAttention: false }),
row({ id: "c", status: "idle", requiresAttention: true }),
]);
expect(queryByTestId("subagents-section-header")?.textContent).toBe(
"3 subagents · 1 needs attention",
);
expect(queryByTestId("subagents-section-header")?.textContent).toBe("3 subagents");
});
it("excludes errored or running rows from the needs attention count", () => {
it("still counts running rows even when they require attention", () => {
render([
row({ id: "a", status: "error", requiresAttention: true }),
row({ id: "b", status: "running", requiresAttention: true }),
row({ id: "c", status: "idle", requiresAttention: true }),
]);
expect(queryByTestId("subagents-section-header")?.textContent).toBe(
"3 subagents · 1 running · 1 needs attention",
);
expect(queryByTestId("subagents-section-header")?.textContent).toBe("3 subagents · 1 running");
});
it("renders each row through the shared workspace tab icon primitives", () => {