diff --git a/.planning/phases/16-store-modularization/16-01-PLAN.md b/.planning/phases/16-store-modularization/16-01-PLAN.md
new file mode 100644
index 00000000..735a3e62
--- /dev/null
+++ b/.planning/phases/16-store-modularization/16-01-PLAN.md
@@ -0,0 +1,139 @@
+---
+phase: 16-store-modularization
+plan: 01
+type: execute
+---
+
+
+Extract localStorage helpers and configuration utilities from workflowStore.ts into dedicated modules.
+
+Purpose: Begin store modularization by extracting pure utility functions that don't depend on Zustand state, making them easier to test and reducing the main store file size.
+Output: New utility modules for localStorage operations and default node data creation, with workflowStore.ts importing from these modules.
+
+
+
+~/.claude/get-shit-done/workflows/execute-phase.md
+~/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/15-test-infrastructure/15-01-SUMMARY.md
+@src/store/workflowStore.ts
+
+**From Phase 15 Summary:**
+- Vitest and React Testing Library configured
+- Zustand store mocking patterns established
+- Test infrastructure ready for validating refactored modules
+
+**Current Store Analysis (2786 lines):**
+The workflowStore.ts contains several pure utility functions at the top that don't depend on Zustand state:
+- localStorage helpers for workflow configs (~40 lines)
+- localStorage helpers for cost tracking (~40 lines)
+- localStorage helpers for GenerateImage defaults (~40 lines)
+- localStorage helpers for provider settings (~50 lines)
+- createDefaultNodeData function (~90 lines)
+- GROUP_COLORS and GROUP_COLOR_ORDER constants (~15 lines)
+- generateWorkflowId utility (~3 lines)
+
+
+
+
+
+ Task 1: Create store utilities module
+ src/store/utils/localStorage.ts
+
+Extract all localStorage helpers into a new module:
+1. Create src/store/utils/localStorage.ts
+2. Move these functions/constants:
+ - STORAGE_KEY constant
+ - COST_DATA_STORAGE_KEY constant
+ - GENERATE_IMAGE_DEFAULTS_KEY constant
+ - PROVIDER_SETTINGS_KEY constant
+ - loadSaveConfigs()
+ - saveSaveConfig()
+ - loadWorkflowCostData()
+ - saveWorkflowCostData()
+ - loadGenerateImageDefaults() (rename from loadNanoBananaDefaults)
+ - saveGenerateImageDefaults() (existing export, keep as-is)
+ - getProviderSettings()
+ - saveProviderSettings()
+ - defaultProviderSettings constant
+ - GenerateImageDefaults interface
+3. Export all functions and types
+4. Keep backward-compatible aliases (NanoBananaDefaults, saveNanoBananaDefaults) in workflowStore.ts but have them re-export from the new module
+
+Note: These functions use localStorage directly and don't depend on Zustand state, making them safe to extract.
+
+ npm run build succeeds with no TypeScript errors
+ All localStorage helpers extracted, workflowStore.ts imports from new module, build passes
+
+
+
+ Task 2: Create node defaults module
+ src/store/utils/nodeDefaults.ts
+
+Extract node creation utilities:
+1. Create src/store/utils/nodeDefaults.ts
+2. Move these items:
+ - createDefaultNodeData() function (~90 lines)
+ - defaultDimensions record (duplicated in addNode and createGroup - consolidate)
+ - GROUP_COLORS record
+ - GROUP_COLOR_ORDER array
+ - GroupColor type import from @/types
+3. The createDefaultNodeData function calls loadGenerateImageDefaults() - update import to use new localStorage module
+4. Export createDefaultNodeData, defaultNodeDimensions, GROUP_COLORS, GROUP_COLOR_ORDER
+5. Update workflowStore.ts to import these from the new module
+
+ npm run build succeeds, npm test passes all 112+ tests
+ Node defaults extracted, GROUP_COLORS exported from new location, all imports updated, tests pass
+
+
+
+ Task 3: Add unit tests for extracted modules
+ src/store/utils/__tests__/localStorage.test.ts, src/store/utils/__tests__/nodeDefaults.test.ts
+
+Create tests for the extracted modules:
+1. Create src/store/utils/__tests__/localStorage.test.ts:
+ - Test loadSaveConfigs returns empty object when localStorage empty
+ - Test saveSaveConfig stores and retrieves config
+ - Test loadWorkflowCostData handles missing data
+ - Test loadGenerateImageDefaults returns defaults when localStorage empty
+ - Test getProviderSettings merges with defaults for new providers
+ - Mock localStorage using vi.stubGlobal or in-memory implementation
+
+2. Create src/store/utils/__tests__/nodeDefaults.test.ts:
+ - Test createDefaultNodeData for each node type returns correct structure
+ - Test defaultNodeDimensions has all expected node types
+ - Test GROUP_COLORS has expected color keys
+ - Mock localStorage for createDefaultNodeData's loadGenerateImageDefaults call
+
+ npm test passes with new tests included, coverage for new modules
+ Unit tests added for both modules, all tests pass including new ones
+
+
+
+
+
+Before declaring plan complete:
+- [ ] `npm run build` succeeds without errors
+- [ ] `npm test` passes all tests (existing + new)
+- [ ] workflowStore.ts is reduced by ~280 lines
+- [ ] New modules are properly typed with exports
+- [ ] Backward compatibility maintained (saveNanoBananaDefaults still works)
+
+
+
+
+- All tasks completed
+- All verification checks pass
+- No TypeScript errors
+- workflowStore.ts imports from new utility modules
+- New modules have test coverage
+
+
+
diff --git a/.planning/phases/16-store-modularization/16-02-PLAN.md b/.planning/phases/16-store-modularization/16-02-PLAN.md
new file mode 100644
index 00000000..707a6482
--- /dev/null
+++ b/.planning/phases/16-store-modularization/16-02-PLAN.md
@@ -0,0 +1,168 @@
+---
+phase: 16-store-modularization
+plan: 02
+type: execute
+---
+
+
+Extract workflow execution logic from workflowStore.ts into a dedicated execution module.
+
+Purpose: The execution logic (~800 lines) is the largest section and most complex. Extracting it enables focused testing and cleaner separation of concerns between state management and execution orchestration.
+Output: New execution module with executeWorkflow, regenerateNode, and supporting execution utilities.
+
+
+
+~/.claude/get-shit-done/workflows/execute-phase.md
+~/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/16-store-modularization/16-01-PLAN.md
+@src/store/workflowStore.ts
+
+**Dependencies from 16-01:**
+- localStorage utilities extracted
+- nodeDefaults module exists
+
+**Execution Logic Analysis (~800 lines):**
+The executeWorkflow and regenerateNode functions are tightly coupled to store state but can be extracted as action creators that receive state getters/setters. Key components:
+- Topological sort algorithm (~30 lines)
+- Node execution switch statement (~600 lines for all node types)
+- API call patterns (repeated for each provider)
+- Logger calls throughout
+- State updates via updateNodeData
+
+
+
+
+
+ Task 1: Extract execution utilities
+ src/store/execution/utils.ts
+
+Create src/store/execution/utils.ts with reusable execution utilities:
+
+1. Extract topologicalSort function:
+ - Takes nodes and edges as input
+ - Returns sorted WorkflowNode array
+ - Throws on cycle detection
+
+2. Extract buildProviderHeaders function:
+ - Takes provider type and providerSettings
+ - Returns headers object with API key headers
+ - Consolidates the repeated header building logic from executeWorkflow/regenerateNode
+
+3. Extract getSourceOutput helper:
+ - Takes a WorkflowNode
+ - Returns { type: "image" | "text" | "video", value: string | null }
+ - Currently duplicated in getConnectedInputs
+
+4. Export types:
+ - ExecutionResult = { success: boolean; error?: string; data?: unknown }
+ - NodeExecutionContext = { nodeId: string; get: () => StoreState; set: (partial: Partial) => void }
+
+These are pure functions that don't directly depend on Zustand, making them testable.
+
+ npm run build succeeds, new module compiles without errors
+ Execution utilities extracted, types defined, build passes
+
+
+
+ Task 2: Extract node executors
+ src/store/execution/nodeExecutors.ts
+
+Create src/store/execution/nodeExecutors.ts with individual node type executors:
+
+1. Create executor type:
+ ```typescript
+ type NodeExecutor = (
+ node: WorkflowNode,
+ context: {
+ getConnectedInputs: (nodeId: string) => ConnectedInputs;
+ updateNodeData: (nodeId: string, data: Partial) => void;
+ get: () => WorkflowStoreState;
+ set: (partial: Partial) => void;
+ providerSettings: ProviderSettings;
+ }
+ ) => Promise<{ continue: boolean; error?: string }>;
+ ```
+
+2. Extract executors for each node type:
+ - executeImageInput (no-op, returns continue: true)
+ - executeAnnotation
+ - executePrompt (no-op)
+ - executeNanoBanana (image generation)
+ - executeGenerateVideo (video generation)
+ - executeLlmGenerate (text generation)
+ - executeSplitGrid
+ - executeOutput
+
+3. Create nodeExecutorMap:
+ ```typescript
+ const nodeExecutorMap: Record = { ... }
+ ```
+
+4. Export executeNode function that dispatches to the correct executor
+
+This keeps the individual node logic but allows testing each executor in isolation.
+
+ npm run build succeeds, no TypeScript errors
+ Node executors extracted as individual functions with shared interface
+
+
+
+ Task 3: Refactor executeWorkflow to use extracted modules
+ src/store/workflowStore.ts
+
+Update executeWorkflow in workflowStore.ts to use the extracted modules:
+
+1. Import from execution/utils.ts:
+ - topologicalSort
+ - buildProviderHeaders
+
+2. Import from execution/nodeExecutors.ts:
+ - executeNode
+
+3. Refactor executeWorkflow to use the imported utilities:
+ - Replace inline topological sort with topologicalSort()
+ - Replace switch statement with executeNode() calls
+ - Keep the overall orchestration logic (pause handling, locked groups, logging) in the store
+
+4. Refactor regenerateNode similarly:
+ - Use buildProviderHeaders
+ - Could call individual executors but for now keep inline (regenerate has slightly different flow)
+
+5. Ensure getConnectedInputs stays in the store (it needs edge state)
+
+The goal is to reduce executeWorkflow from ~800 lines to ~200 lines of orchestration logic.
+
+ npm run build succeeds, npm test passes, manual test of workflow execution works
+ executeWorkflow refactored to ~200 lines, uses extracted modules, all tests pass
+
+
+
+
+
+Before declaring plan complete:
+- [ ] `npm run build` succeeds without errors
+- [ ] `npm test` passes all tests
+- [ ] executeWorkflow function reduced from ~800 to ~200 lines
+- [ ] Workflow execution still works (test with a simple prompt -> generate -> output flow)
+- [ ] regenerateNode still works
+- [ ] Error handling preserved
+
+
+
+
+- All tasks completed
+- All verification checks pass
+- executeWorkflow is significantly shorter and more readable
+- Node execution logic is isolated and testable
+- No regression in workflow execution behavior
+
+
+
diff --git a/.planning/phases/16-store-modularization/16-03-PLAN.md b/.planning/phases/16-store-modularization/16-03-PLAN.md
new file mode 100644
index 00000000..3ec5e805
--- /dev/null
+++ b/.planning/phases/16-store-modularization/16-03-PLAN.md
@@ -0,0 +1,212 @@
+---
+phase: 16-store-modularization
+plan: 03
+type: execute
+---
+
+
+Extract remaining store slices into focused modules using Zustand slice pattern.
+
+Purpose: Break up the remaining monolithic store into logical slices (groups, clipboard, persistence, providers) that can be developed and tested independently while maintaining a single unified store.
+Output: Zustand slices for groups, clipboard, persistence, and provider settings, composed into the main store.
+
+
+
+~/.claude/get-shit-done/workflows/execute-phase.md
+~/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/16-store-modularization/16-01-PLAN.md
+@.planning/phases/16-store-modularization/16-02-PLAN.md
+@src/store/workflowStore.ts
+
+**Dependencies from 16-01 and 16-02:**
+- localStorage utilities extracted to src/store/utils/localStorage.ts
+- Node defaults extracted to src/store/utils/nodeDefaults.ts
+- Execution logic extracted to src/store/execution/
+
+**Remaining Store Sections:**
+After 16-01 and 16-02, the store still contains:
+- Group operations (~200 lines): createGroup, deleteGroup, addNodesToGroup, etc.
+- Clipboard operations (~100 lines): copySelectedNodes, pasteNodes, clearClipboard
+- Persistence operations (~300 lines): saveWorkflow, loadWorkflow, auto-save
+- Provider settings (~100 lines): updateProviderSettings, updateProviderApiKey
+- Core node/edge operations (~200 lines): These stay in main store
+- UI state (~50 lines): modal count, quickstart - stays in main store
+
+
+
+
+
+ Task 1: Create group operations slice
+ src/store/slices/groupSlice.ts
+
+Create src/store/slices/groupSlice.ts using Zustand slice pattern:
+
+1. Define GroupSlice interface:
+ ```typescript
+ interface GroupSlice {
+ groups: Record;
+ createGroup: (nodeIds: string[]) => string;
+ deleteGroup: (groupId: string) => void;
+ addNodesToGroup: (nodeIds: string[], groupId: string) => void;
+ removeNodesFromGroup: (nodeIds: string[]) => void;
+ updateGroup: (groupId: string, updates: Partial) => void;
+ toggleGroupLock: (groupId: string) => void;
+ moveGroupNodes: (groupId: string, delta: { x: number; y: number }) => void;
+ setNodeGroupId: (nodeId: string, groupId: string | undefined) => void;
+ }
+ ```
+
+2. Create slice creator function:
+ ```typescript
+ export const createGroupSlice: StateCreator<
+ WorkflowStore,
+ [],
+ [],
+ GroupSlice
+ > = (set, get) => ({
+ groups: {},
+ createGroup: (nodeIds) => { ... },
+ // ... other methods
+ });
+ ```
+
+3. Import GROUP_COLORS and GROUP_COLOR_ORDER from utils/nodeDefaults
+4. Import defaultNodeDimensions for bounding box calculation
+5. Manage groupIdCounter within the slice
+
+The slice needs access to nodes for createGroup bounding box calculation, which it gets via get().
+
+ npm run build succeeds, slice compiles without errors
+ Group slice created with all group operations
+
+
+
+ Task 2: Create persistence slice
+ src/store/slices/persistenceSlice.ts
+
+Create src/store/slices/persistenceSlice.ts:
+
+1. Define PersistenceSlice interface:
+ ```typescript
+ interface PersistenceSlice {
+ // State
+ workflowId: string | null;
+ workflowName: string | null;
+ saveDirectoryPath: string | null;
+ generationsPath: string | null;
+ lastSavedAt: number | null;
+ hasUnsavedChanges: boolean;
+ autoSaveEnabled: boolean;
+ isSaving: boolean;
+ useExternalImageStorage: boolean;
+
+ // Actions
+ setWorkflowMetadata: (id: string, name: string, path: string, generationsPath?: string | null) => void;
+ setWorkflowName: (name: string) => void;
+ setGenerationsPath: (path: string | null) => void;
+ setAutoSaveEnabled: (enabled: boolean) => void;
+ setUseExternalImageStorage: (enabled: boolean) => void;
+ markAsUnsaved: () => void;
+ saveToFile: () => Promise;
+ initializeAutoSave: () => void;
+ cleanupAutoSave: () => void;
+ saveWorkflow: (name?: string) => void;
+ loadWorkflow: (workflow: WorkflowFile, workflowPath?: string) => Promise;
+ clearWorkflow: () => void;
+ }
+ ```
+
+2. Move autoSaveIntervalId to slice file scope
+3. Import localStorage helpers from utils/localStorage
+4. Import externalizeWorkflowImages, hydrateWorkflowImages from @/utils/imageStorage
+5. Keep nodeIdCounter and groupIdCounter management in main store (loadWorkflow needs to update them)
+
+Note: loadWorkflow also needs to reset execution state (isRunning, currentNodeId) which stays in main store. The slice's loadWorkflow will need to call through to main store's set().
+
+ npm run build succeeds, slice compiles without errors
+ Persistence slice created with save/load/auto-save logic
+
+
+
+ Task 3: Compose slices into main store
+ src/store/workflowStore.ts
+
+Refactor workflowStore.ts to compose the slices:
+
+1. Import slices:
+ ```typescript
+ import { createGroupSlice, GroupSlice } from './slices/groupSlice';
+ import { createPersistenceSlice, PersistenceSlice } from './slices/persistenceSlice';
+ ```
+
+2. Define combined store type:
+ ```typescript
+ type WorkflowStore = CoreSlice & GroupSlice & PersistenceSlice & ExecutionSlice;
+ ```
+
+3. Update store creation using spread:
+ ```typescript
+ export const useWorkflowStore = create()((...args) => ({
+ // Core state and actions inline
+ nodes: [],
+ edges: [],
+ // ...
+
+ // Spread slices
+ ...createGroupSlice(...args),
+ ...createPersistenceSlice(...args),
+ }));
+ ```
+
+4. Keep in main store (CoreSlice):
+ - nodes, edges, edgeStyle state
+ - Node CRUD: addNode, updateNodeData, removeNode, onNodesChange
+ - Edge operations: onEdgesChange, onConnect, addEdgeWithType, removeEdge, toggleEdgePause
+ - getNodeById, getConnectedInputs, validateWorkflow
+ - UI state: openModalCount, isModalOpen, showQuickstart
+ - Execution state: isRunning, currentNodeId, pausedAtNodeId
+ - executeWorkflow, regenerateNode, stopWorkflow (uses extracted execution modules)
+ - globalImageHistory, incurredCost state and actions
+ - Provider settings state and actions
+ - Model search dialog state
+
+5. Export backward-compatible aliases (GROUP_COLORS, saveNanoBananaDefaults, etc.)
+
+Target: Main store file reduced from ~2800 to ~1500 lines.
+
+ npm run build succeeds, npm test passes all tests, manual test of group creation and save/load works
+ Store composed from slices, main file significantly reduced, all functionality preserved
+
+
+
+
+
+Before declaring plan complete:
+- [ ] `npm run build` succeeds without errors
+- [ ] `npm test` passes all tests
+- [ ] workflowStore.ts reduced from ~2800 to ~1500 lines
+- [ ] Group operations work (create, lock, delete)
+- [ ] Save/load workflow works
+- [ ] Auto-save works
+- [ ] All exports maintained for backward compatibility
+
+
+
+
+- All tasks completed
+- All verification checks pass
+- Store properly composed from slices
+- Each slice is focused and cohesive
+- No regression in any store functionality
+- Phase 16 complete: Store Modularization achieved
+
+
+