Browse Source
Phase 27: Node Defaults Infrastructure - 1 plan created - 3 tasks defined - Ready for executionhandoff-20260429-1057
1 changed files with 191 additions and 0 deletions
@ -0,0 +1,191 @@ |
|||||
|
--- |
||||
|
phase: 27-node-defaults-infrastructure |
||||
|
plan: 01 |
||||
|
type: execute |
||||
|
--- |
||||
|
|
||||
|
<objective> |
||||
|
Create infrastructure for storing default model and settings preferences per node type. |
||||
|
|
||||
|
Purpose: Enable users to configure default models for GenerateImage, GenerateVideo, and LLM nodes so keyboard shortcuts and quick-add buttons create nodes with their preferred settings. |
||||
|
Output: NodeDefaults types, localStorage persistence, and integration with createDefaultNodeData. |
||||
|
</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 files:** |
||||
|
@src/store/utils/localStorage.ts |
||||
|
@src/store/utils/nodeDefaults.ts |
||||
|
@src/types/nodes.ts |
||||
|
@src/types/providers.ts |
||||
|
|
||||
|
**Current state:** |
||||
|
- GenerateImageDefaults already exists in localStorage.ts for nanoBanana node |
||||
|
- createDefaultNodeData() uses loadGenerateImageDefaults() for nanoBanana type |
||||
|
- generateVideo and llmGenerate use hardcoded defaults |
||||
|
- Node creation via Shift+G, Shift+L shortcuts calls addNode() → createDefaultNodeData() |
||||
|
|
||||
|
**Established patterns:** |
||||
|
- localStorage helpers: load{X}(), save{X}() with SSR-safe typeof window checks |
||||
|
- Defaults merged with existing settings to handle schema evolution |
||||
|
- Types defined in src/types/*.ts, re-exported from index.ts |
||||
|
|
||||
|
**Constraining decisions:** |
||||
|
- Phase 23: Recently used models stored per-model, not per-node-type |
||||
|
- Existing GenerateImageDefaults: {aspectRatio, resolution, model, useGoogleSearch} |
||||
|
</context> |
||||
|
|
||||
|
<tasks> |
||||
|
|
||||
|
<task type="auto"> |
||||
|
<name>Task 1: Define node defaults types and localStorage helpers</name> |
||||
|
<files>src/types/nodes.ts, src/types/index.ts, src/store/utils/localStorage.ts</files> |
||||
|
<action> |
||||
|
1. Add NodeDefaultsConfig interface to src/types/nodes.ts (at end of file): |
||||
|
|
||||
|
```typescript |
||||
|
/** |
||||
|
* Default settings for node types - stored in localStorage |
||||
|
*/ |
||||
|
export interface GenerateImageNodeDefaults { |
||||
|
selectedModel?: { |
||||
|
provider: ProviderType; |
||||
|
modelId: string; |
||||
|
displayName: string; |
||||
|
}; |
||||
|
aspectRatio?: string; |
||||
|
resolution?: string; |
||||
|
useGoogleSearch?: boolean; |
||||
|
} |
||||
|
|
||||
|
export interface GenerateVideoNodeDefaults { |
||||
|
selectedModel?: { |
||||
|
provider: ProviderType; |
||||
|
modelId: string; |
||||
|
displayName: string; |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
export interface LLMNodeDefaults { |
||||
|
provider?: LLMProvider; |
||||
|
model?: LLMModelType; |
||||
|
temperature?: number; |
||||
|
maxTokens?: number; |
||||
|
} |
||||
|
|
||||
|
export interface NodeDefaultsConfig { |
||||
|
generateImage?: GenerateImageNodeDefaults; |
||||
|
generateVideo?: GenerateVideoNodeDefaults; |
||||
|
llm?: LLMNodeDefaults; |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Import ProviderType from ./providers.ts and LLMProvider, LLMModelType from existing imports. |
||||
|
|
||||
|
2. Re-export from src/types/index.ts: |
||||
|
- Add: GenerateImageNodeDefaults, GenerateVideoNodeDefaults, LLMNodeDefaults, NodeDefaultsConfig |
||||
|
|
||||
|
3. Add localStorage helpers to src/store/utils/localStorage.ts: |
||||
|
- STORAGE_KEY: "node-banana-node-defaults" |
||||
|
- loadNodeDefaults(): NodeDefaultsConfig |
||||
|
- saveNodeDefaults(config: NodeDefaultsConfig): void |
||||
|
- Helpers: getGenerateImageDefaults(), getGenerateVideoDefaults(), getLLMDefaults() |
||||
|
- Each getter returns undefined if not set, allowing fallback to hardcoded defaults |
||||
|
|
||||
|
Pattern: Follow existing getProviderSettings() pattern with SSR guard and JSON parse/stringify. |
||||
|
|
||||
|
Do NOT remove existing GenerateImageDefaults - it stays for backward compatibility. |
||||
|
</action> |
||||
|
<verify>npm run build passes without TypeScript errors</verify> |
||||
|
<done>NodeDefaultsConfig types exist, localStorage helpers compile, exports are in place</done> |
||||
|
</task> |
||||
|
|
||||
|
<task type="auto"> |
||||
|
<name>Task 2: Integrate node defaults into createDefaultNodeData</name> |
||||
|
<files>src/store/utils/nodeDefaults.ts</files> |
||||
|
<action> |
||||
|
1. Import new types and helpers: |
||||
|
- Import loadNodeDefaults from ./localStorage |
||||
|
- Import GenerateImageNodeDefaults, GenerateVideoNodeDefaults, LLMNodeDefaults from @/types |
||||
|
|
||||
|
2. Update createDefaultNodeData for nanoBanana case: |
||||
|
- Load node defaults: const nodeDefaults = loadNodeDefaults(); |
||||
|
- Get generateImage defaults: nodeDefaults.generateImage |
||||
|
- If selectedModel is set in nodeDefaults.generateImage, use it |
||||
|
- Fall back to existing loadGenerateImageDefaults() for aspectRatio/resolution/model/useGoogleSearch |
||||
|
- Merge: nodeDefaults.generateImage overrides legacy GenerateImageDefaults |
||||
|
|
||||
|
Priority for nanoBanana: |
||||
|
1. nodeDefaults.generateImage.selectedModel (if set) |
||||
|
2. Else: construct from loadGenerateImageDefaults().model as Gemini model |
||||
|
|
||||
|
3. Update createDefaultNodeData for generateVideo case: |
||||
|
- If nodeDefaults.generateVideo?.selectedModel is set, use it |
||||
|
- Otherwise keep undefined (user must select model) |
||||
|
|
||||
|
4. Update createDefaultNodeData for llmGenerate case: |
||||
|
- If nodeDefaults.llm exists, merge with hardcoded defaults |
||||
|
- Hardcoded: provider="google", model="gemini-3-flash-preview", temperature=0.7, maxTokens=8192 |
||||
|
- Override with any fields set in nodeDefaults.llm |
||||
|
|
||||
|
Keep the function efficient - only call loadNodeDefaults() once per node creation (cache at top of switch). |
||||
|
</action> |
||||
|
<verify>npm run build passes, npm test passes (existing tests should not break)</verify> |
||||
|
<done>createDefaultNodeData uses stored defaults when available, falls back to hardcoded defaults when not set</done> |
||||
|
</task> |
||||
|
|
||||
|
<task type="auto"> |
||||
|
<name>Task 3: Add tests for node defaults persistence</name> |
||||
|
<files>src/store/utils/__tests__/localStorage.test.ts, src/store/utils/__tests__/nodeDefaults.test.ts</files> |
||||
|
<action> |
||||
|
1. Add tests to localStorage.test.ts for new helpers: |
||||
|
- loadNodeDefaults returns empty object when not set |
||||
|
- saveNodeDefaults persists to localStorage |
||||
|
- getGenerateImageDefaults returns undefined when not configured |
||||
|
- getGenerateImageDefaults returns stored value when configured |
||||
|
- Same pattern for getGenerateVideoDefaults and getLLMDefaults |
||||
|
|
||||
|
2. Add tests to nodeDefaults.test.ts for createDefaultNodeData integration: |
||||
|
- nanoBanana uses default Gemini model when no node defaults set (existing behavior) |
||||
|
- nanoBanana uses stored selectedModel when generateImage defaults set |
||||
|
- generateVideo uses stored selectedModel when generateVideo defaults set |
||||
|
- llmGenerate uses stored provider/model when llm defaults set |
||||
|
- llmGenerate falls back to hardcoded when llm defaults not set |
||||
|
|
||||
|
Mock localStorage using existing pattern from localStorage.test.ts. |
||||
|
</action> |
||||
|
<verify>npm test -- --run passes all new and existing tests</verify> |
||||
|
<done>Tests verify defaults loading/saving and createDefaultNodeData integration</done> |
||||
|
</task> |
||||
|
|
||||
|
</tasks> |
||||
|
|
||||
|
<verification> |
||||
|
Before declaring plan complete: |
||||
|
- [ ] `npm run build` succeeds without TypeScript errors |
||||
|
- [ ] `npm test` passes all tests |
||||
|
- [ ] NodeDefaultsConfig types properly exported |
||||
|
- [ ] localStorage helpers work with SSR (typeof window check) |
||||
|
- [ ] createDefaultNodeData respects stored defaults |
||||
|
</verification> |
||||
|
|
||||
|
<success_criteria> |
||||
|
|
||||
|
- All tasks completed |
||||
|
- TypeScript builds without errors |
||||
|
- Tests pass for new functionality |
||||
|
- Node defaults infrastructure ready for Phase 28 UI |
||||
|
- Backward compatible with existing GenerateImageDefaults |
||||
|
</success_criteria> |
||||
|
|
||||
|
<output> |
||||
|
After completion, create `.planning/phases/27-node-defaults-infrastructure/27-01-SUMMARY.md` |
||||
|
</output> |
||||
Loading…
Reference in new issue