import { EventEmitter } from "node:events"; export type NodeKind = "orchestrator" | "leaf"; export type NodeStatus = "pending" | "running" | "cancelling" | "cancelled" | "completed" | "failed" | "escalated"; export interface UsageSnapshot { input: number; output: number; cacheRead: number; /** Peak (high-water) context-window size. Non-cumulative — see UsageDelta. */ context: number; } export interface NodeMetrics { turn: number; toolCount: number; errCount: number; } export interface OrchestratorNode { id: string; label: string; kind: NodeKind; parentId: string | null; children: string[]; status: NodeStatus; startedAt: number; endedAt?: number; usage: UsageSnapshot; model?: string; provider?: string; compression?: { calls: number; tokensSaved: number; }; metrics: NodeMetrics; iteration?: number; tailBuffer: string[]; unreadWarnings: number; firstTurnPreview?: string; lastTurnPreview?: string; promptPreview?: string; outcomePreview?: string; abortController?: AbortController; } export interface StartNodeOptions { parentId?: string; label?: string; kind?: NodeKind; promptPreview?: string; } export declare const MAX_TAIL_ENTRY_CHARS = 4096; export declare const MAX_PROMPT_PREVIEW_CHARS = 16384; /** Cap an entry for storage. Marks the cut so views can surface it. */ export declare function capTailEntry(raw: string, max?: number): string; export declare class OrchestratorTree extends EventEmitter { private nodes; private roots; startNode(id: string, opts?: StartNodeOptions): OrchestratorNode; completeNode(id: string, status: NodeStatus): void; setNodeUsage(id: string, usage: UsageSnapshot): void; setNodeModel(id: string, model: string, provider: string): void; setNodeCompression(id: string, compression: { calls: number; tokensSaved: number; }): void; bumpNodeTurn(id: string): void; incrementNodeToolCount(id: string, delta?: number): void; incrementNodeErrCount(id: string, delta?: number): void; setNodeIteration(id: string, iteration: number): void; setNodeOutcome(id: string, preview: string): void; appendTail(id: string, line: string, opts?: { warning?: boolean; }): void; markTailRead(id: string): void; setTurnPreview(id: string, preview: string): void; requestCancel(id: string): boolean; getAbortSignal(id: string): AbortSignal | undefined; getNode(id: string): OrchestratorNode | undefined; getChildren(id: string): OrchestratorNode[]; getAncestors(id: string): OrchestratorNode[]; getRoots(): OrchestratorNode[]; /** Active roots: all roots if any are running/cancelling, otherwise * only non-terminal roots. Prunes stale terminal roots that have no * running descendants — the dashboard should not show completed sprints * from prior invocations alongside the current one. */ getActiveRoots(): OrchestratorNode[]; /** Returns true if every node in the subtree rooted at `id` has reached a * terminal state (completed, failed, cancelled, or escalated). */ private isSubtreeTerminal; /** Re-parent a node from its current position to a new parent (or to root * if newParentId is null). Removes from old parent's children and/or * roots, adds to new parent's children and/or roots, and updates the * node's parentId field. */ private reparentNode; getSubtreeUsage(id: string): UsageSnapshot; getSubtreeProgress(id: string): { completed: number; total: number; }; /** Depth of a node (root = 0). Useful for tree indentation. */ getDepth(id: string): number; private evictIfNeeded; private removeSubtree; } export declare function getOrchestratorTree(): OrchestratorTree;