/** * Auto-Layout for Agent Spec Flows * * Agent Spec has no visual position information. This module assigns * positions to imported nodes using a layered layout algorithm: * * 1. Topological sort from StartNode using control-flow edges * 2. Assign layers based on longest path from StartNode * 3. Position nodes with configurable spacing * 4. Fan out branches vertically from BranchingNode */ import type { AgentSpecFlow } from '../../types/agentspec.js'; /** Measured dimensions for a node */ export interface NodeDimensions { width: number; height: number; } /** Layout configuration */ export interface AutoLayoutConfig { /** Minimum horizontal gap between the right edge of one layer and the left edge of the next (px) */ horizontalGap: number; /** Minimum vertical gap between the bottom edge of one node and the top edge of the next in the same layer (px) */ verticalGap: number; /** Starting X position */ startX: number; /** Starting Y position */ startY: number; /** Fallback node width when measured dimensions are unavailable */ defaultNodeWidth: number; /** Fallback node height when measured dimensions are unavailable */ defaultNodeHeight: number; } /** * Compute node positions for an Agent Spec flow using layered layout. * Takes actual node dimensions into account to prevent overlap. * * @param flow - The Agent Spec flow to layout * @param config - Optional layout configuration * @param nodeDimensions - Optional map of node name to measured {width, height} * @returns Map of node name to {x, y} position */ export declare function computeAutoLayout(flow: AgentSpecFlow, config?: Partial, nodeDimensions?: Map): Map; /** Input position for beautify: existing node placement */ export interface NodePosition { x: number; y: number; } /** Beautify configuration */ export interface BeautifyLayoutConfig { /** Minimum horizontal gap between the right edge of one column and the left edge of the next (px) */ horizontalGap: number; /** Minimum vertical gap between the bottom edge of one node and the top edge of the next in the same column (px) */ verticalGap: number; /** Fallback node width when measured dimensions are unavailable */ defaultNodeWidth: number; /** Fallback node height when measured dimensions are unavailable */ defaultNodeHeight: number; } /** * Beautify existing node positions: preserve relative column/row ordering * but apply uniform spacing based on actual node dimensions. * * Algorithm: * 1. Cluster nodes into columns by X proximity (gap threshold = median width) * 2. Sort columns left-to-right by their median X * 3. Within each column, sort nodes top-to-bottom by their original Y * 4. Re-position with uniform horizontal and vertical gaps * * @param positions - Current node positions (keyed by node id) * @param config - Optional spacing configuration * @param nodeDimensions - Optional map of node id to measured {width, height} * @returns Map of node id to new {x, y} position */ export declare function computeBeautifyLayout(positions: Map, config?: Partial, nodeDimensions?: Map): Map;