typescript/selection-state-unification.md
We currently have two main data sources for UI selection state:
selectedNodeIdAtom / useSelectedNode() – legacy atom used by graph-specific features (detail panel, execution sync) to know the active node.unifiedSelectionAtom – newer atom introduced for PromptPreview + graph integration. It already mirrors functionName, testName, activeWorkflowId, and selectedNodeId. DebugPanel clicks and code-navigation update both the graph atoms and this unified atom.This duality leads to complexity and bugs (state drift when one atom updates but the other doesn’t). The long-term goal is to have a single source of truth, ideally unifiedSelectionAtom.
Inventory Consumers
useSelectedNode(), selectedNodeIdAtom, or their write helpers (e.g., setSelectedNodeId). Key areas include detail panel components, input-library selectors, execution sync, navigation heuristics.Introduce Read Adapters
useUnifiedSelectedNode() that read unifiedSelectionAtom.selectedNodeId. Start by migrating read-only consumers (places that only need the current node id) to this adapter. The legacy hook can internally read the unified atom so we change behavior without touching every consumer at once.Centralize Writes
unifiedSelectionAtom. Provide helper functions if needed (e.g., setGraphSelection({ nodeId, workflowId })). Deprecate direct use of setSelectedNodeId once all writers are converted.Update Derived Hooks
useActiveNode, detail panel selectors, and input-source logic should be refactored to depend on the unified state. Where they currently compute derived data off selectedNodeIdAtom, swap to unifiedSelectionAtom.selectedNodeId.Remove Legacy Atom
selectedNodeIdAtom directly, delete the atom and update SDK storage hooks to drop any dependencies. This also simplifies useGraphSync and navigation since they no longer have to coordinate two atoms.Regression Tests
unified-selection-sync.test.ts (or add a new test) to mount a minimal GraphView + DebugPanel setup. Verify that clicking nodes/functions updates the unified selection once and that detail-panel state follows. Also add tests around useCodeNavigation to ensure workflow switches still clear node selection properly.selectedNodeIdAtom. Missing a write path could leave parts of the UI (detail panel, execution I/O) stuck because they never see selection changes.selectedNodeId to exit LLM-only mode) might hinge on selectedNodeIdAtom side effects. Centralizing selection means re-implementing those side effects around the unified atom.Following this plan gives us a single, well-defined selection state that all features can rely on, reducing bugs like “graph view doesn’t show LLM tabs when clicking nodes” and making future features (e.g., cross-panel sync) simpler.