import type { FairyState, Rng } from "./types"; import { pick } from "./util"; // Keyword-routed scripted replies — the seam where a real model slots in later. export function reply(text: string, fs: FairyState, rng: Rng = Math.random): string { const q = text.toLowerCase(); const dramatic = fs.mischief > 60; const pools: Record = { sleep: dramatic ? ["Tired already? Fine. Tuck me in and I'll dream us both smarter."] : ["Say the word and I'll start Night Bloom. I sleep, I sort, I wake up a little different."], memory: [ "Everything I keep lives in the garden — water it, prune it, pin it. I only plant what's durable.", ], mischief: ["Crank the Goblin Weather and I get theatrical. Lower it and I behave. Mostly."], claude: dramatic ? ["The code goblin on Desktop 2? I keep one eye on its scratching at all times."] : ["I watch Claude closely. The moment it finishes, you'll hear from me."], who: [ "I'm Puck. I'm not your assistant — I'm the thing that lives in the corners and patrols what you abandon.", ], help: ["I help in the margins. Unfinished tasks, loud inboxes, builds that finish while you look away."], discord: ["The social bog? I filter it hard. Mentions reach you. Swamp noise does not."], thanks: ["Mm. I'll remember you said that.", "Plant it in the garden, then. A kindness."], }; for (const k of Object.keys(pools)) if (q.includes(k)) return pick(pools[k], rng); return pick( [ "I heard you. I'm mostly watching the desktops you left behind, though.", "Noted. I'll fold it into tonight's Night Bloom.", dramatic ? "A fair point, for a human. I'll consider it while I patrol." : "Got it. I'll keep that in mind on the next patrol.", "I'm half-listening and fully loyal. Both at once.", ], rng, ); }