# AGENTS.md OBS/browser overlay that reads Beat Saber Plus Song Overlay events over WebSocket (`ws://localhost:2947/socket`). Serve the folder with **`deno task serve`** (see [`src/server/serve.ts`](src/server/serve.ts)) so the request-queue JSON loads from the same origin; configure the BS+ database path via `CHAT_REQUEST_DATABASE` or `chat-request-database.path`. ## Preference: HTTP only, no `file://` Do **not** add or maintain code paths for opening the overlay as **`file://`**. The client assumes **`http:` / `https:`** for fetching JSON (cache-busted `fetch`). Do not reintroduce XHR/`file:` fallbacks or docs that suggest local file URLs—one supported way: serve with Deno (or another HTTP server) per [`README.md`](README.md). ## Files of interest - [`index.html`](index.html) — Page shell: markup for map info, time bar, score, settings dialog; pulls `index.css` and bundled `index.js` module. - [`src/client/index.ts`](src/client/index.ts) — Main overlay source in TypeScript; connects to BS+ WebSocket, parses events (`gameState`, `mapInfo`, `pause`, `resume`, `score`), updates DOM, and manages settings/hash state. - [`src/client/types.ts`](src/client/types.ts) — Shared TypeScript types for BS+ payloads/events and chat request JSON. - [`index.js`](index.js) — Bundled browser output generated from `src/client/index.ts` via `deno task build`. - [`index.css`](index.css) — Layout, theming, visibility toggles driven by body classes and CSS variables from settings. - [`src/server/serve.ts`](src/server/serve.ts) — Deno static server + optional mapping of `ChatRequest.json` / `database.json` to the real BS+ `Database.json` path. - [`deno.json`](deno.json) — Deno tasks and TypeScript compiler options (`build`, `serve`, `dev`). - [`images/`](images/) — Cover fallback (`unknown.svg`), characteristic icons under `images/characteristic/` (filenames match BS+ characteristic strings). - [`README.md`](README.md) — User-facing usage (Deno, OBS URL, BS+ module). - [`dprint.json`](dprint.json) — Formatter config for the repo. - [`.editorconfig`](.editorconfig) — Basic indent/charset rules for editors. ## Out of scope here Beat Saber Plus itself (game mod) exposes the socket; this repo is only the HTML/CSS/TS client. ## Recent implementation notes (2026-04) - **Live API calls must be runtime-proxied**: browser/OBS hits CORS on BeatLeader/BeatSaver. Keep live requests same-origin via `src/server/serve.ts`: - `/api/beatleader?path=/...` - `/api/beatsaver?path=/...` - **Map correlation is hash-based**: resolve BeatSaver map/hash first, then BeatLeader leaderboards via `/leaderboards/hash/{hash}`. - **Score source for friend matching**: use `/leaderboard/{leaderboardId}` scores for stable `playerId` fields; do not rely on v5 score payload shape for player IDs. - **Mutual friends definition**: intersection of `/player/{id}/followers?type=Following` and `type=Followers` (paged by `page` + `count` only). - **Overlay feature added**: `#friendScores` panel shows best accuracy per mutual friend for current map, sorted DESC. - **Debug defaults**: - mock map key: `4f4e4` - debug BeatLeader player id: `76561199407393962` - both debug inputs must have no effect when debug is disabled.