113 lines
6.3 KiB
Markdown
113 lines
6.3 KiB
Markdown
# EPIC: The Musical Timeline
|
||
|
||
Unofficial fan site: an interactive timeline of *EPIC: The Musical* songs. Currently 7 design-direction
|
||
mockups. Bun 1.3.14 (server, bundler, test runner), TypeScript, three.js (mockups 06/07/13/14/15 only), Docker.
|
||
|
||
`AGENTS.md` is the single source of truth for agents here. `CLAUDE.md` and `GEMINI.md` only point here.
|
||
Deeper context on demand: `docs/ARCHITECTURE.md`, `docs/DECISIONS.md`, `docs/TODO.md`.
|
||
|
||
## Commands
|
||
|
||
Install: `bun install --frozen-lockfile`
|
||
Dev: `bun run dev` (`PORT` env, default 3000)
|
||
Test: `bun test` | Single file: `bun test tests/data.test.ts` | Single case: `bun test -t "registry has 15"`
|
||
Typecheck: `bun run typecheck`
|
||
Build: `bun run build` | Run the build: `bun run start`
|
||
Docker: `docker build -t epic-timeline .` then `docker run --rm -p 3000:3000 epic-timeline`
|
||
|
||
Run the production bundle **from inside `dist/`**. Bun resolves bundled assets relative to the cwd:
|
||
```sh
|
||
bun run start # right: cd dist && bun server.js
|
||
bun dist/server.js # wrong: crashes with 'Bundled file "./index-….js" not found'
|
||
```
|
||
|
||
## Rules
|
||
|
||
- Every page shows the fan notice and the Jorge Rivera-Herrans credit: keep `<footer data-fan-credits>`
|
||
and the `../../shared/credits.css` link in the page's HTML, and call `mountCredits()` from
|
||
`src/shared/credits.ts`. Never write your own notice text.
|
||
- Mockup agents edit only their own `src/mockups/NN-slug/` folder. `src/data/`, `src/shared/`,
|
||
`src/server.ts`, `src/index.html` and `src/mockups/registry.ts` are the shared contract; change them
|
||
only when the plan says so.
|
||
- No two mockups may have byte-identical `style.css` — the build fails with
|
||
"Multiple files share the same output path". Give each one its own styles from the start.
|
||
- Sample data (`src/data/sample.ts`): lyrics are placeholders, never real lyrics. Any fact, story time
|
||
or Odyssey reference you can't confirm gets `// TODO(verify)`.
|
||
- Assets are bundled, never loaded from a CDN: fonts from `@fontsource/*`, three.js from npm.
|
||
YouTube videos are link cards (`createVideoCards`), not embeds.
|
||
- Adding a mockup route means editing `src/server.ts`, `src/mockups/registry.ts` and the cards in
|
||
`src/index.html` together; `tests/server.test.ts` checks every registry slug is served and that the index shows each entry's name, pitch and tryThis.
|
||
|
||
## Workflow
|
||
|
||
Required skills: `superpowers`, `impeccable`. Check at session start; install if missing.
|
||
Specs → `docs/specs/NNN-slug.md` (permanent). Plans → `docs/plans/NNN-slug.md` while in progress;
|
||
`git rm` them before opening a merge request — the spec is the record.
|
||
(Overrides the superpowers default paths.)
|
||
|
||
Anything beyond a trivial fix: brainstorm → spec (sign-off) → plan (sign-off) → TDD → review.
|
||
Tick plan checkboxes as you go so an interrupted session is resumable.
|
||
Trivial changes (typo, version bump, one-line config): say "trivial, skipping spec" and proceed.
|
||
|
||
Use impeccable for user-facing UI — `craft` for new, `audit`/`polish` on existing, `harden` before
|
||
shipping. Design context: `PRODUCT.md`, `DESIGN.md`. No visual direction is chosen yet (see `DESIGN.md`).
|
||
|
||
Mockup rounds — any UI change beyond a trivial tweak, while brainstorming and before the spec:
|
||
- Round 1: about three genuinely different alternatives, each a clickable mockup with realistic
|
||
content, plus an index page giving each a one-line pitch and what to try.
|
||
- Then diverge (about three options on one open question) or converge (one combined mockup); small
|
||
choices can be toggles inside one mockup. Repeat until the user approves one mockup.
|
||
- Once `DESIGN.md` has a chosen direction, options vary structure, flow and behaviour within it —
|
||
never a new palette or font family.
|
||
- **This repo deviates from the usual throwaway setup:** mockups live in `src/mockups/NN-slug/`, are
|
||
committed, served by the app and smoke-tested.
|
||
- On approval, write `docs/design/NNN-slug.md` (the spec's number): each chosen idea, buildable without
|
||
the mockup, and what was deselected and why. The spec links it.
|
||
|
||
## Architecture
|
||
|
||
`src/server.ts` -> `Bun.serve` with HTML-import routes: `/` and `/mockups/NN-slug/`
|
||
`src/data/` -> `types.ts` (shapes), `sample.ts` (shared sample data), `query.ts` (helpers)
|
||
`src/shared/` -> credits, audio slot (direct MP3, empty state), YouTube link cards
|
||
`src/mockups/NN-slug/` -> one design direction each: `index.html`, `main.ts`, `style.css`, plus optional helper modules (e.g. `scene.ts`, `layout.ts`)
|
||
`tests/` -> data invariants, shared DOM modules (happy-dom), route smoke tests
|
||
|
||
Full picture: `docs/ARCHITECTURE.md` — read it before your first change in a session.
|
||
|
||
## Boundaries
|
||
|
||
Never touch: `dist/`, `node_modules/`.
|
||
Never commit `.env`, secrets, or credentials.
|
||
Never force-push or rewrite pushed history.
|
||
|
||
Ask first: new runtime dependencies · changes to `src/data/types.ts` or the shared modules ·
|
||
the Dockerfile · work the approved plan does not cover.
|
||
|
||
If the task turns out much larger than the plan assumed: stop, report, re-plan.
|
||
|
||
## Docs duties
|
||
|
||
Same commit as the code, not "later":
|
||
- `docs/ARCHITECTURE.md` — when a module, boundary, or data flow changes.
|
||
- `docs/DECISIONS.md` — append-only; any choice a future maintainer would reverse-engineer.
|
||
- `docs/TODO.md` — anything noticed and deliberately not fixed. No `TODO` comments in source
|
||
(`// TODO(verify)` in sample data is the exception).
|
||
- `docs/PERMISSIONS.md` — together with every tool permission file (`.claude/settings.json`,
|
||
`.codex/`, `.gemini/settings.json`), in one commit.
|
||
|
||
## Git
|
||
|
||
Remote `origin` is Gitea, not GitHub: `gh` does not apply. Commits: Conventional Commits (`feat:`,
|
||
`docs:`, `chore:`, `feat(mockups):`).
|
||
Branches: TODO(maintainer): confirm whether work goes on branches (suggest `feat|fix|chore/<slug>`) or straight to `main` as so far.
|
||
|
||
## Done means verified
|
||
|
||
Do not report success on work you have not run. Before saying done:
|
||
`bun test` and `bun run typecheck` run *in this session* and seen passing · `bun run build` succeeds ·
|
||
matches the approved spec · docs duties complete · `git status` clean and the diff is only what you intended.
|
||
UI work, in the app or a mockup: with `bun run start` running, take headless screenshots at 1440×900
|
||
(`google-chrome --headless --window-size=1440,900 --screenshot=screenshots/x.png <url>`, or Playwright)
|
||
of each screen you changed into `screenshots/` (gitignored) and look at them before saying done.
|
||
"It should work" is not verification.
|