Browse Source

docs(09): create phase plan

Phase 09: Video History
- 1 plan created
- 3 total tasks defined
- Ready for execution
handoff-20260429-1057
shrimbly 6 months ago
parent
commit
38d7e55cde
  1. 6
      .planning/ROADMAP.md
  2. 185
      .planning/phases/09-video-history/09-01-PLAN.md

6
.planning/ROADMAP.md

@ -121,10 +121,10 @@ Plans:
**Goal**: Add history carousel for generated videos matching image history pattern **Goal**: Add history carousel for generated videos matching image history pattern
**Depends on**: Phase 8 **Depends on**: Phase 8
**Research**: Unlikely (existing image history pattern) **Research**: Unlikely (existing image history pattern)
**Plans**: TBD **Plans**: 1 plan
Plans: 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 #### 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 | | 6. Video & Polish | v1.0 | 4/4 | Complete | 2026-01-11 |
| 7. Video Connections | v1.1 | 1/1 | Complete | 2026-01-12 | | 7. Video Connections | v1.1 | 1/1 | Complete | 2026-01-12 |
| 8. Error Display | 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 | - | | 10. Node Autosizing | v1.1 | 0/? | Not started | - |
| 11. UI Polish | v1.1 | 0/? | Not started | - | | 11. UI Polish | v1.1 | 0/? | Not started | - |
| 12. Model Improvements | v1.1 | 0/? | Not started | - | | 12. Model Improvements | v1.1 | 0/? | Not started | - |

185
.planning/phases/09-video-history/09-01-PLAN.md

@ -0,0 +1,185 @@
---
phase: 09-video-history
plan: 01
type: execute
---
<objective>
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.
</objective>
<execution_context>
~/.claude/get-shit-done/workflows/execute-phase.md
~/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.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
</context>
<tasks>
<task type="auto">
<name>Task 1: Add video history types and store support</name>
<files>src/types/index.ts, src/store/workflowStore.ts</files>
<action>
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.
</action>
<verify>TypeScript compiles: `npm run build` passes without type errors related to video history</verify>
<done>GenerateVideoNodeData has videoHistory and selectedVideoHistoryIndex fields. Workflow execution saves videos to history and persists to generations folder.</done>
</task>
<task type="auto">
<name>Task 2: Update load-generation API to support video formats</name>
<files>src/app/api/load-generation/route.ts</files>
<action>
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<string, string> = {
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'`
</action>
<verify>API handles video loading: Create a test .mp4 file in generations folder and verify the endpoint returns it correctly</verify>
<done>load-generation API can load both images and videos by ID, with correct MIME types and response fields</done>
</task>
<task type="auto">
<name>Task 3: Add carousel controls to GenerateVideoNode</name>
<files>src/components/nodes/GenerateVideoNode.tsx</files>
<action>
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
</action>
<verify>Visual inspection: Generate 2+ videos with same node, verify carousel appears and navigation works</verify>
<done>GenerateVideoNode has prev/next carousel buttons showing after first regeneration, allowing users to browse video history</done>
</task>
</tasks>
<verification>
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
</verification>
<success_criteria>
- 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
</success_criteria>
<output>
After completion, create `.planning/phases/09-video-history/09-01-SUMMARY.md` following summary template.
</output>
Loading…
Cancel
Save