Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions webviews/src/agent-session/acpmux/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8140,19 +8140,23 @@ function AcpmuxPane() {
].join("\u0000")
: "";
const scopedRows = shownSubagent === undefined ? undefined : snapshot.subagentViews?.[shownSubagent];
// Session Info lists the subagent's rows as they stood when the reader started scrolling, until
// the scroll settles, as the chat's card does with `cardRows` (summary/heldWhileScrolling.ts,
// cmux#29639). Another subagent, or another chat, takes its rows at once.
const cardScopedRows = useHeldWhileScrolling(scopedRows, `${shownSessionId ?? ""}\u0000${shownSubagent ?? ""}`);
const sessionInfoSubagent = useMemo((): SubagentScope | undefined => {
if (!scopedAgent) return undefined;
const parent = scopedAgent.parent;
return {
agent: scopedAgent,
rows: scopedRows ?? [],
rows: cardScopedRows ?? [],
parent: parent === null ? chatName : (chatAgents.find((agent) => agent.id === parent)?.name ?? chatName),
agents: descendants(chatAgents, scopedAgent.id),
// As its "Subagent of" pill: back to its parent subagent's view, else the chat's.
onBack: () => setSubagentView(parent ?? undefined),
};
// eslint-disable-next-line react-hooks/exhaustive-deps -- a new scope only when what it shows changes
}, [scopedKey, scopedRows, chatName, chatAgents]);
}, [scopedKey, cardScopedRows, chatName, chatAgents]);
// How many rows Session Info's Background tasks lists for the view on screen, read as it reads
// them (sessionInfoLists drops a transcript shell the registry no longer lists): a subagent's view
// from its own rows (none yet: empty) and processes, with how its shells ended in the chat's rows
Expand Down
24 changes: 24 additions & 0 deletions webviews/test/summary-held-while-scrolling.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,27 @@ test("the card renders no more while history pages in under a 100-event scroll,
act(() => root!.render(<Pane rows={["b1"]} chat="b" />));
expect(host.textContent).toBe("b1");
});

test("subagent-scoped Session Info holds its rows; another subagent takes its own at once", async () => {
// App.tsx holds `snapshot.subagentViews[shown]` keyed by chat and subagent (cmux#29639), as it
// holds the chat's rows for the session card.
const { createRoot } = await import("react-dom/client");
const clock = manualClock();
const flag = new ReaderScroll(clock, HOLD_SETTLE_MS);
function Scoped({ rows, chat, subagent }: { rows: string[] | undefined; chat: string; subagent: string }) {
const held = useHeldWhileScrolling(rows, `${chat}\u0000${subagent}`, flag);
return <span>{(held ?? []).join(",")}</span>;
}
root = createRoot(host);
act(() => root!.render(<Scoped rows={["s5"]} chat="a" subagent="one" />));
act(() => flag.scrolled());
// Older history of the subagent pages in under the reader's scroll: Session Info keeps its rows.
act(() => root!.render(<Scoped rows={["s4", "s5"]} chat="a" subagent="one" />));
expect(host.textContent).toBe("s5");
act(() => clock.run());
expect(host.textContent).toBe("s4,s5");
// Another subagent of the same chat, mid-scroll: its own rows at once.
act(() => flag.scrolled());
act(() => root!.render(<Scoped rows={["t1"]} chat="a" subagent="two" />));
expect(host.textContent).toBe("t1");
});
Loading