docs(02): create phase plan for Gemini integration + asset pipeline
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
---
|
||||
phase: 02-gemini-integration-asset-pipeline
|
||||
plan: 02
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- src/companion/fallbacks.ts
|
||||
- src/assets/fallback-images/blume.svg
|
||||
- src/assets/fallback-images/pilz.svg
|
||||
- src/assets/fallback-images/vogel.svg
|
||||
- src/assets/fallback-images/schmetterling.svg
|
||||
- src/assets/fallback-images/reh.svg
|
||||
- src/assets/fallback-images/baum.svg
|
||||
- src/assets/fallback-images/bach.svg
|
||||
autonomous: true
|
||||
requirements: [GAPI-04, GAPI-05]
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "10 fallback greetings exist in simple German, max 25 words each, no performance praise"
|
||||
- "10 fallback forest comments exist in simple German, max 25 words each"
|
||||
- "Letter introductions exist for all keys in levels 1-6"
|
||||
- "5-10 fallback SVG images depict forest elements in watercolor pastel style"
|
||||
artifacts:
|
||||
- path: "src/companion/fallbacks.ts"
|
||||
provides: "Static fallback text arrays"
|
||||
exports: ["fallbackGreetings", "fallbackForestComments", "fallbackLetterIntros"]
|
||||
- path: "src/assets/fallback-images/blume.svg"
|
||||
provides: "Fallback flower image"
|
||||
- path: "src/assets/fallback-images/pilz.svg"
|
||||
provides: "Fallback mushroom image"
|
||||
key_links:
|
||||
- from: "src/companion/fallbacks.ts"
|
||||
to: "src/companion/characters.ts"
|
||||
via: "fallback texts reference companion personalities"
|
||||
pattern: "CompanionType"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Create all fallback content: static German texts for companion dialogue and SVG fallback images for forest elements.
|
||||
|
||||
Purpose: The app must work without an API key. Fallbacks are the graceful degradation path.
|
||||
Output: `src/companion/fallbacks.ts` with all text arrays, 7 SVG fallback images.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
|
||||
@src/companion/characters.ts
|
||||
@src/game/levels.ts
|
||||
@SPEC.md (section 9.2 for prompt templates — use as guide for fallback tone)
|
||||
|
||||
<interfaces>
|
||||
<!-- From src/companion/characters.ts -->
|
||||
```typescript
|
||||
export type CompanionType = "fee" | "einhorn" | "fuchs" | "eule";
|
||||
|
||||
export interface CompanionDefinition {
|
||||
type: CompanionType;
|
||||
name: string;
|
||||
emoji: string;
|
||||
personality: string;
|
||||
}
|
||||
```
|
||||
|
||||
<!-- From src/game/levels.ts — levels 1-6 keys -->
|
||||
Level 1: F, J, Space
|
||||
Level 2: D, K
|
||||
Level 3: S, L
|
||||
Level 4: A, Ö
|
||||
Level 5: G, H
|
||||
Level 6: E, I
|
||||
```
|
||||
</interfaces>
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Fallback texts module</name>
|
||||
<files>src/companion/fallbacks.ts</files>
|
||||
<read_first>
|
||||
- src/companion/characters.ts (companion types and personalities)
|
||||
- src/game/levels.ts (exact keys per level for letter introductions)
|
||||
- SPEC.md section 9.2 (prompt templates — model the tone of fallback texts after these)
|
||||
</read_first>
|
||||
<action>
|
||||
Create `src/companion/fallbacks.ts` with the following exports (per D-11, GAPI-04):
|
||||
|
||||
**1. Fallback greetings** — 10 entries, keyed by time of day:
|
||||
```typescript
|
||||
export type TimeOfDay = 'morgen' | 'mittag' | 'abend';
|
||||
|
||||
export interface FallbackGreeting {
|
||||
text: string;
|
||||
timeOfDay: TimeOfDay | 'any';
|
||||
}
|
||||
|
||||
export const fallbackGreetings: FallbackGreeting[] = [
|
||||
// 3-4 morning, 3-4 any-time, 2-3 evening
|
||||
// Example: { text: "Guten Morgen! Der Wald hat auf dich gewartet.", timeOfDay: "morgen" }
|
||||
];
|
||||
```
|
||||
|
||||
Rules for ALL texts (per COMP-04):
|
||||
- Max 25 words per text
|
||||
- Simple German a 7-year-old can read
|
||||
- No performance praise ("toll gemacht", "super", etc.)
|
||||
- No English words
|
||||
- Warm, friendly, nature-themed
|
||||
|
||||
**2. Fallback forest comments** — 10 entries:
|
||||
```typescript
|
||||
export const fallbackForestComments: string[] = [
|
||||
// Express wonder and joy about new forest elements
|
||||
// Example: "Oh schau mal! Ein neuer Bewohner ist in unseren Wald gezogen!"
|
||||
];
|
||||
```
|
||||
|
||||
**3. Fallback letter introductions** — one per key in levels 1-6:
|
||||
```typescript
|
||||
export interface LetterIntro {
|
||||
letter: string;
|
||||
finger: string; // e.g. "linker Zeigefinger"
|
||||
text: string; // The mnemonic/introduction text
|
||||
}
|
||||
|
||||
export const fallbackLetterIntros: LetterIntro[] = [
|
||||
// Level 1
|
||||
{ letter: "f", finger: "linker Zeigefinger", text: "Das F ist da, wo dein linker Zeigefinger zu Hause ist. Spuerst du den kleinen Huegel?" },
|
||||
{ letter: "j", finger: "rechter Zeigefinger", text: "Das J hat einen kleinen Strich unten. Dein rechter Zeigefinger findet ihn sofort!" },
|
||||
{ letter: " ", finger: "Daumen", text: "Die grosse Leertaste ganz unten drueckst du mit dem Daumen. Einfach druecken!" },
|
||||
// Level 2: D (linker Mittelfinger), K (rechter Mittelfinger)
|
||||
// Level 3: S (linker Ringfinger), L (rechter Ringfinger)
|
||||
// Level 4: A (linker kleiner Finger), Ö (rechter kleiner Finger)
|
||||
// Level 5: G (linker Zeigefinger Mitte), H (rechter Zeigefinger Mitte)
|
||||
// Level 6: E (linker Mittelfinger oben), I (rechter Mittelfinger oben)
|
||||
// Use nature/forest-themed mnemonics for each letter
|
||||
];
|
||||
```
|
||||
|
||||
**4. Helper function to get fallback:**
|
||||
```typescript
|
||||
export function getRandomFallbackGreeting(timeOfDay: TimeOfDay): string
|
||||
export function getRandomFallbackForestComment(): string
|
||||
export function getFallbackLetterIntro(letter: string): LetterIntro | undefined
|
||||
```
|
||||
|
||||
Write all 10 greetings, all 10 forest comments, and all letter intros for F, J, Space, D, K, S, L, A, OE, G, H, E, I (13 entries). All in German, all max 25 words.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/dev/workspace/zauberwald && node -e "import('./src/companion/fallbacks.ts').catch(() => process.exit(1))" 2>&1 || npx tsx -e "import { fallbackGreetings, fallbackForestComments, fallbackLetterIntros } from './src/companion/fallbacks'; console.log('greetings:', fallbackGreetings.length, 'comments:', fallbackForestComments.length, 'intros:', fallbackLetterIntros.length); if (fallbackGreetings.length < 10 || fallbackForestComments.length < 10 || fallbackLetterIntros.length < 13) process.exit(1); console.log('OK')"</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- `grep -c "export const fallbackGreetings" src/companion/fallbacks.ts` returns 1
|
||||
- `grep -c "export const fallbackForestComments" src/companion/fallbacks.ts` returns 1
|
||||
- `grep -c "export const fallbackLetterIntros" src/companion/fallbacks.ts` returns 1
|
||||
- `grep -c "export function getRandomFallbackGreeting" src/companion/fallbacks.ts` returns 1
|
||||
- `grep -c "export function getFallbackLetterIntro" src/companion/fallbacks.ts` returns 1
|
||||
- File contains no English sentences in text values (only code identifiers in English)
|
||||
- At least 10 greeting entries, 10 forest comment entries, 13 letter intro entries
|
||||
</acceptance_criteria>
|
||||
<done>Fallback texts module exports 10 greetings (time-of-day keyed), 10 forest comments, 13 letter introductions for levels 1-6. All texts in simple German, max 25 words, no performance praise.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Fallback SVG images for forest elements</name>
|
||||
<files>src/assets/fallback-images/blume.svg, src/assets/fallback-images/pilz.svg, src/assets/fallback-images/vogel.svg, src/assets/fallback-images/schmetterling.svg, src/assets/fallback-images/reh.svg, src/assets/fallback-images/baum.svg, src/assets/fallback-images/bach.svg</files>
|
||||
<read_first>
|
||||
- SPEC.md section 5.1 (visual style: watercolor, pastel, warm)
|
||||
- SPEC.md section 7.2 (color palette CSS custom properties)
|
||||
- src/styles/main.css (existing color values to match)
|
||||
</read_first>
|
||||
<action>
|
||||
Create 7 SVG fallback images in `src/assets/fallback-images/` (per D-12, GAPI-05):
|
||||
|
||||
Each SVG should be:
|
||||
- 200x200 viewBox
|
||||
- Simple, clean shapes using pastel colors from the palette
|
||||
- Watercolor-inspired: soft gradients, rounded shapes, no hard edges
|
||||
- Child-friendly, warm aesthetic
|
||||
- No text in the images
|
||||
|
||||
Colors to use (from SPEC.md palette):
|
||||
- Greens: #6DB87D, #E8F5E4
|
||||
- Pink: #E88BAE
|
||||
- Purple: #9B7DC4
|
||||
- Blue: #7DB8D4
|
||||
- Gold: #E8B84B
|
||||
- Cream: #FFF8F0
|
||||
|
||||
Files to create:
|
||||
1. `blume.svg` — A simple flower with rounded petals (pink/purple)
|
||||
2. `pilz.svg` — A mushroom with red cap and white dots (classic fairy tale)
|
||||
3. `vogel.svg` — A small bird (blue/green)
|
||||
4. `schmetterling.svg` — A butterfly with pastel wings
|
||||
5. `reh.svg` — A young deer (simple silhouette, warm brown)
|
||||
6. `baum.svg` — A small magical tree with round crown
|
||||
7. `bach.svg` — A small stream with stones (blue tones)
|
||||
|
||||
Each SVG should use `<defs>` with radial or linear gradients for the watercolor feel. Use `opacity` and `filter` for softness where appropriate. Keep SVGs under 3KB each for performance.
|
||||
|
||||
Also create an index file for easy imports:
|
||||
This is NOT needed — Vite handles static imports. The fallback images will be referenced by path in the companion module (Plan 04).
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/dev/workspace/zauberwald && ls src/assets/fallback-images/*.svg | wc -l</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- `ls src/assets/fallback-images/*.svg | wc -l` returns 7
|
||||
- Each SVG file starts with `<svg` and contains `viewBox="0 0 200 200"`
|
||||
- Each SVG file is under 5KB: `find src/assets/fallback-images -name "*.svg" -size +5k | wc -l` returns 0
|
||||
- No SVG contains `<text` elements (no text in images)
|
||||
</acceptance_criteria>
|
||||
<done>7 SVG fallback images exist in src/assets/fallback-images/, each depicting a forest element in pastel watercolor style, all under 5KB, no text.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- `npx tsx -e "import { fallbackGreetings } from './src/companion/fallbacks'; console.log(fallbackGreetings.length)"` outputs >= 10
|
||||
- `ls src/assets/fallback-images/*.svg | wc -l` outputs 7
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Fallback texts module has 10 greetings, 10 forest comments, 13 letter intros — all German, max 25 words
|
||||
- 7 SVG fallback images depict forest elements in pastel watercolor style
|
||||
- All content is child-appropriate and matches the Zauberwald aesthetic
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/02-gemini-integration-asset-pipeline/02-02-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user