/** * Background-run UX, mirroring Claude Code: * - A live task panel below the input lists in-progress runs while you keep working. * It is informational; run /workflows to open the full navigator. * - When a background run finishes, its result is delivered back into the * conversation so the paused task continues with the outcome. */ import type { ExtensionAPI, ExtensionUIContext, Theme } from "@earendil-works/pi-coding-agent"; import { type WorkflowAgentSnapshot } from "./display.js"; import type { ManagedRun, WorkflowManager } from "./workflow-manager.js"; import type { WorkflowStorage } from "./workflow-saved.js"; import type { WorkflowSettings } from "./workflow-settings.js"; export interface TaskPanelOptions { storage?: WorkflowStorage; cwd?: string; /** * Live settings loader. When provided, the panel reads it fresh (with a short * TTL cache) on each render so `/workflows-progress` takes effect without a * restart. Omitted in tests / minimal hosts → always detailed. */ loadSettings?: () => WorkflowSettings; } /** * Deliver a finished (completed) run's result as a `` XML * block. Failed/paused runs go through {@link formatTaskNotification} directly * from the event handlers with the event payload's status/error. */ export declare function deliverText(run: ManagedRun): string; /** * When a background run finishes (or fails), deliver its result back into the * conversation AND continue the turn so the assistant can act on it — without * blocking the user meanwhile: * * - `triggerTurn: true` starts a fresh turn when the agent is idle, feeding the * result to the model so the paused conversation continues. * - `deliverAs: "followUp"` means that if the user is busy in another turn, the * result is queued and picked up after that turn finishes — never interrupting. * * Set up once per extension; idempotent via an internal guard. */ export declare function installResultDelivery(pi: ExtensionAPI, manager: WorkflowManager): void; export declare function renderPanel(manager: WorkflowManager, theme: Theme, width?: number): string[]; /** Record a token-total sample for `runId` at time `now` (ms). */ export declare function sampleTokens(runId: string, total: number, now: number): void; /** Tokens/second over the rolling window; 0 when too few samples or totals plateau. */ export declare function tokensPerSecond(runId: string): number; /** Forget a run's samples (call when it finishes) so the map can't grow unbounded. */ export declare function clearTokenSamples(runId: string): void; /** Compact token count for the space-constrained panel: 980, 12.4K, 1.3M. */ export declare function fmtTokensShort(n: number): string; /** Normalize the configured per-phase agent cap to a sane integer (default 8). */ export declare function clampMaxAgents(value: number | undefined): number; /** * Detailed variant of {@link renderPanel}: per-run header with aggregate tokens, * cost, and a live token/s rate, followed by per-phase progress and per-agent rows * (capped at `maxAgents` per phase). `now` is injected for testability. */ export declare function renderPanelDetailed(manager: WorkflowManager, theme: Theme, width: number | undefined, maxAgents: number, now: number): string[]; /** * A self-contained view of one run for the reusable {@link renderWorkflowTree} * renderer. It carries the plain (persistable / manager-decoupled) data needed to * render a per-run header + the {@link renderRunBody} phase/agent tree, without a * live {@link WorkflowManager}. Fields mirror what {@link renderPanelDetailed} * reads from a `ManagedRun`/`PersistedRunState`. */ export interface RenderWorkflowRunView { /** Stable run id used to key the rolling token/s samples. */ runId: string; workflowName: string; status: string; /** Run-level token usage; only `cost` is read here (live totals come from agents). */ tokenUsage?: { total?: number; cost?: number; }; /** Declared phase order. Falls back to discovery order (as renderRunBody does). */ phases?: string[]; currentPhase?: string; /** Per-agent snapshots; `tokens`/`model`/`resultPreview`/`error` are all honored. */ agents: WorkflowAgentSnapshot[]; } /** Options for {@link renderWorkflowTree}. */ export interface RenderWorkflowTreeOptions { theme: Theme; /** Per-phase agent cap (mirrors {@link clampMaxAgents}); default 8. */ maxAgents?: number; /** Injected clock (ms) so the rolling token/s rate is deterministic in tests. */ now?: number; } /** * Render the full per-run phase/agent tree across the given run views and return * the lines (no `fitLine` width truncation — the monitor pane is free-form text). * * This is the reusable extraction of {@link renderPanelDetailed}'s per-run * rendering: the same `◆`/`⏸` icon, bold name, dim meta (done/total · current phase * · total tokens · cost · tok/s rate) header, then the same {@link renderRunBody} * phase/agent body. `renderPanelDetailed` is intentionally left untouched (its * output stays byte-identical for the live task panel); this function exists so the * workflow monitor pane and tests can render the tree from plain run-view data * without a live manager. * * Returns `[]` when `runs` is empty (mirrors the live panel's no-active-runs case). */ export declare function renderWorkflowTree(runs: RenderWorkflowRunView[], { theme, maxAgents, now }: RenderWorkflowTreeOptions): string[]; /** * Install the live "workflows running" panel below the editor. Re-rendered on * every manager event. Informational only — the user opens the navigator with * /workflows. (`_pi` is kept for signature stability.) */ export declare function installTaskPanel(_pi: ExtensionAPI, manager: WorkflowManager, ui: ExtensionUIContext, opts?: TaskPanelOptions): void;