/** * InstanceRouter — request routing with switch lock (Phase 2b) * * Routes tool requests to the currently selected Godot instance. * Instance switching is atomic: in-flight requests complete before the switch. */ import type { InstanceInfo } from './instance-manager.js'; import type { ToolResult } from '../types.js'; export interface RouterDependencies { instances: InstanceInfo[]; sendToInstance: (instance: InstanceInfo, toolName: string, args: Record) => Promise; onInstanceChanged?: (instance: InstanceInfo | null) => void; } export declare class InstanceRouter { private deps; /** H-01: O(1) lookup cache, rebuilt on updateInstances() */ private instanceMap; private selectedId; private inflightCount; private inflightZeroResolve; /** I-11: Draining flag — blocks new route() calls while selectInstance waits for in-flight to drain. */ private draining; constructor(deps: RouterDependencies); /** Rebuild the Map from the current instances array (copy-on-write). */ private rebuildMap; /** Get currently selected instance id. */ getSelectedId(): string | null; /** Get the currently selected InstanceInfo, or null. */ getSelectedInstance(): InstanceInfo | null; /** * Auto-select instance based on count: * - 0 instances → null * - 1 instance → auto-select * - 2+ instances → null (requires explicit selection) */ autoSelect(): string | null; /** Select instance by id. Throws if not found. */ selectInstance(id: string): Promise; /** Select instance by project path. Returns selected id or null. * Only safe during initialization (no concurrent route() calls). * Throws if draining is active (instance switch in progress). */ selectInstanceByProject(projectPath: string): string | null; /** Route a tool request to the selected instance. Returns error string if no selection. */ route(toolName: string, args: Record): Promise; /** * Resolve the best port for the selected instance using a priority chain: * 1. Original port still alive (same id + port in current instances) * 2. Same projectPath — pick most recent heartbeat * 3. Single instance available — use its port * 4. No match — null */ resolvePort(): Promise; /** Update the available instances list (e.g. after rediscovery). */ updateInstances(instances: InstanceInfo[]): void; }