diff --git a/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md b/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md index 9785a00..5744c45 100644 --- a/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md +++ b/.planning/phases/02-season-1-vertical-slice-soil/02-04-lura-gate-beats-PLAN.md @@ -13,7 +13,6 @@ files_modified: - content/dialogue/season1/lura-mid.ink - content/dialogue/season1/lura-farewell.ink - content/dialogue/season1/compost-acknowledgements.ink - - content/dialogue/season1/lura-greeting-template.ink - src/sim/narrative/lura-gate.ts - src/sim/narrative/lura-gate.test.ts - src/sim/narrative/beat-queue.ts @@ -278,13 +277,12 @@ function findInkFiles(root) { } function inklecateBinary() { - // Verified at Task 1 — node_modules/inklecate/ ships per-platform binaries. - // The wrapper module exports a programmatic API; if it does not, fall through here. - const platform = process.platform; - const root = resolve(process.cwd(), 'node_modules/inklecate'); - if (platform === 'win32') return resolve(root, 'inklecate-windows/inklecate.exe'); - if (platform === 'darwin') return resolve(root, 'inklecate-mac/inklecate'); - return resolve(root, 'inklecate-linux/inklecate'); + // The wrapper API is tried first in compileAllInk; this is the fallback. + // Verified Task 1: node_modules/inklecate/bin/{inklecate,inklecate.exe} — + // a single bin/ directory holds both .NET binaries (Windows + POSIX). The + // wrapper handles platform selection internally. + const ext = process.platform === 'win32' ? '.exe' : ''; + return resolve(process.cwd(), 'node_modules/inklecate/bin/inklecate' + ext); } export async function compileAllInk() { @@ -538,6 +536,14 @@ export const INK_VARIABLE_MAP = { if (frag.tags.includes('heavy')) return 'winter-rose'; return ''; }, + // Per W4 — first sentence of the most-recently-harvested fragment's body, for letter prose. + last_fragment_title: (s: AppStoreShape) => { + const lastId = s.harvestedFragmentIds[s.harvestedFragmentIds.length - 1]; + if (!lastId) return ''; + const frag = allFragments.find((f) => f.id === lastId); + if (!frag) return ''; + return frag.body.split(/[.!?]/)[0]?.trim() ?? ''; + }, } as const; export async function loadInkStory(name: 'lura-arrival' | 'lura-mid' | 'lura-farewell' | 'compost-acknowledgements'): Promise { @@ -611,6 +617,8 @@ If `compile:ink` fails on Windows (Assumption A6 risk), DOCUMENT in SUMMARY.md a - `test -f scripts/compile-ink.mjs && grep -q "compileAllInk" scripts/compile-ink.mjs` + - `grep -q "node_modules/inklecate/bin" scripts/compile-ink.mjs` (BLOCKER 4: real binary path; not the non-existent inklecate-windows/ etc.) + - `! grep -q "inklecate-windows\|inklecate-mac\|inklecate-linux" scripts/compile-ink.mjs` (negative: stale path strings absent) - `test -f content/dialogue/season1/lura-arrival.ink` - `test -f content/dialogue/season1/lura-mid.ink` - `test -f content/dialogue/season1/lura-farewell.ink`