diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index a2b0cdc5..8dd7faf6 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -12,7 +12,7 @@ None
- ✅ **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-22 (in progress)
+- 🚧 **v1.2 Improvements** - Phases 15-23 (in progress)
## Phases
@@ -268,7 +268,7 @@ Plans:
**Depends on**: Phase 20
**Research**: Likely (Gemini API image input handling, current hashing implementation)
**Research topics**: Gemini 3 Pro image generation API requirements, why image inputs are ignored, current save logic for inputs vs generations
-**Plans**: TBD
+**Plans**: 1 plan
**Issues:**
1. nano-banana-pro model generates without considering image inputs (image data sent but not used)
@@ -276,7 +276,7 @@ Plans:
3. Generated images should be prepended with prompt details like generated videos
Plans:
-- [ ] 21-01: TBD (run /gsd:plan-phase 21 to break down)
+- [ ] 21-01: Fix Gemini image-to-image part ordering and unify MD5 hashing
#### Phase 22: Generate Node Dynamic Input Tests
@@ -295,10 +295,25 @@ Plans:
Plans:
- [ ] 22-01: ModelParameters tests, GenerateImageNode/GenerateVideoNode dynamic handle tests
+#### Phase 23: Model Browser Improvements
+
+**Goal**: Improve model browser UX with recently used models section, icon-based provider dropdown with Gemini, and include Gemini models in browse list
+**Depends on**: Phase 22
+**Research**: Unlikely (existing UI patterns)
+**Plans**: TBD
+
+**Features:**
+1. Recently used models section at top of browse dialog showing last 4 models used
+2. Provider dropdown uses icons instead of text, add Gemini to the provider list
+3. Include Gemini models (nano-banana, nano-banana-pro) in the browsable model list alongside Replicate/fal.ai models
+
+Plans:
+- [ ] 23-01: TBD (run /gsd:plan-phase 23 to break down)
+
## Progress
**Execution Order:**
-Phases execute in numeric order: 1 → 2 → ... → 14 → 15 → 16 → 17 → 18 → 19 → 20 → 21 → 22
+Phases execute in numeric order: 1 → 2 → ... → 14 → 15 → 16 → 17 → 18 → 19 → 20 → 21 → 22 → 23
| Phase | Milestone | Plans Complete | Status | Completed |
|-------|-----------|----------------|--------|-----------|
@@ -322,5 +337,6 @@ Phases execute in numeric order: 1 → 2 → ... → 14 → 15 → 16 → 17 →
| 18. API Route Tests | v1.2 | 5/5 | Complete | 2026-01-13 |
| 19. Type Refactoring | v1.2 | 0/? | Not started | - |
| 20. Integration Tests | v1.2 | 0/? | Not started | - |
-| 21. Fix Image Input & Deduplication | v1.2 | 0/? | Not started | - |
+| 21. Fix Image Input & Deduplication | v1.2 | 0/1 | Planned | - |
| 22. Generate Node Dynamic Input Tests | v1.2 | 0/1 | Planned | - |
+| 23. Model Browser Improvements | v1.2 | 0/? | Not started | - |
diff --git a/.planning/STATE.md b/.planning/STATE.md
index 21414726..0c14c569 100644
--- a/.planning/STATE.md
+++ b/.planning/STATE.md
@@ -9,10 +9,10 @@ See: .planning/PROJECT.md (updated 2026-01-09)
## Current Position
-Phase: 18 of 22 (API Route Tests)
-Plan: 5 of 5 in current phase
-Status: Phase complete
-Last activity: 2026-01-13 - Completed 18-05-PLAN.md
+Phase: 21 of 23 (Fix Image Input & Deduplication)
+Plan: 1 of 1 in current phase
+Status: Planned
+Last activity: 2026-01-13 - Created 21-01-PLAN.md
Progress: █████████░ 93%
@@ -124,10 +124,11 @@ Recent decisions affecting current work:
- Milestone v1.2 Improvements created: 6 phases (Phase 15-20), testing and modularization
- Phase 21 added: Fix Gemini Pro image input handling and image deduplication issues
- Phase 22 added: Generate node dynamic input validation and API call tests
+- Phase 23 added: Model browser improvements (recently used, icon dropdown, Gemini models in list)
## Session Continuity
Last session: 2026-01-13
-Stopped at: Phase 22 planned (1 plan created)
+Stopped at: Phase 21 planned (1 plan created)
Resume file: None
-Next action: Execute Phase 22 (run /gsd:execute-plan .planning/phases/22-generate-node-dynamic-input-tests/22-01-PLAN.md)
+Next action: Execute Phase 21 (run /gsd:execute-plan .planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md)
diff --git a/.planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md b/.planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md
new file mode 100644
index 00000000..6e65b31f
--- /dev/null
+++ b/.planning/phases/21-fix-image-input-deduplication/21-01-PLAN.md
@@ -0,0 +1,153 @@
+---
+phase: 21-fix-image-input-deduplication
+plan: 01
+type: execute
+---
+
+
+Fix Gemini nano-banana-pro model ignoring image inputs and resolve duplicate image saving across input/generated images.
+
+Purpose: Ensure image-to-image generation works correctly with Gemini and that the deduplication system consistently prevents duplicate files in the generations folder.
+Output: Working image-to-image generation with Gemini Pro, consistent hashing across all image saving operations.
+
+
+
+~/.claude/get-shit-done/workflows/execute-phase.md
+~/.claude/get-shit-done/templates/summary.md
+~/.claude/get-shit-done/references/checkpoints.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+
+# Key source files:
+@src/app/api/generate/route.ts
+@src/app/api/save-generation/route.ts
+@src/utils/imageStorage.ts
+
+# Prior phase with related hashing decision:
+@.planning/phases/13-fix-duplicate-generations/13-01-SUMMARY.md
+
+**Tech stack available:** Next.js 16, Zustand, @google/genai SDK
+**Established patterns:** MD5 content hashing for deduplication (Phase 13)
+
+**Issues being addressed:**
+1. nano-banana-pro model generates without considering image inputs (image data sent but not used)
+2. Input and generated images have duplicate files despite different hashes - need consistent hashing approach
+3. Generated images should be prepended with prompt details like generated videos
+
+**Research findings:**
+- Gemini SDK docs show that for image editing, the order matters: image should come BEFORE text in the parts array
+- Current implementation sends [text, ...images] but should send [...images, text] for image-to-image
+- imageStorage.ts uses position-based sampling hash while save-generation uses MD5 - these are incompatible
+
+
+
+
+
+ Task 1: Fix Gemini image-to-image part ordering
+ src/app/api/generate/route.ts
+
+In generateWithGemini(), change the requestParts array construction to place images BEFORE text prompt. The Gemini SDK documentation shows image editing works with [inlineData, text] order, not [text, inlineData].
+
+Current code (around line 59):
+```
+const requestParts = [
+ { text: prompt }, // Text first - WRONG for image-to-image
+ ...imageData.map(...) // Images second
+];
+```
+
+Change to:
+```
+const requestParts = [
+ ...imageData.map(...) // Images first - correct for image editing
+ { text: prompt }, // Text second
+];
+```
+
+WHY: Gemini's image generation models treat the first content type as primary input. For text-to-image, text should be first. For image-to-image (editing), images should be first so the model knows it's modifying existing images.
+
+IMPORTANT: Only reorder when images are present. If no images, text should still be the only part.
+
+
+Build succeeds with `npm run build`. Manual test: Create workflow with ImageInput → GenerateImage (nano-banana-pro) → Output, connect an image, add prompt like "make it blue", run workflow. Output should visually reference the input image.
+
+
+When images are connected to a Gemini GenerateImage node, the generated output incorporates/transforms the input image based on the prompt.
+
+
+
+
+ Task 2: Unify image hashing to MD5 across all save operations
+ src/utils/imageStorage.ts
+
+Replace the position-based sampling hash in imageStorage.ts with MD5 content hashing (matching save-generation/route.ts pattern).
+
+The current approach at line 209-211 uses a weak hash based on string length and sampled substrings:
+```
+const hash = `${folder}-${len}-${imageData.substring(50, 100)}-${imageData.substring(mid, mid + 50)}-${imageData.substring(Math.max(0, len - 50))}`;
+```
+
+This is problematic because:
+1. Different hash method than save-generation API (MD5)
+2. Same image can get different hashes if saved via different paths
+3. Position-based sampling is weak for dedup (similar images may have same samples)
+
+Replace with:
+1. Import crypto at top: `import crypto from "crypto";`
+2. Create helper: `function computeContentHash(data: string): string { return crypto.createHash("md5").update(data).digest("hex"); }`
+3. Replace the hash computation: `const hash = `${folder}-${computeContentHash(imageData)}`;` (folder prefix still needed to separate inputs/generations)
+
+WHY: MD5 is already used in save-generation (Phase 13 decision), provides reliable deduplication, and is fast enough for our use case.
+
+
+Build succeeds with `npm run build`. TypeScript types check with no errors.
+
+
+imageStorage.ts uses MD5 hashing, consistent with save-generation API. Same image saved twice gets same hash and is deduplicated.
+
+
+
+
+
+Fixed Gemini image-to-image generation (part ordering) and unified MD5 hashing for deduplication.
+
+
+ 1. Run: `npm run dev`
+ 2. Create a new workflow with:
+ - ImageInput node (load any test image)
+ - GenerateImage node (select nano-banana-pro model)
+ - Prompt node with text like "add a sunset background" or "make it black and white"
+ - Output node
+ 3. Connect: ImageInput → GenerateImage (image handle), Prompt → GenerateImage (text handle)
+ 4. Run the workflow
+ 5. Verify: The generated image should visually show the transformation applied to the input image (not a completely new unrelated image)
+ 6. Check generations folder: No duplicate files for the same generated content
+
+ Type "approved" if image-to-image works correctly, or describe issues
+
+
+
+
+
+Before declaring phase complete:
+- [ ] `npm run build` succeeds without errors
+- [ ] `npm test` passes all existing tests
+- [ ] Gemini image-to-image generation produces output that transforms the input image
+- [ ] No TypeScript errors in modified files
+
+
+
+- All tasks completed
+- All verification checks pass
+- Image-to-image generation with nano-banana-pro produces visually related output
+- Deduplication uses consistent MD5 hashing across all image save paths
+- No regression in text-to-image generation (still works when no image connected)
+
+
+