From 80f6c9712767ac34cd3813f19fcd1c52a2082de7 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Fri, 23 Oct 2026 18:25:46 +0200 Subject: [PATCH] chore: bootstrap agent-ready docs and rules Co-Authored-By: Claude Opus 5.5 --- .claude/settings.json | 24 ++++++++ .codex/config.toml | 2 + .codex/rules/project.rules | 20 +++++++ .gemini/settings.json | 21 +++++++ .gitignore | 2 + AGENTS.md | 112 +++++++++++++++++++++++++++++++++++++ CLAUDE.md | 9 +++ DESIGN.md | 29 ++++++++++ GEMINI.md | 7 +++ PRODUCT.md | 34 +++++++++++ README.md | 6 ++ docs/ARCHITECTURE.md | 48 ++++++++++++++++ docs/DECISIONS.md | 50 +++++++++++++++++ docs/PERMISSIONS.md | 58 +++++++++++++++++++ docs/TODO.md | 43 ++++++++++++++ docs/plans/README.md | 11 ++++ docs/specs/README.md | 10 ++++ 17 files changed, 486 insertions(+) create mode 100644 .claude/settings.json create mode 100644 .codex/config.toml create mode 100644 .codex/rules/project.rules create mode 100644 .gemini/settings.json create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 DESIGN.md create mode 100644 GEMINI.md create mode 100644 PRODUCT.md create mode 100644 README.md create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/DECISIONS.md create mode 100644 docs/PERMISSIONS.md create mode 100644 docs/TODO.md create mode 100644 docs/plans/README.md create mode 100644 docs/specs/README.md diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..f70a14c --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,24 @@ +{ + "permissions": { + "allow": [ + "Bash(git status:*)", "Bash(git diff:*)", "Bash(git log:*)", "Bash(git show:*)", + "Bash(git branch --list:*)", "Bash(git rev-parse:*)", "Bash(git add:*)", "Bash(git commit:*)", + "Bash(bun install --frozen-lockfile:*)", "Bash(bun test:*)", "Bash(bun run typecheck:*)", + "Bash(bun run build:*)", "Bash(bun run dev:*)", "Bash(bun run start:*)" + ], + "ask": [ + "Bash(git push:*)", "Bash(git merge:*)", "Bash(git rebase:*)", "Bash(git switch:*)", + "Bash(git restore:*)", "Bash(git commit --amend:*)", "Bash(rm:*)", + "Bash(bun add:*)", "Bash(bun remove:*)", "Bash(bun update:*)", "Bash(bun upgrade:*)", + "Bash(bunx:*)", "Bash(npx:*)", "Bash(docker:*)" + ], + "deny": [ + "Bash(git push --force:*)", "Bash(git push -f:*)", "Bash(git push --force-with-lease:*)", + "Bash(git reset --hard:*)", "Bash(git clean:*)", "Bash(git add -f:*)", "Bash(git add --force:*)", + "Bash(git commit --no-verify:*)", "Bash(git commit -n:*)", + "Bash(rm -r:*)", "Bash(rm -R:*)", "Bash(rm -rf:*)", "Bash(rm -fr:*)", "Bash(rm -Rf:*)", + "Bash(rm -fR:*)", "Bash(rm --recursive:*)", "Bash(sudo:*)", + "Read(./.env)", "Read(./.env.*)", "Read(./secrets/**)" + ] + } +} diff --git a/.codex/config.toml b/.codex/config.toml new file mode 100644 index 0000000..5542eff --- /dev/null +++ b/.codex/config.toml @@ -0,0 +1,2 @@ +sandbox_mode = "workspace-write" +approval_policy = "on-request" diff --git a/.codex/rules/project.rules b/.codex/rules/project.rules new file mode 100644 index 0000000..25645cd --- /dev/null +++ b/.codex/rules/project.rules @@ -0,0 +1,20 @@ +# Rendered from docs/PERMISSIONS.md. No allow rules: in Codex, allow means "run outside the sandbox". +# Deny +prefix_rule(pattern = ["git", "push", ["--force", "-f", "--force-with-lease"]], decision = "forbidden", + justification = "Force-push rewrites shared history.") +prefix_rule(pattern = ["git", "reset", "--hard"], decision = "forbidden", justification = "Discards work.") +prefix_rule(pattern = ["git", "clean"], decision = "forbidden", justification = "Deletes untracked files.") +prefix_rule(pattern = ["git", "add", ["-f", "--force"]], decision = "forbidden", + justification = "Stages ignored files, e.g. secrets.") +prefix_rule(pattern = ["git", "commit", ["--no-verify", "-n"]], decision = "forbidden", justification = "Skips hooks.") +prefix_rule(pattern = ["rm", ["-r", "-R", "-rf", "-fr", "-Rf", "-fR", "--recursive"]], decision = "forbidden", + justification = "Recursive delete.") +prefix_rule(pattern = ["sudo"], decision = "forbidden", justification = "No privilege escalation.") +# Ask +prefix_rule(pattern = ["git", ["push", "merge", "rebase", "switch", "restore"]], decision = "prompt") +prefix_rule(pattern = ["git", "commit", "--amend"], decision = "prompt") +prefix_rule(pattern = ["rm"], decision = "prompt") +prefix_rule(pattern = ["bun", ["add", "remove", "update", "upgrade"]], decision = "prompt") +prefix_rule(pattern = ["bunx"], decision = "prompt") +prefix_rule(pattern = ["npx"], decision = "prompt") +prefix_rule(pattern = ["docker"], decision = "prompt") diff --git a/.gemini/settings.json b/.gemini/settings.json new file mode 100644 index 0000000..8e33f6d --- /dev/null +++ b/.gemini/settings.json @@ -0,0 +1,21 @@ +{ + "tools": { + "allowed": [ + "run_shell_command(git status)", "run_shell_command(git diff)", "run_shell_command(git log)", + "run_shell_command(git show)", "run_shell_command(git branch --list)", "run_shell_command(git rev-parse)", + "run_shell_command(git add)", "run_shell_command(git commit)", + "run_shell_command(bun install --frozen-lockfile)", "run_shell_command(bun test)", + "run_shell_command(bun run typecheck)", "run_shell_command(bun run build)", + "run_shell_command(bun run dev)", "run_shell_command(bun run start)" + ], + "exclude": [ + "run_shell_command(git push --force)", "run_shell_command(git push -f)", + "run_shell_command(git push --force-with-lease)", "run_shell_command(git reset --hard)", + "run_shell_command(git clean)", "run_shell_command(git add -f)", "run_shell_command(git add --force)", + "run_shell_command(git commit --no-verify)", "run_shell_command(git commit -n)", + "run_shell_command(rm -r)", "run_shell_command(rm -R)", "run_shell_command(rm -rf)", + "run_shell_command(rm -fr)", "run_shell_command(rm -Rf)", "run_shell_command(rm -fR)", + "run_shell_command(rm --recursive)", "run_shell_command(sudo)" + ] + } +} diff --git a/.gitignore b/.gitignore index 39bab0e..c049332 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ dist/ CLAUDE.local.md .worktrees/ screenshots/ +.superpowers/ +.claude/settings.local.json diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..a142a46 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,112 @@ +# 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 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 7"` +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 `