diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 557b4973..2d7ae341 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -121,10 +121,10 @@ Plans: **Goal**: Add history carousel for generated videos matching image history pattern **Depends on**: Phase 8 **Research**: Unlikely (existing image history pattern) -**Plans**: TBD +**Plans**: 1 plan Plans: -- [ ] 09-01: TBD (run /gsd:plan-phase 9 to break down) +- [ ] 09-01: Video history types, store support, load API, and carousel UI #### Phase 10: Node Autosizing @@ -172,7 +172,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → | 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 | 0/? | Not started | - | +| 9. Video History | v1.1 | 0/1 | Planned | - | | 10. Node Autosizing | v1.1 | 0/? | Not started | - | | 11. UI Polish | v1.1 | 0/? | Not started | - | | 12. Model Improvements | v1.1 | 0/? | Not started | - | diff --git a/.planning/phases/09-video-history/09-01-PLAN.md b/.planning/phases/09-video-history/09-01-PLAN.md new file mode 100644 index 00000000..65fd1676 --- /dev/null +++ b/.planning/phases/09-video-history/09-01-PLAN.md @@ -0,0 +1,185 @@ +--- +phase: 09-video-history +plan: 01 +type: execute +--- + + +Add history carousel for generated videos in GenerateVideoNode, matching the image history pattern. + +Purpose: Allow users to browse through previously generated videos without re-generating, improving workflow iteration speed. +Output: GenerateVideoNode with carousel navigation controls and persistent video history stored to generations folder. + + + +~/.claude/get-shit-done/workflows/execute-phase.md +~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + +# Key reference files (pattern to follow): +@src/components/nodes/GenerateImageNode.tsx - Has carousel controls to copy pattern from (lines 295-334, 609-636) +@src/types/index.ts - Has ImageHistoryItem/CarouselImageItem types (lines 117-134) +@src/store/workflowStore.ts - Has imageHistory handling in executeWorkflow (lines 1201-1207, 1893-1899) +@src/app/api/load-generation/route.ts - Currently only handles .png, needs video support +@src/app/api/save-generation/route.ts - Already supports video (line 12-16), good reference + +# Files to modify: +@src/components/nodes/GenerateVideoNode.tsx + + + + + + Task 1: Add video history types and store support + src/types/index.ts, src/store/workflowStore.ts + +1. In src/types/index.ts: + - Add `CarouselVideoItem` type after `CarouselImageItem` (line ~135): + ```typescript + export interface CarouselVideoItem { + id: string; + timestamp: number; + prompt: string; + model: string; // Model ID for video (not ModelType since external providers) + } + ``` + - Update `GenerateVideoNodeData` interface (line ~165) to add: + ```typescript + videoHistory: CarouselVideoItem[]; + selectedVideoHistoryIndex: number; + ``` + +2. In src/store/workflowStore.ts: + - Update `createDefaultNodeData` for "generateVideo" case (around line 214) to include: + ```typescript + videoHistory: [], + selectedVideoHistoryIndex: 0, + ``` + - In `executeWorkflow` where generateVideo success is handled (around line 1392-1398), add video history tracking after setting outputVideo: + - Generate unique ID: `const videoId = crypto.randomUUID();` + - Create history item: `{ id: videoId, timestamp: Date.now(), prompt: text || '', model: nodeData.selectedModel?.modelId || '' }` + - Update history array (prepend new item): `videoHistory: [newHistoryItem, ...(nodeData.videoHistory || [])].slice(0, 50)` + - Set `selectedVideoHistoryIndex: 0` + - Call save-generation API with video and videoId (async, don't await) + - Do the same for regenerateNode video handling (around line 2136-2142) + +Import `crypto` from Node.js is not needed - use Math.random() fallback pattern already in codebase, or check if crypto.randomUUID exists. + + TypeScript compiles: `npm run build` passes without type errors related to video history + GenerateVideoNodeData has videoHistory and selectedVideoHistoryIndex fields. Workflow execution saves videos to history and persists to generations folder. + + + + Task 2: Update load-generation API to support video formats + src/app/api/load-generation/route.ts + +Update the load-generation API to handle video files in addition to images: + +1. Change the hardcoded `.png` extension logic (line 54) to search for the file by ID with multiple extensions: + - Define supported extensions: `const extensions = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'mp4', 'webm', 'mov'];` + - Loop through extensions to find the file that exists + - If no file found with any extension, return 404 + +2. Update the MIME type detection based on actual file extension found: + ```typescript + const extToMime: Record = { + png: 'image/png', + jpg: 'image/jpeg', + jpeg: 'image/jpeg', + webp: 'image/webp', + gif: 'image/gif', + mp4: 'video/mp4', + webm: 'video/webm', + mov: 'video/quicktime', + }; + ``` + +3. Return appropriate response field: + - For images: `{ success: true, image: dataUrl }` + - For videos: `{ success: true, video: dataUrl }` + - Include `contentType` field to indicate type: `contentType: extension.startsWith('mp4') || extension === 'webm' || extension === 'mov' ? 'video' : 'image'` + + API handles video loading: Create a test .mp4 file in generations folder and verify the endpoint returns it correctly + load-generation API can load both images and videos by ID, with correct MIME types and response fields + + + + Task 3: Add carousel controls to GenerateVideoNode + src/components/nodes/GenerateVideoNode.tsx + +Add carousel UI and navigation to GenerateVideoNode, following GenerateImageNode pattern: + +1. Add state for loading: + ```typescript + const [isLoadingCarouselVideo, setIsLoadingCarouselVideo] = useState(false); + ``` + +2. Get generationsPath from store: + ```typescript + const generationsPath = useWorkflowStore((state) => state.generationsPath); + ``` + +3. Add loadVideoById callback (copy pattern from GenerateImageNode lines 266-293): + ```typescript + const loadVideoById = useCallback(async (videoId: string) => { + if (!generationsPath) return null; + try { + const response = await fetch("/api/load-generation", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ directoryPath: generationsPath, imageId: videoId }), + }); + if (!response.ok) return null; + const result = await response.json(); + return result.success ? (result.video || result.image) : null; + } catch { return null; } + }, [generationsPath]); + ``` + +4. Add carousel navigation handlers (copy pattern from GenerateImageNode lines 295-333): + ```typescript + const handleCarouselPrevious = useCallback(async () => { ... }, [...]); + const handleCarouselNext = useCallback(async () => { ... }, [...]); + ``` + Adapt for video: use `videoHistory`, `selectedVideoHistoryIndex`, `outputVideo` + +5. Add carousel UI after the video element, inside the outputVideo conditional (around line 388): + - Check `hasCarouselVideos = (nodeData.videoHistory || []).length > 1` + - Add carousel controls div with prev/next buttons (copy from GenerateImageNode lines 609-636) + - Show "N / M" indicator using videoHistory length and selectedVideoHistoryIndex + +6. Add loading overlay for carousel navigation (copy from GenerateImageNode lines 572-595): + - Inside the video preview div, add conditional overlay when isLoadingCarouselVideo is true + + Visual inspection: Generate 2+ videos with same node, verify carousel appears and navigation works + GenerateVideoNode has prev/next carousel buttons showing after first regeneration, allowing users to browse video history + + + + + +Before declaring phase complete: +- [ ] `npm run build` succeeds without errors +- [ ] GenerateVideoNode shows carousel controls after 2+ generations +- [ ] Carousel navigation loads previous videos from disk +- [ ] Videos persist across page refresh (stored in generations folder) +- [ ] No TypeScript errors + + + + +- All tasks completed +- All verification checks pass +- Video history works identically to image history pattern +- Carousel shows N/M indicator and prev/next navigation +- Videos saved to and loaded from generations folder + + + +After completion, create `.planning/phases/09-video-history/09-01-SUMMARY.md` following summary template. +