From b9cf6042f4100476dfe0313685a4bfae226df21e Mon Sep 17 00:00:00 2001 From: shrimbly Date: Tue, 13 Jan 2026 07:54:54 +1300 Subject: [PATCH] docs(16-01): complete extract localStorage and node defaults plan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tasks completed: 3/3 - Create store utilities module (localStorage.ts) - Create node defaults module (nodeDefaults.ts) - Add unit tests for extracted modules SUMMARY: .planning/phases/16-store-modularization/16-01-SUMMARY.md Reduced workflowStore.ts by 239 lines (2786 → 2547) Added 35 new tests (total: 147) --- .planning/ROADMAP.md | 277 ++++++++++++++++++ .planning/STATE.md | 131 +++++++++ .../16-store-modularization/16-01-SUMMARY.md | 124 ++++++++ 3 files changed, 532 insertions(+) create mode 100644 .planning/ROADMAP.md create mode 100644 .planning/STATE.md create mode 100644 .planning/phases/16-store-modularization/16-01-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md new file mode 100644 index 00000000..a3834137 --- /dev/null +++ b/.planning/ROADMAP.md @@ -0,0 +1,277 @@ +# Roadmap: Node Banana Multi-Provider Support + +## Overview + +Transform Node Banana from a Gemini-only image generator into a multi-provider platform supporting Replicate and fal.ai. The journey builds provider infrastructure first, then adds dynamic model discovery, refactors the generate node for flexibility, creates a searchable model browser, adds local image serving for URL-based providers, and finishes with video support and polish. + +## Domain Expertise + +None + +## Milestones + +- ✅ **v1.0 Multi-Provider Support** - Phases 1-6 (shipped 2026-01-11) +- ✅ **v1.1 Improvements** - Phases 7-14 (shipped 2026-01-12) +- 🚧 **v1.2 Improvements** - Phases 15-20 (in progress) + +## Phases + +**Phase Numbering:** +- Integer phases (1, 2, 3): Planned milestone work +- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED) + +
+✅ v1.0 Multi-Provider Support (Phases 1-6) - SHIPPED 2026-01-11 + +### Phase 1: Provider Infrastructure +**Goal**: Users can configure Replicate and fal.ai API keys in settings, with keys securely stored +**Depends on**: Nothing (first phase) +**Research**: Unlikely (internal UI patterns, Zustand state management) +**Plans**: 2 plans + +Plans: +- [x] 01-01: Provider settings UI in ProjectSetupModal +- [x] 01-02: Provider abstraction layer and types + +### Phase 2: Model Discovery +**Goal**: App can fetch and cache available models from enabled providers at runtime +**Depends on**: Phase 1 +**Research**: Likely (external APIs) +**Research topics**: Replicate model listing API endpoints, fal.ai model discovery endpoints, response schemas and pagination +**Plans**: 3 plans + +Plans: +- [x] 02-01: Replicate model fetching API route +- [x] 02-02: fal.ai model fetching API route +- [x] 02-03: Model caching and unified model interface + +### Phase 3: Generate Node Refactor +**Goal**: NanoBanana node becomes GenerateImage node supporting any provider's image models +**Depends on**: Phase 2 +**Research**: Unlikely (internal refactoring using existing patterns) +**Design decision**: Separate nodes for image vs video generation (GenerateVideo added in Phase 6) +**Plans**: 3 plans + +Plans: +- [x] 03-01: Rename NanoBanana to GenerateImage, add model selector (image models only) +- [x] 03-02: Provider-specific execution in generate API route +- [x] 03-03: Backward compatibility for existing workflows + +### Phase 4: Model Search Dialog +**Goal**: Users can browse models via floating action bar icons and searchable dialog +**Depends on**: Phase 3 +**Research**: Unlikely (internal UI using React patterns) +**Plans**: 2 plans + +Plans: +- [x] 04-01: Floating action bar with provider icons +- [x] 04-02: Model search dialog with filtering and selection + +### Phase 5: Image URL Server +**Goal**: Local API endpoint serves workflow images as URLs for providers requiring URL inputs +**Depends on**: Phase 3 +**Research**: Unlikely (Next.js API routes, existing patterns) +**Plans**: 2 plans + +Plans: +- [x] 05-01: Image serving endpoint and URL generation +- [x] 05-02: Integration with generate node for URL-based providers + +### Phase 6: Video & Polish +**Goal**: GenerateVideo node for video generation, video playback, custom parameters, edge cases +**Depends on**: Phase 5 +**Research**: Likely (video handling) +**Research topics**: HTML5 video element for base64/blob URLs, provider response formats for video content +**Design decision**: GenerateVideo as separate node type (not combined with GenerateImage) +**Plans**: 4 plans + +Plans: +- [x] 06-01: GenerateVideo node with video-capable model selector +- [x] 06-02: Video playback in output node +- [x] 06-03: Custom model parameters from provider schemas +- [x] 06-04: Edge case handling and final polish + +
+ +
+✅ v1.1 Improvements (Phases 7-14) - SHIPPED 2026-01-12 + +**Milestone Goal:** Fix connection issues, improve error visibility, add video history, auto-size nodes, and polish UI + +#### Phase 7: Video Connections ✅ + +**Goal**: Fix video handle connections to only allow valid targets (generateVideo, output) +**Depends on**: Phase 6 +**Research**: Unlikely (internal connection validation patterns) +**Plans**: 1 plan + +Plans: +- [x] 07-01: Add video handle type and connection validation + +#### Phase 8: Error Display ✅ + +**Goal**: Better error visibility with overlay display, not hidden by previous output +**Depends on**: Phase 7 +**Research**: Unlikely (internal UI patterns) +**Plans**: 1 plan + +Plans: +- [x] 08-01: Error notifications with persistent toast and node overlays + +#### Phase 9: Video History ✅ + +**Goal**: Add history carousel for generated videos matching image history pattern +**Depends on**: Phase 8 +**Research**: Unlikely (existing image history pattern) +**Plans**: 1 plan + +Plans: +- [x] 09-01: Video history types, store support, load API, and carousel UI + +#### Phase 10: Node Autosizing ✅ + +**Goal**: Auto-size nodes to output dimensions and aspect ratio +**Depends on**: Phase 9 +**Research**: Unlikely (React Flow node sizing) +**Plans**: 1 plan + +Plans: +- [x] 10-01: Node dimension utility and auto-resize on output + +#### Phase 11: UI Polish ✅ + +**Goal**: Flora UI alignment, header UI improvements, project settings, provider logos on nodes +**Depends on**: Phase 10 +**Research**: Unlikely (internal UI work) +**Plans**: 1 plan + +Plans: +- [x] 11-01: Provider badges on nodes and header UI streamlining + +#### Phase 12: Model Improvements ✅ + +**Goal**: Verify Replicate image models work, extend model cache TTL +**Depends on**: Phase 11 +**Research**: Likely (Replicate API behavior verification) +**Research topics**: Replicate image model endpoints, cache invalidation strategies +**Plans**: 1 plan + +Plans: +- [x] 12-01: Extended cache TTL, fixed isImageInput, fixed stale node data in execution + +#### Phase 13: Fix Duplicate Generations ✅ + +**Goal**: Fix image deduplication - generations folder has duplicate images due to hashing failure +**Depends on**: Phase 12 +**Research**: Likely (investigate current hashing implementation) +**Research topics**: Current save-generation hashing logic, why duplicates are being created +**Plans**: 1 plan + +Plans: +- [x] 13-01: Add MD5 content hashing and deduplication to save-generation API + +#### Phase 14: Fix Drag-Connect Node Creation Bugs ✅ + +**Goal**: Fix bugs with nodes created via drag-connect: (1) connection vanishes after selecting model from browser, (2) defaults to Gemini with missing model selector in header +**Depends on**: Phase 13 +**Research**: Unlikely (React Flow connection state, node creation flow) +**Research topics**: Connection state during node creation, model selection callbacks, createDefaultNodeData initialization +**Plans**: 1 plan + +Plans: +- [x] 14-01: Normalize dynamic handle IDs and fix connection persistence + +
+ +### 🚧 v1.2 Improvements (In Progress) + +**Milestone Goal:** Add automated testing across the application and modularize large monolithic files for better maintainability + +#### Phase 15: Test Infrastructure + +**Goal**: Set up testing framework with Vitest and React Testing Library for Next.js 16 +**Depends on**: Phase 14 +**Research**: Likely (Vitest + Next.js 16 App Router setup) +**Research topics**: Vitest configuration for Next.js 16, React Testing Library setup, test file organization +**Plans**: TBD + +Plans: +- [x] 15-01: React Testing Library setup and configuration + +#### Phase 16: Store Modularization ✅ + +**Goal**: Break up workflowStore.ts into focused modules (execution, nodes, edges, persistence) +**Depends on**: Phase 15 +**Research**: Unlikely (internal Zustand patterns) +**Plans**: 1 plan + +Plans: +- [x] 16-01: Extract localStorage helpers and node defaults to utility modules + +#### Phase 17: Component Tests + +**Goal**: Add tests for key node components and UI interactions +**Depends on**: Phase 16 +**Research**: Unlikely (established React Testing Library patterns) +**Plans**: TBD + +Plans: +- [ ] 17-01: TBD (run /gsd:plan-phase 17 to break down) + +#### Phase 18: API Route Tests + +**Goal**: Add tests for generate, llm, and workflow API routes +**Depends on**: Phase 17 +**Research**: Unlikely (Next.js API route testing patterns) +**Plans**: TBD + +Plans: +- [ ] 18-01: TBD (run /gsd:plan-phase 18 to break down) + +#### Phase 19: Type Refactoring + +**Goal**: Split types/index.ts into domain-specific type files (nodes, providers, workflow) +**Depends on**: Phase 18 +**Research**: Unlikely (internal refactoring) +**Plans**: TBD + +Plans: +- [ ] 19-01: TBD (run /gsd:plan-phase 19 to break down) + +#### Phase 20: Integration Tests + +**Goal**: End-to-end workflow execution tests covering node connections and data flow +**Depends on**: Phase 19 +**Research**: Unlikely (internal testing patterns) +**Plans**: TBD + +Plans: +- [ ] 20-01: TBD (run /gsd:plan-phase 20 to break down) + +## Progress + +**Execution Order:** +Phases execute in numeric order: 1 → 2 → ... → 14 → 15 → 16 → 17 → 18 → 19 → 20 + +| Phase | Milestone | Plans Complete | Status | Completed | +|-------|-----------|----------------|--------|-----------| +| 1. Provider Infrastructure | v1.0 | 2/2 | Complete | 2026-01-09 | +| 2. Model Discovery | v1.0 | 3/3 | Complete | 2026-01-09 | +| 3. Generate Node Refactor | v1.0 | 3/3 | Complete | 2026-01-09 | +| 4. Model Search Dialog | v1.0 | 2/2 | Complete | 2026-01-09 | +| 5. Image URL Server | v1.0 | 2/2 | Complete | 2026-01-09 | +| 6. Video & Polish | v1.0 | 4/4 | Complete | 2026-01-11 | +| 7. Video Connections | v1.1 | 1/1 | Complete | 2026-01-12 | +| 8. Error Display | v1.1 | 1/1 | Complete | 2026-01-12 | +| 9. Video History | v1.1 | 1/1 | Complete | 2026-01-12 | +| 10. Node Autosizing | v1.1 | 1/1 | Complete | 2026-01-12 | +| 11. UI Polish | v1.1 | 1/1 | Complete | 2026-01-12 | +| 12. Model Improvements | v1.1 | 1/1 | Complete | 2026-01-12 | +| 13. Fix Duplicate Generations | v1.1 | 1/1 | Complete | 2026-01-12 | +| 14. Fix Drag-Connect Node Creation Bugs | v1.1 | 1/1 | Complete | 2026-01-12 | +| 15. Test Infrastructure | v1.2 | 1/1 | Complete | 2026-01-12 | +| 16. Store Modularization | v1.2 | 1/1 | Complete | 2026-01-12 | +| 17. Component Tests | v1.2 | 0/? | Not started | - | +| 18. API Route Tests | v1.2 | 0/? | Not started | - | +| 19. Type Refactoring | v1.2 | 0/? | Not started | - | +| 20. Integration Tests | v1.2 | 0/? | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md new file mode 100644 index 00000000..5bc63bfc --- /dev/null +++ b/.planning/STATE.md @@ -0,0 +1,131 @@ +# Project State + +## Project Reference + +See: .planning/PROJECT.md (updated 2026-01-09) + +**Core value:** Provider infrastructure that dynamically discovers models from external APIs, enabling users to access hundreds of image/video generation models without hardcoding schemas. +**Current focus:** Testing and modularization (v1.2) + +## Current Position + +Phase: 16 of 20 (Store Modularization) +Plan: 1 of 1 in current phase +Status: Phase complete +Last activity: 2026-01-12 - Completed 16-01-PLAN.md + +Progress: ████████░░ 80% (Phase 16 complete) + +## Performance Metrics + +**Velocity:** +- Total plans completed: 24 +- Average duration: 7 min +- Total execution time: 2.9 hours + +**By Phase:** + +| Phase | Plans | Total | Avg/Plan | +|-------|-------|-------|----------| +| 1. Provider Infrastructure | 2/2 | 14 min | 7 min | +| 2. Model Discovery | 3/3 | 14 min | 4.7 min | +| 3. Generate Node Refactor | 3/3 | 13 min | 4.3 min | +| 4. Model Search Dialog | 2/2 | 17 min | 8.5 min | +| 5. Image URL Server | 2/2 | 5 min | 2.5 min | +| 6. Video & Polish | 4/4 | 43 min | 14.3 min | +| 7. Video Connections | 1/1 | 4 min | 4 min | +| 8. Error Display | 1/1 | 14 min | 14 min | +| 9. Video History | 1/1 | 12 min | 12 min | +| 10. Node Autosizing | 1/1 | 2 min | 2 min | +| 11. UI Polish | 1/1 | 8 min | 8 min | +| 12. Model Improvements | 1/1 | - | - | +| 13. Fix Duplicate Generations | 1/1 | 1 min | 1 min | +| 14. Fix Drag-Connect Bugs | 1/1 | 7 min | 7 min | +| 15. Test Infrastructure | 1/1 | 3 min | 3 min | +| 16. Store Modularization | 1/1 | 22 min | 22 min | + +**Recent Trend:** +- Last 5 plans: 8 min, 1 min, 7 min, 3 min, 22 min +- Trend: Larger refactoring tasks take longer but establish patterns + +## Accumulated Context + +### Decisions + +Decisions are logged in PROJECT.md Key Decisions table. +Recent decisions affecting current work: + +- Gemini always enabled via env var (GEMINI_API_KEY), Replicate/fal.ai optional +- API keys stored in localStorage under node-banana-provider-settings key +- Local state in modal to avoid saving on every keystroke +- Provider config pattern: {id, name, enabled, apiKey, apiKeyEnvVar?} +- Provider registry uses self-registration pattern via registerProvider() +- Gemini remains special-cased in /api/generate for now, not yet migrated +- Capability inference from model name/description keywords +- fal.ai API key optional (works without but rate limited) +- fal.ai auth header: "Key {apiKey}" format (not Bearer) +- fal.ai category maps directly to ModelCapability (no inference) +- 1-hour cache TTL for model lists (extended from 10 min) +- Unified API at /api/models with header-based auth +- Provider dropdown shows Gemini always, others only if API key configured +- Aspect ratio/resolution controls shown only for Gemini provider +- Backward compatibility via aliases: NanoBananaNode, saveNanoBananaDefaults +- Server-side provider execution in API route (not client-side) +- Header-based API key passing: X-Replicate-API-Key, X-Fal-API-Key +- fal.ai sync API (fal.run) instead of queue-based async +- Dual migration approach: loadWorkflow migrates + UI effect for runtime +- fal.ai icon always visible in action bar (works without key but rate limited) +- Replicate icon only visible when API key is configured +- Client-side search filtering for Replicate (their search API unreliable) +- Show all capability badges to differentiate similar models +- Extract variant suffix from fal.ai model IDs for display name +- No TTL for image store - explicit cleanup pattern (callers delete after use) +- 256KB threshold for shouldUseImageUrl (Replicate recommendation) +- Gemini excluded from video node (doesn't support video generation) +- Large videos (>20MB) return URL instead of base64 to avoid memory issues +- Fetch schema from provider API at model selection time with 10-min cache +- Filter internal params, prioritize user-relevant ones (seed, steps, guidance) +- Collapsible parameters section to keep node UI compact +- Node autosizing constraints: 200-500px width, 200-600px height, ~100px chrome +- Provider badges prepend node title (left side) with w-4 h-4 icons +- Node titles show only model name (no "Generate Image/Video" prefix) +- BaseNode supports titlePrefix prop for icon prepending +- Header aligned for saved/unsaved states with same icon layout +- isImageInput() uses word-boundary checks (not substring) to avoid matching num_images +- Workflow execution gets fresh node data from store (not stale captured array) +- regenerateNode includes parameters in request body +- MD5 content hashing for generation deduplication (fast, collision resistance not critical) +- Hash prefix in filename for O(1) duplicate lookup +- Normalized handle IDs (image, text, image-0) for connection stability across model changes +- Handle-to-schema mapping built at execution time from inputSchema +- Placeholder handles (dimmed 30%) for input types not used by model, preserving connections +- ReactFlowProvider wrapper for component tests using @xyflow/react hooks +- Zustand store mocking with vi.mock pattern returning mocked functions +- Vitest jsdom environment for React component tests +- Store utilities extracted to src/store/utils/ with re-exports for backward compatibility +- Consolidated defaultNodeDimensions (was duplicated in addNode and createGroup) +- localStorage mocking pattern for testing utility modules + +### Deferred Issues + +- UAT-001: Resolved - Provider icons now use real Replicate/fal.ai logos +- ISS-001: Resolved - Generate nodes now adapt to model requirements via dynamic parameters + +### Blockers/Concerns + +- Pre-existing lint configuration issue (ESLint not configured). Not blocking development. + +### Roadmap Evolution + +- v1.0 Multi-Provider Support shipped: 6 phases (Phase 1-6), 15 plans +- Milestone v1.1 Improvements created: 6 phases (Phase 7-12), improvements and polish +- Phase 13 added: Fix duplicate generations (hashing failure investigation) +- Phase 14 added: Fix drag-connect node creation bugs (consolidated from two phases) +- Milestone v1.2 Improvements created: 6 phases (Phase 15-20), testing and modularization + +## Session Continuity + +Last session: 2026-01-12 +Stopped at: Phase 16 complete +Resume file: None +Next action: Plan Phase 17 (run /gsd:plan-phase 17) diff --git a/.planning/phases/16-store-modularization/16-01-SUMMARY.md b/.planning/phases/16-store-modularization/16-01-SUMMARY.md new file mode 100644 index 00000000..235e62bc --- /dev/null +++ b/.planning/phases/16-store-modularization/16-01-SUMMARY.md @@ -0,0 +1,124 @@ +--- +phase: 16-store-modularization +plan: 01 +subsystem: store +tags: [zustand, localStorage, refactoring, testing, modularization] + +# Dependency graph +requires: + - phase: 15-test-infrastructure + provides: Vitest testing framework and patterns +provides: + - localStorage utilities module (src/store/utils/localStorage.ts) + - Node defaults module (src/store/utils/nodeDefaults.ts) + - Unit tests for both modules (35 total) + - Shared defaultNodeDimensions (consolidated from duplicates) +affects: [store-modularization, component-tests, api-route-tests] + +# Tech tracking +tech-stack: + added: [] + patterns: + - Store utility extraction pattern (pure functions in utils/) + - Re-export for backward compatibility + - localStorage mocking with vi.stubGlobal + +key-files: + created: + - src/store/utils/localStorage.ts + - src/store/utils/nodeDefaults.ts + - src/store/utils/__tests__/localStorage.test.ts + - src/store/utils/__tests__/nodeDefaults.test.ts + modified: + - src/store/workflowStore.ts + +key-decisions: + - "Consolidated defaultNodeDimensions (was duplicated in addNode and createGroup)" + - "Re-export functions from workflowStore for backward compatibility" + - "Fixed createGroup missing generateVideo node type in dimensions" + +patterns-established: + - "Store utilities live in src/store/utils/" + - "Tests for store utilities use in-memory localStorage mock" + +issues-created: [] + +# Metrics +duration: 22min +completed: 2026-01-12 +--- + +# Phase 16 Plan 01: Extract localStorage and Node Defaults Summary + +**Extracted 239 lines from workflowStore.ts into focused utility modules with 35 new tests** + +## Performance + +- **Duration:** 22 min +- **Started:** 2026-01-12T18:25:43Z +- **Completed:** 2026-01-12T18:47:24Z +- **Tasks:** 3 +- **Files modified:** 4 created, 1 modified + +## Accomplishments + +- Extracted all localStorage helpers into `src/store/utils/localStorage.ts` (130 lines) +- Extracted node creation utilities into `src/store/utils/nodeDefaults.ts` (120 lines) +- Created 35 unit tests for extracted modules (19 localStorage + 16 nodeDefaults) +- Consolidated duplicated defaultNodeDimensions constant +- Fixed missing generateVideo type in createGroup's dimension lookup +- Maintained full backward compatibility via re-exports + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Create store utilities module** - `836c77e` (refactor) +2. **Task 2: Create node defaults module** - `cf66751` (refactor) +3. **Task 3: Add unit tests for extracted modules** - `3d5cde7` (test) + +## Files Created/Modified + +- `src/store/utils/localStorage.ts` - Storage keys, workflow configs, cost data, provider settings helpers +- `src/store/utils/nodeDefaults.ts` - createDefaultNodeData, defaultNodeDimensions, GROUP_COLORS +- `src/store/utils/__tests__/localStorage.test.ts` - 19 tests for localStorage utilities +- `src/store/utils/__tests__/nodeDefaults.test.ts` - 16 tests for node defaults utilities +- `src/store/workflowStore.ts` - Reduced from 2786 to 2547 lines (-239) + +## Decisions Made + +- Consolidated defaultNodeDimensions: Previously duplicated in addNode and createGroup with inconsistency (createGroup was missing generateVideo) +- Re-export strategy: Functions like `saveNanoBananaDefaults`, `generateWorkflowId`, `GROUP_COLORS` re-exported from workflowStore for existing import compatibility +- Type assertions remain in workflowStore: Node data type imports kept since they're used for runtime type assertions in getConnectedInputs and executeWorkflow + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Fixed missing generateVideo in createGroup dimensions** +- **Found during:** Task 2 (Node defaults extraction) +- **Issue:** createGroup's local defaultNodeDimensions was missing generateVideo type, causing fallback to generic {300, 280} +- **Fix:** Consolidated to shared defaultNodeDimensions that includes all 8 node types +- **Files modified:** src/store/utils/nodeDefaults.ts, src/store/workflowStore.ts +- **Verification:** TypeScript compilation passes, groups with video nodes size correctly +- **Committed in:** cf66751 (Task 2 commit) + +--- + +**Total deviations:** 1 auto-fixed (bug), 0 deferred +**Impact on plan:** Bug fix was essential for consistency. No scope creep. + +## Issues Encountered + +None - plan executed smoothly. + +## Next Phase Readiness + +- Store utilities extracted and tested +- 147 total tests passing (112 existing + 35 new) +- Pattern established for future store modularization +- Ready for Phase 17 (Component Tests) or continued Phase 16 work on execution/persistence extraction + +--- +*Phase: 16-store-modularization* +*Completed: 2026-01-12*