fix(coding-agent): stabilize interactive status indicators

Closes #6026
This commit is contained in:
Mario Zechner
2026-06-29 16:53:39 +02:00
parent 541d11f725
commit 5d499272a8
5 changed files with 239 additions and 151 deletions
@@ -10,8 +10,7 @@ type InteractiveModePrototype = {
};
type ImportCommandContext = {
loadingAnimation?: { stop: () => void };
statusContainer: { clear: () => void };
clearStatusIndicator: () => void;
runtimeHost: { importFromJsonl: (inputPath: string, cwdOverride?: string) => Promise<{ cancelled: boolean }> };
showError: (message: string) => void;
showStatus: (message: string) => void;
@@ -58,7 +57,7 @@ describe("InteractiveMode /import parsing", () => {
const showError = vi.fn();
const context: ImportCommandContext = {
statusContainer: { clear: vi.fn() },
clearStatusIndicator: vi.fn(),
runtimeHost: { importFromJsonl },
showError,
showStatus,
@@ -90,7 +89,7 @@ describe("InteractiveMode /import parsing", () => {
const showError = vi.fn();
const context: ImportCommandContext = {
statusContainer: { clear: vi.fn() },
clearStatusIndicator: vi.fn(),
runtimeHost: { importFromJsonl },
showError,
showStatus,
@@ -123,7 +122,7 @@ describe("InteractiveMode /import parsing", () => {
});
const context: ImportCommandContext = {
statusContainer: { clear: vi.fn() },
clearStatusIndicator: vi.fn(),
runtimeHost: { importFromJsonl },
showError,
showStatus,
@@ -0,0 +1,32 @@
import type { TUI } from "@earendil-works/pi-tui";
import { afterEach, describe, expect, it, vi } from "vitest";
import { IdleStatus, RetryStatusIndicator } from "../src/modes/interactive/components/status-indicator.ts";
import { initTheme } from "../src/modes/interactive/theme/theme.ts";
describe("status indicators", () => {
afterEach(() => {
vi.useRealTimers();
});
it("keeps idle status at the same height as status indicators", () => {
const idleStatus = new IdleStatus();
const lines = idleStatus.render(20);
expect(lines).toHaveLength(2);
expect(lines).toEqual([" ".repeat(20), " ".repeat(20)]);
});
it("disposes retry countdown updates", () => {
initTheme("dark");
vi.useFakeTimers();
const requestRender = vi.fn();
const tui = { requestRender } as unknown as TUI;
const indicator = new RetryStatusIndicator(tui, 1, 3, 1000);
const callsBeforeDispose = requestRender.mock.calls.length;
indicator.dispose();
vi.advanceTimersByTime(2000);
expect(requestRender).toHaveBeenCalledTimes(callsBeforeDispose);
});
});