feat(status-ui): add compact session status strip

This commit is contained in:
2026-08-25 18:32:33 +02:00
parent 166b065ad4
commit 612b146fd6
5 changed files with 332 additions and 105 deletions
+54
View File
@@ -178,6 +178,60 @@ describe("multi-session navigation", () => {
await user.click(screen.getByText("Tool result · read"));
expect(details).toHaveAttribute("open");
});
it("packs session status between model controls and the composer", () => {
const runtime = runtimeView(summary("status", "streaming"));
runtime.summary.queueCount = 2;
runtime.stats = {
tokens: { input: 10_000, output: 2_450, cacheRead: 8_000, total: 12_450 },
contextUsage: { tokens: 32_000, contextWindow: 200_000, percent: 16 },
};
const { container } = render(
<ConversationWorkspace
runtime={runtime}
onDraft={vi.fn()}
onSubmit={vi.fn()}
onAbort={vi.fn()}
onScroll={vi.fn()}
onModel={vi.fn()}
onThinking={vi.fn()}
onCommand={vi.fn()}
status={{
label: "Working",
detail: "Thinking and preparing a response",
phase: "working",
bridge: "ready",
extensions: ["\u001B[32mLSP\u001B[0m \uE0B0\uFFFDactive\u0007"],
}}
/>,
);
const modelControls = screen.getByRole("region", {
name: "Model and thinking controls",
});
const status = screen.getByRole("status", { name: "Session status" });
const composer = container.querySelector(".composer");
for (const text of [
"Working",
"Thinking and preparing a response",
"Bridge",
"ready",
"In",
"10k",
"Out",
"2.5k",
"Cache read",
"8k",
"Context",
"32k / 200k · 16%",
"Queue",
"2",
"LSP active",
])
expect(status).toHaveTextContent(text);
expect(status.textContent).not.toMatch(/[\u001B\u0007\uE0B0\uFFFD]/u);
expect(modelControls.nextElementSibling).toBe(status);
expect(status.nextElementSibling).toBe(composer);
});
it("shows a jump control only while scrolled up and moves to the latest message", async () => {
const user = userEvent.setup();
const onScroll = vi.fn();