- scripts/compile-ink.mjs: build-time inklecate runner using bundled binary
(BLOCKER 4 — uses node_modules/inklecate/bin, not stale -windows/-mac path strings).
Assumption A6 verified first-try on Windows; the same binary path resolution
works on macOS + Linux per the wrapper's own getInklecatePath convention.
- scripts/compile-ink.test.mjs: 3 Vitest cases proving the compiler runs +
emits valid JSON with inkVersion. wipe=false for the test path so it can
run in parallel with the ink-loader test without racing on the wipe step.
- 4 Season-1 .ink files authored in voice (Lura warmth-anchor, gardener-keeper
for compost): lura-arrival.ink, lura-mid.ink, lura-farewell.ink,
compost-acknowledgements.ink (rewrite of Plan 02-03 scaffolded version into
VAR-driven branch shape consumable by the runtime).
- src/content/ink-loader.ts: loadInkStory + bindGardenStateToInk +
INK_VARIABLE_MAP. Centralized snake_case slot mapping per Pitfall 4. UTF-8
BOM stripped before Story instantiation.
- src/content/ink-loader.test.ts: 8 cases — Story instantiation for all 4
beats, fragment_count binding, Pitfall 4 snake_case enforcement, silent
skip for stories missing declared vars.
- package.json: build now runs compile:ink first; ci chain runs compile:ink
before test so ink-loader.test.ts's precondition check passes.
- .gitignore: src/content/compiled-ink/ excluded (regenerated on every build).
npm run ci exits 0; 11 new tests green (228 total).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Built equivalent React + Vite + TypeScript scaffold by hand because the official
npm create @phaserjs/game@latest scaffolder is interactive-only and the documented
--template/--yes flags are ignored (verified 2026-05-08 with create-game v1.3.2).
Plan Step 1 explicitly authorizes this fallback. Resulting tree mirrors the
official template shape: index.html, src/main.tsx, src/App.tsx, src/PhaserGame.tsx,
src/game/main.ts, src/game/scenes/Boot.ts.
- Installed Phase-1 production deps at versions verified in RESEARCH.md:
phaser@4.1.0, react@19.2.6, react-dom@19.2.6, idb@8.0.3, lz-string@1.5.0,
zod@4.4.3, crc-32@1.2.2, gray-matter@4.0.3, yaml@2.8.4, inkjs@2.4.0.
- Installed Phase-1 dev deps: vite@8.0.11, @vitejs/plugin-react@6.0.1,
typescript@6.0.3, @types/react@19, @types/react-dom@19, @types/node@22,
vitest@4.1.5, @vitest/ui, happy-dom, fake-indexeddb@6 (for Plan 03 IDB tests),
@playwright/test@1.59.1, eslint@9, eslint-plugin-boundaries@6.0.2, inklecate@1.8.1.
- Created the seven architectural-firewall directories under src/ with .gitkeep
markers (sim, render, ui, save, content, audio, store) — siblings to the
template-provided src/game/ — so Plan 02's ESLint boundaries rule has clean
targets per CLAUDE.md 'Architectural Firewall'.
- Created repo-root /content/ (with /dialogue/ and /seasons/ subdirs) and /assets/
trees per CONTEXT D-11, D-12.
- Pre-declared all downstream-required scripts in package.json so Plans 02–06 only
edit code, not script keys: dev, build, preview, lint (--max-warnings 0 per
RESEARCH CI Pitfall C), test (--passWithNoTests=false per CI Pitfall B),
test:watch, validate:assets, compile:ink (no-op stub for Phase 1; Phase 2
replaces with real inklecate invocation), ci.
- TypeScript strict mode enforced via tsconfig.json + tsconfig.app.json + tsconfig.node.json.
- npm run build succeeds (tsc -b && vite build) producing dist/index.html and
dist/assets/index-*.js (~1.5MB Phaser bundle; code-splitting deferred to Phase 2+
when actual scenes exist).