# AGENTS.md — SciFi-XZBT Guidance for AI coding agents working in this repository. ## What this project is A browser-only, zero-dependency **sci-fi ambient audio + visual display**. It synthesizes starship room tone (hull drone, worp core, life support, telemetry, alerts) with the Web Audio API and renders LCARD-styled UI, an audio visualizer, and a procedural "observation" viewscreen on HTML canvas. It runs by opening `index.html` in a browser. There is **no build step, no package manager, no server, and no test suite.** ## Architecture `index.html` loads one stylesheet and eight scripts **in a fixed order**: ``` css/style.css js/audio.js -> js/config.js -> js/core-animations.js -> js/visualizer.js js/observation-bezels.js -> js/observation-engine.js js/midi.js -> js/generative-experience.js -> js/app.js ``` Order matters: every file defines plain classes/objects and publishes them on `window`; `js/app.js` runs last and consumes all of them. Do not reorder the tags without checking the dependencies. | File | Owns | ~Lines | | --- | --- | --- | | `index.html` | DOM skeleton, script/link tags | 460 | | `css/style.css` | LCARD themes, CRT effects, palettes | 2,430 | | `js/audio.js` | `AudioManager`, `FuturisticNoiceCancellation` + all synth classes (hull, warp, life support, telemetry, alert, Whataverse, expanded sci-fi) | 6,890 | | `js/config.js` | `StarshipPresets`, `UniverseRegistry` — data only, no behavior | 1,170 | | `js/core-animations.js` | `CoreAnimations` — settings-panel core animations | 220 | | `js/visualizer.js` | `StarshipVisualizer` — spectrum + worp core canvas | 670 | | `js/observation-bezels.js` | `ObservationBezels` — procedural SVG viewport frames per era | 270 | | `js/observation-engine.js` | `ObservationEngine` — celestial simulation, canvas rendering, per-universe waveform | 3,590 | | `js/midi.js` | `XZBTControlBus` (semantic control registry) + `XZBTMidiController` (Web MIDI / MIDI learn) | 170 | | `js/generative-experience.js` | `XZBTGenerativeExperience` — optional local LLM narration and neural speech | 1,370 | | `js/app.js` | DOM bindings, hotkeys, UI controllers, main loop | 4,440 | | `tools/package.ps1` | Builds the standalone single-file HTML | — | | `dist/SciFiAmbientDisplay_V.html` | **Generated output — never edit by hand** | — | ## Hard constraints - **No dependencies.** No npm, no CDN links, no external fonts, images, or audio files. The packaged build must work when double-clicked while offline. - **No ES modules.** No `import` / `export`, no `type="module"`. Scripts are classic globals. ### The one documented exception `js/generative-experience.js` is the **only** file permitted to reach the network, and it is the only file permitted to use `import`. It lazily pulls WebLLM and Kokoro via dynamic `import()` from CDN: ```js this.webllm = this.webllm || await import('https://esm.run/@mlc-ai/web-llm'); this.kokoroModule = this.kokoroModule || await import('https://esm.sh/kokoro-js@1.2.1?bundle'); ``` The exception is bounded, and every bound is load-bearing: - The imports live **inside** `prepareExperience()` / `prepareTTS()`. Nothing is fetched at parse time, so the packaged single-file build still opens and runs fully offline — the Generative Experience panel simply stays on STANDBY. - Both are guarded: `navigator.gpu` is checked before the WebLLM import, and a failed Kokoro load falls back rather than throwing. - No other subsystem may depend on this one. The deterministic engine stays authoritative; the LLM only verbalizes world state that audio.js and app.js already decided. Do not widen this exception. New network use anywhere else, a static ` ``` `tools/package.ps1` inlines assets by matching `` and ``. Extra attributes, a different quote style, or a self-closing script tag will be silently left as an external reference and the standalone build will break. ## Build ```powershell powershell -ExecutionPolicy Bypass -File .\tools\package.ps1 ``` Writes `dist/SciFiAmbientDisplay_v4.html` (CSS and JS inlined). Re-run it after any change to CSS, JS, or `index.html`. `tools/extract.ps1` is the original extraction script, kept for reference only. ## Verifying work There are no automated tests. Verification is manual: 1. Open `index.html` in a browser; check the console is clean. 2. Exercise the affected area — play a preset, switch era/universe, enter the Watch Experience, toggle FNC. 3. Re-run `package.ps1` and open the generated `dist/SciFiAmbientDisplay_V.html` **with the network disabled** to confirm it is genuinely self-contained. The Generative Experience panel must report an error and everything else must still work — that is the test for the exception above, not a failure. Browser autoplay policy blocks audio until a user gesture; audio starting only after a click is expected behavior, not a bug. The Generative Experience needs a WebGPU-capable browser (Chrome/Edge) **and** network access on first preparation. Absence of either is expected to degrade quietly, never to break the console. ## Conventions and cautions - 2-space indentation; single quotes in JS; existing brace and spacing style. - `js/app.js`, `js/audio.js` and `js/observation-engine.js` are large. Make **surgical, scoped edits** — do not rewrite, reorder, or reformat whole files. - Do not reformat or lint files wholesale; diffs should stay minimal and reviewable. - Never edit anything in `dist/` — regenerate it instead. - Preserve the offline, single-file-deliverable property in every change. ## Terminology `Theme_Terminology_IP_Changes.md` is the authoritative rename table and applies to **identifiers as well as display strings**. The universe id is `whataverse`, the theme class is `theme-whataverse-tardix`, preset ids are `tardix-*`, and the telemetry era is `'whataverse'`. Do not reintroduce the original franchise spellings anywhere, including in comments. `TelemetrySynth` still accepts `'who'` and `'what'` as era values purely for backward compatibility with older presets; do not write new presets against them.