/** * The live surface (progress §7): one widget, keyed `pi-workflows:progress`, above the editor. * * **The surface is chosen by `ctx.mode`, not by `hasUI`** (§7.2) — the two disagree exactly where it * matters. RPC has a UI and no frame clock: `setWidget` carries `widgetLines: string[]` over the wire, * a component factory cannot cross that boundary, and there is no `requestRender` on the far side to * drive an animation. So RPC gets the same tree, redrawn only when an event moves it, which is the * honest thing to show a client that cannot animate. Handing it a factory would not degrade; it would * fail. * * **The TUI surface owns one timer, and only while work is in flight** (§7.3). 120 ms advances the * spinner and asks for a re-render; it starts when the projection first reports an `in_progress` node * and stops the moment none remains — including while `blocked`, which may last hours and must not wake * the TUI at all. That is also why the pure renderer takes its frame as a parameter (progress §4.8): * the only thing this timer does is count, and between whole seconds the render it triggers is * byte-identical, so a diffing TUI redraws nothing. * * Everything about how the panel LOOKS lives in `src/progress` and nothing about it is decided here. */ import type { ExtensionUIContext } from "@earendil-works/pi-coding-agent"; import type { ProgressView } from "../progress/types.ts"; /** The widget key (progress §7.1). One executing run per project (spec §7) means one widget, never a set. */ export declare const PROGRESS_WIDGET_KEY = "pi-workflows:progress"; /** The slice of PI's UI a surface touches. Narrow on purpose: a fake in a test is three functions. */ export type WidgetUI = Pick; /** Somewhere a projection can be pushed. The sink holds one and never asks which kind it is. */ export interface ProgressSurface { /** Draw `view`. `working` names the current step for the harness's own working indicator (§7.4). */ update(view: ProgressView, working: string | undefined): void; /** Remove the widget and stop anything recurring. Idempotent. */ clear(): void; } /** * The interactive surface: a component factory, a live theme, and the spinner timer. * * The factory is installed ONCE and then fed by mutation — `setWidget` on every event would hand PI a * new component each time, discarding the one holding the timer and leaking an interval per event. */ export declare function createTuiSurface(ui: WidgetUI, runLabel: string): ProgressSurface; /** * The RPC surface: the same tree as `string[]`, re-pushed per event. No factory (it cannot cross the * wire) and no timer (there is no `requestRender` on the far side to drive one), so the spinner never * advances — an honest still frame rather than an animation nobody would see. */ export declare function createRpcSurface(ui: WidgetUI, runLabel: string): ProgressSurface; /** * Whether anything is executing right now — the timer's whole start/stop condition (§7.3). * * Deliberately generous: ANY node reading `in_progress` counts, construct or leaf. Being briefly * awake with nothing to animate costs one wasted tick; being asleep while a spinner should be turning * is the panel freezing in front of the user, which is the failure this feature exists to prevent. */ export declare function hasWorkInFlight(view: ProgressView): boolean; /** * `workflow: test (2 of 5)` — what `setWorkingMessage` says while a run is live (§7.4). `undefined` * once nothing is executing, which restores PI's own message. */ export declare function workingMessage(view: ProgressView): string | undefined; //# sourceMappingURL=progress-widget.d.ts.map