Browse Source

docs(27): create phase plan for Node Defaults Infrastructure

Phase 27: Node Defaults Infrastructure
- 1 plan created
- 3 tasks defined
- Ready for execution
handoff-20260429-1057
shrimbly 6 months ago
parent
commit
3ebb48d247
  1. 191
      .planning/phases/27-node-defaults-infrastructure/27-01-PLAN.md

191
.planning/phases/27-node-defaults-infrastructure/27-01-PLAN.md

@ -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…
Cancel
Save