/** * agent-widget.ts — Persistent widget showing running/completed agents above the editor. * * Displays a tree of agents with animated spinners, live stats, and activity descriptions. * Uses the callback form of setWidget for themed rendering. * * Performance features: * - Dirty checking: skips TUI re-render when agent list structure hasn't changed. * - Adaptive refresh: responsive interval (160ms) while work is active, * falling back to a low-cost 1000ms idle cadence. * * UI styles: premium (default), retro, plain */ import type { AgentManager } from "../agent-manager.js"; import type { AgentActivity, UICtx } from "./agent-ui-types.js"; export declare class AgentWidget { private manager; private agentActivity; private closed; private uiCtx; private widgetFrame; private widgetInterval; /** Current refresh interval in ms (for adaptive tracking). */ private currentIntervalMs; /** Tracks how many turns each finished agent has survived. Key: agent ID, Value: turns since finished. */ private finishedTurnAge; /** How many extra turns errors/aborted agents linger (completed agents clear after 1 turn). */ private static readonly ERROR_LINGER_TURNS; /** Whether the widget callback is currently registered with the TUI. */ private widgetRegistered; /** Cached TUI reference from widget factory callback, used for requestRender(). */ private tui; /** Last status bar text, used to avoid redundant setStatus calls. */ private lastStatusText; /** Last footer slot written — cleared when the configured slot changes. */ private lastFooterSlot; /** * Lightweight structural snapshot: numeric hash of agent IDs + statuses. * When unchanged, we skip requestRender to avoid TUI-wide re-render. * Uses numeric comparison (O(1)) instead of string equality (O(N)). */ private agentSnapshotHash; /** * True if the snapshot changed during the last update. * Reset after each render cycle. */ private dirty; /** Debounce timer for coalescing rapid update() calls during spawn bursts. */ private updateTimer; /** Current scroll page (0 = first). */ private scrollPage; /** Total pages available based on current agent count. */ private maxPages; /** Render timing tracker for monitoring update() performance. */ private renderMetrics; /** Timestamp of first spawned agent (for time-to-first-visible). */ private firstSpawnedAt; /** Minimum gap between consecutive update() calls (16ms ~ 60fps). */ private static readonly SPAWN_BATCH_MS; constructor(manager: AgentManager, agentActivity: Map); /** Set the UI context (grabbed from first tool execution). */ setUICtx(ctx: UICtx): void; /** * Called on each new turn (tool_execution_start). * Ages finished agents and clears those that have lingered long enough. */ onTurnStart(): void; /** Ensure the widget update timer is running. */ ensureTimer(): void; /** * Schedule the next tick using setTimeout (self-rescheduling). * Prevents render pileup that can occur with setInterval when a render * takes longer than the interval period. */ private scheduleNextTick; /** Check if a finished agent should still be shown in the widget. */ private shouldShowFinished; /** Record an agent as finished (call when agent completes). */ markFinished(agentId: string): void; /** Get the agents for the current scroll page. */ private getVisibleWindow; /** Scroll one page up (toward newest agents). */ scrollUp(): void; /** Scroll one page down (toward older/finished agents). */ scrollDown(): void; /** Get current scroll page. */ getScrollPage(): number; /** Get total pages. */ getMaxPages(): number; /** Get render performance metrics snapshot. */ getRenderMetrics(): import("./render-metrics.js").RenderMetricsSnapshot; private renderWidget; /** * Debounced update: coalesces rapid calls (e.g. bulk spawns) into a single * update after 16ms. Falls back to immediate update when the timer is not * already pending — ensures the widget still updates promptly for the * first spawn, while batching subsequent ones. * * Usage: call from spawn paths where multiple agents may be created in * quick succession (background spawns, swarm joins, group joins). */ debouncedUpdate(): void; /** Force an immediate widget update. */ update(): void; dispose(): void; }