diff --git a/CLAUDE.md b/CLAUDE.md index 9db3884..5b228d2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,10 +6,55 @@ The Nexus is a Three.js environment — Timmy's sovereign home in 3D space. It s ## Architecture +**app.js is a thin orchestrator. It should almost never change.** + +All logic lives in ES modules under `modules/`. app.js only imports modules, wires them to the ticker, and starts the loop. New features go in new modules — not in app.js. + ``` -index.html # Entry point: HUD, chat panel, loading screen, live-reload script -style.css # Design system: dark space theme, holographic panels -app.js # Three.js scene, shaders, controls, game loop (~all logic) +index.html # Entry point: HUD, chat panel, loading screen +style.css # Design system: dark space theme, holographic panels +app.js # THIN ORCHESTRATOR — imports + init + ticker start (~200 lines) +modules/ + core/ + scene.js # THREE.Scene, camera, renderer, controls, resize + ticker.js # Global Animation Clock — the single RAF loop + theme.js # NEXUS.theme — colors, fonts, line weights, glow params + state.js # Shared data bus (activity, weather, BTC, agents) + audio.js # Web Audio: reverb, panner, ambient, portal hums + data/ + gitea.js # All Gitea API calls (commits, PRs, agents) + weather.js # Open-Meteo weather fetch + bitcoin.js # Blockstream BTC block height + loaders.js # JSON file loaders (portals, sovereignty, SOUL) + panels/ + heatmap.js # Commit heatmap + zone rendering + agent-board.js # Agent status board (Gitea API) + dual-brain.js # Dual-brain panel (honest offline) + lora-panel.js # LoRA adapter panel (honest empty) + sovereignty.js # Sovereignty meter + score arc + earth.js # Holographic earth (activity-tethered) + effects/ + matrix-rain.js # Matrix rain (commit-tethered) + lightning.js # Lightning arcs between zones + energy-beam.js # Energy beam (agent-count-tethered) + rune-ring.js # Rune ring (portal-tethered) + gravity-zones.js # Gravity anomaly zones + shockwave.js # Shockwave, fireworks, merge flash + terrain/ + island.js # Floating island + crystals + clouds.js # Cloud layer (weather-tethered) + stars.js # Star field + constellations (BTC-tethered) + portals/ + portal-system.js # Portal creation, warp, health checks + commit-banners.js # Floating commit banners + narrative/ + bookshelves.js # Floating bookshelves (SOUL.md) + oath.js # Oath display + enter/exit + chat.js # Chat panel, speech bubbles, NPC dialog + utils/ + perlin.js # Perlin noise generator + geometry.js # Shared geometry helpers + canvas-utils.js # Canvas texture creation helpers ``` No build step. Served as static files. Import maps in `index.html` handle Three.js resolution. @@ -17,11 +62,16 @@ No build step. Served as static files. Import maps in `index.html` handle Three. ## Conventions - **ES modules only** — no CommonJS, no bundler -- **Single-file app** — logic lives in `app.js`; don't split without good reason -- **Color palette** — defined in `NEXUS.colors` at top of `app.js` +- **Modular architecture** — all logic in `modules/`. app.js is the orchestrator and should almost never change. +- **Module contract** — every module exports `init(scene, state, theme)` and `update(elapsed, delta)`. Optional: `dispose()` +- **Single animation clock** — one `requestAnimationFrame` in `ticker.js`. No module may call RAF directly. All subscribe to the ticker. +- **Theme is law** — all colors, fonts, line weights come from `NEXUS.theme` in `theme.js`. No inline hex codes, no hardcoded font strings. +- **Data flows through state** — data modules write to `state.js`, visual modules read from it. No `fetch()` outside `data/` modules. - **Conventional commits**: `feat:`, `fix:`, `refactor:`, `test:`, `chore:` - **Branch naming**: `claude/issue-{N}` (e.g. `claude/issue-5`) - **One PR at a time** — wait for merge-bot before opening the next +- **Atomic PRs** — target <150 lines changed per PR. Commit by concern: data, logic, or visuals. If a change needs >200 lines, split into sequential PRs. +- **No new code in app.js** — new features go in a new module or extend an existing module. The only reason to touch app.js is to add an import line for a new module. ## Validation (merge-bot checks)