- MIGRATION_CLUSTERS.md: reactive dependency graph across 20 bridges/stores - PHASE1_STORE_AUDIT.md: 11 stores audited (3 clean, 5 bridge-dependent, 3 platform-specific) - ADR-001: dual-stack binding strategy (accepted, S-1+S-3 hybrid) - Settings domain migration: all 6 settings components + App.svelte + FilesTab migrated from settings-bridge to getBackend() calls
12 KiB
Migration Clusters: Reactive Dependency Graph Analysis
Phase 2 binding analysis — reactive state dependencies across stores, bridge adapters, and components.
Store Dependency Matrix
agents.svelte.ts
- Bridge imports: claude-messages (type only)
- Store imports: none
- Reactive state:
$state<AgentSession[]>(sessions) - Exported functions: getAgentSessions, getAgentSession, createAgentSession, updateAgentStatus, setAgentSdkSessionId, setAgentModel, appendAgentMessage(s), updateAgentCost, findChildByToolUseId, getChildSessions, getTotalCost, clearAllAgentSessions, removeAgentSession
- Consumed by stores: workspace, health, wake-scheduler
- Consumed by components: AgentPane, AgentPreviewPane, AgentTree, AgentCard, AgentSession, ContextTab, MetricsPanel, StatusBar, TeamAgentsPanel
- Consumed by utils: session-persistence, subagent-router, agent-dispatcher
workspace.svelte.ts
- Bridge imports: groups-bridge, btmsg-bridge
- Store imports: agents, health, conflicts, wake-scheduler
- Reactive state:
$state<GroupsFile | null>,$state<string>(activeGroupId),$state<WorkspaceTab>,$state<string | null>(activeProjectId),$state<Record<string, TerminalTab[]>>,$state<string | null>(focusFlash) - Exported functions: get*/set* for all state, switchGroup, load/saveWorkspace, add/remove/update Group/Project/Agent, terminal tab mgmt, event callbacks
- Consumed by stores: wake-scheduler
- Consumed by components: GlobalTabBar, ProjectGrid, ProjectBox, GroupAgentsPanel, CommandPalette, SettingsTab, DocsTab, SearchOverlay, TerminalTabs, SshTab, AgentSession, StatusBar, CommsTab, ProjectSettings
- Consumed by utils: auto-anchoring, agent-dispatcher (via waitForPendingPersistence)
health.svelte.ts
- Bridge imports: none
- Store imports: agents, conflicts
- Reactive state:
$state<Map>(trackers, stallThresholds),$state<number>(tickTs) - Exported functions: trackProject, untrackProject, setStallThreshold, updateProjectSession, recordActivity, recordToolDone, recordTokenSnapshot, start/stopHealthTick, setReviewQueueDepth, clearHealthTracking, getProjectHealth, getAllProjectHealth, getAttentionQueue, getHealthAggregates
- Consumed by stores: workspace (import clearHealthTracking), wake-scheduler
- Consumed by components: ProjectBox, ProjectHeader, MetricsPanel, StatusBar, AgentSession
- Consumed by utils: agent-dispatcher, attention-scorer (type only)
conflicts.svelte.ts
- Bridge imports: none (types/ids only)
- Store imports: none
- Reactive state:
$state<Map>(projectFileWrites, acknowledgedFiles, sessionWorktrees, agentWriteTimestamps) - Exported functions: setSessionWorktree, recordFileWrite, recordExternalWrite, getExternalConflictCount, getProjectConflicts, hasConflicts, getTotalConflictCount, acknowledgeConflicts, clearSessionWrites, clearProjectConflicts, clearAllConflicts
- Consumed by stores: workspace (import clearAllConflicts), health
- Consumed by components: ProjectBox, ProjectHeader, StatusBar
- Consumed by utils: agent-dispatcher
anchors.svelte.ts
- Bridge imports: anchors-bridge
- Store imports: none
- Reactive state:
$state<Map>(projectAnchors),$state<Set>(autoAnchoredProjects) - Exported functions: get/add/remove/change anchor(s), loadAnchorsForProject, hasAutoAnchored, markAutoAnchored, getAnchorSettings
- Consumed by components: AgentPane, ContextTab, AgentSession
- Consumed by utils: auto-anchoring, agent-dispatcher
theme.svelte.ts
- Bridge imports: settings-bridge
- Store imports: none
- Reactive state:
$state<ThemeId>,$state<ThemePalette | null> - Exported functions: getCurrentTheme, getXtermTheme, setTheme, initTheme, previewPalette, clearPreview, setCustomTheme, onThemeChange
- Consumed by components: TerminalPane, AgentPreviewPane, SettingsTab, AppearanceSettings, ThemeEditor
- Consumed by: App.svelte (init)
plugins.svelte.ts
- Bridge imports: plugins-bridge, settings-bridge
- Store imports: none
- Reactive state:
$state<PluginCommand[]>,$state<PluginEntry[]> - Exported functions: get/add/removePluginCommands, pluginEventBus, getPluginEntries, setPluginEnabled, loadAllPlugins, reloadAllPlugins, destroyAllPlugins
- Consumed by components: CommandPalette, SettingsTab, AdvancedSettings
- Consumed by: plugin-host.ts
machines.svelte.ts
- Bridge imports: remote-bridge
- Store imports: notifications
- Reactive state:
$state<Machine[]> - Exported functions: getMachines, getMachine, loadMachines, addMachine, removeMachine, connectMachine, disconnectMachine, init/destroyMachineListeners
- Consumed by components: (used by SettingsTab multi-machine section)
wake-scheduler.svelte.ts
- Bridge imports: bttask-bridge, audit-bridge
- Store imports: health, workspace, agents
- Reactive state:
$state<Map>(registrations, pendingWakes) - Exported functions: disableWakeScheduler, register/unregisterManager, updateManager*, getWakeEvent, consumeWakeEvent, forceWake, clearWakeScheduler
- Consumed by stores: workspace (import clearWakeScheduler)
- Consumed by components: ProjectBox, AgentSession, StatusBar
notifications.svelte.ts
- Bridge imports: notifications-bridge
- Store imports: none
- Reactive state:
$state<Toast[]>,$state<HistoryNotification[]> - Exported functions: getNotifications, notify, dismissNotification, addNotification, getNotificationHistory, getUnreadCount, markRead, markAllRead, clearHistory
- Consumed by stores: machines
- Consumed by components: ToastContainer, NotificationCenter, ProjectBox, AgentPane
- Consumed by utils: handle-error, global-error-handler, auto-anchoring, agent-dispatcher
layout.svelte.ts
- Bridge imports: session-bridge
- Store imports: none
- Reactive state:
$state<Pane[]>,$state<LayoutPreset>,$state<string | null>(focusedPaneId) - Exported functions: getPanes, getActivePreset, getFocusedPaneId, add/removePane, focusPane, setPreset, renamePaneTitle, setPaneGroup, restoreFromDb, getGridTemplate, getPaneGridArea
- Consumed by components: AgentPane (focusPane)
- Consumed by utils: detach (type only), subagent-router
settings-scope.svelte.ts
- Bridge imports: settings-bridge
- Store imports: none
- Reactive state:
$state<string | null>(activeProjectId),$state<Map>(overrideCache) - Exported functions: setActiveProject, getActiveProjectForSettings, scopedGet/Set, removeOverride, getOverrideChain, hasProjectOverride, invalidateSettingsCache
- Consumed by components: ProjectSettings
sessions.svelte.ts
- Bridge imports: none
- Store imports: none
- Reactive state:
$state<Session[]> - Exported functions: getSessions, addSession, removeSession
- Consumed by: (v2 legacy, minimal usage)
Migration Clusters
Clusters are groups of files that share reactive state and must migrate atomically.
Cluster 1: Pure State (No Bridge Dependencies)
Files: agents.svelte.ts, conflicts.svelte.ts, sessions.svelte.ts
Dependency: None on bridges. Pure in-memory reactive state.
Risk: LOW. These are self-contained state containers with zero platform coupling.
Migration: Move to @agor/stores immediately. No BackendAdapter wiring needed.
Cluster 2: Settings Domain
Files: settings-bridge.ts, settings-scope.svelte.ts, theme.svelte.ts, plugins.svelte.ts, custom-themes.ts
Dependency: All import settings-bridge.ts (Tauri invoke).
Component consumers: SettingsTab, FilesTab, AppearanceSettings, AgentSettings, OrchestrationSettings, SecuritySettings, AdvancedSettings, ProjectSettings, App.svelte
Risk: MEDIUM. settings-bridge is the most-imported bridge (13 consumers). Theme init runs at app startup. Plugin lifecycle depends on settings for enabled state.
Migration: Replace settings-bridge imports with getBackend().getSetting() / getBackend().setSetting(). Migrate settings-scope.svelte.ts and theme.svelte.ts first, then plugins.svelte.ts.
Cluster 3: Workspace + Groups
Files: workspace.svelte.ts, groups-bridge.ts, btmsg-bridge.ts
Dependency: Imports groups-bridge (Tauri invoke) and btmsg-bridge (agent registration).
Cross-store deps: Imports agents, health, conflicts, wake-scheduler (clear functions).
Risk: HIGH. Central orchestration hub. 15+ component consumers. switchGroup() cascades clears across 4 stores. loadWorkspace() is app bootstrap path.
Migration: Replace groups-bridge calls with BackendAdapter.loadGroups()/saveGroups(). btmsg registration needs a new BackendAdapter method or stays as a separate bridge.
Cluster 4: Notification + Error Handling
Files: notifications.svelte.ts, notifications-bridge.ts, handle-error.ts, global-error-handler.ts
Dependency: notifications-bridge (Tauri invoke for desktop notifications).
Risk: LOW-MEDIUM. notifications-bridge is a single function (sendDesktopNotification). Capability-gated by supportsDesktopNotifications. handle-error is consumed everywhere.
Migration: Replace sendDesktopNotification with capability-checked BackendAdapter call. handle-error stays as-is (it calls notify() which is pure state).
Cluster 5: Machine Management
Files: machines.svelte.ts, remote-bridge.ts
Dependency: remote-bridge (Tauri invoke + listen for WebSocket events).
Cross-store deps: imports notifications
Risk: MEDIUM. Event listener lifecycle (listen/unlisten). 12 IPC commands. Not in BackendAdapter yet.
Migration: Defer. Needs BackendAdapter extension for remote machine operations. Low priority (multi-machine is advanced feature).
Cluster 6: Layout + Session Persistence
Files: layout.svelte.ts, session-bridge.ts
Dependency: session-bridge (Tauri invoke for SQLite session CRUD).
Risk: MEDIUM. V2 legacy layout — v3 uses workspace store. Still consumed by AgentPane.focusPane and subagent-router.
Migration: Replace session-bridge calls with BackendAdapter (needs session methods). Can coexist during transition.
Cluster 7: Anchors
Files: anchors.svelte.ts, anchors-bridge.ts
Dependency: anchors-bridge (Tauri invoke for SQLite anchor CRUD).
Risk: LOW. Self-contained, small API surface (save, load, delete, updateType).
Migration: Replace anchors-bridge with BackendAdapter (needs anchor methods) or standalone bridge kept temporarily.
Cluster 8: Wake Scheduler
Files: wake-scheduler.svelte.ts, bttask-bridge.ts, audit-bridge.ts
Dependency: bttask-bridge (Tauri invoke for task listing), audit-bridge (Tauri invoke for audit logging).
Cross-store deps: Reads from health, workspace, agents.
Risk: MEDIUM-HIGH. Complex evaluation logic + timer management. Multiple bridge dependencies. Reads across 3 stores.
Migration: Last cluster. Depends on clusters 1, 3, 8 completing first.
Cluster Dependency Graph
Cluster 1 (Pure State)
|
+---> Cluster 3 (Workspace) depends on Cluster 1
| |
| +---> Cluster 8 (Wake Scheduler) depends on Clusters 1, 3, 4
|
+---> Cluster 4 (Notifications) standalone
|
+---> Cluster 6 (Layout) standalone
|
+---> Cluster 7 (Anchors) standalone
Cluster 2 (Settings) standalone
Cluster 5 (Machines) depends on Cluster 4
Recommended Migration Order
- Cluster 1: Pure State (agents, conflicts, sessions) -- zero risk, no bridges
- Cluster 2: Settings Domain -- most consumers, establishes BackendAdapter pattern
- Cluster 4: Notifications -- small bridge surface, enables error handling migration
- Cluster 7: Anchors -- self-contained, small
- Cluster 6: Layout -- v2 legacy, low priority
- Cluster 3: Workspace -- high risk, many cross-deps, central hub
- Cluster 5: Machines -- needs BackendAdapter extension
- Cluster 8: Wake Scheduler -- depends on everything else
Risk Assessment Summary
| Cluster | Risk | Reason |
|---|---|---|
| 1. Pure State | LOW | No platform deps, pure memory |
| 2. Settings | MEDIUM | 13 consumers, startup path, theme init |
| 3. Workspace | HIGH | Central hub, cascading clears, 15+ components |
| 4. Notifications | LOW-MEDIUM | Single bridge function, capability-gated |
| 5. Machines | MEDIUM | Event listeners, not in BackendAdapter yet |
| 6. Layout | MEDIUM | V2 legacy, session persistence |
| 7. Anchors | LOW | Small, self-contained |
| 8. Wake Scheduler | MEDIUM-HIGH | Multi-bridge, cross-store reads, timers |