From 68470426649584516a427a3afe9f6f2ce170b295 Mon Sep 17 00:00:00 2001 From: Garret Patti <42485635+garretpatti@users.noreply.github.com> Date: Mon, 6 Jul 2026 12:48:27 -0400 Subject: [PATCH] add agents.md and login and tag bugfix --- AGENTS.md | 54 +++++++++++++++++++++++++++++ src/lib/components/TagEditor.svelte | 15 ++++++-- src/routes/logout/+page.server.ts | 7 +++- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..39cb52e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,54 @@ +# AGENTS.md — Game Grid + +## Stack + +- **SvelteKit 2** with **Svelte 5** (runes mode: `$state`, `$derived`, `$props`) +- **TypeScript** (strict), **Tailwind CSS 3** +- **SQLite** via `better-sqlite3` (native module — needs Python/make/g++) +- **bcrypt** (also native), **archiver** for on-the-fly .app zipping +- **Docker** for deployment with multi-stage build and bind-mounted game volumes + +## Commands + +```bash +npm run dev # dev server (vite dev) +npm run build # production build (vite build) +npm run check # typecheck: runs svelte-kit sync then svelte-check +npm run preview # preview production build +``` + +No test, lint, or format scripts exist. No CI. + +## Architecture + +**Two-tier library**: `GAMES_PATH/public/` (no auth) and `GAMES_PATH/private/` (login required). + +**Scanner runs on every layout load** (`src/routes/+layout.server.ts:6`). On first request the scanner walks the file tree, detecting games, series, platforms, cover art, and screenshots — populating the SQLite DB. Database is auto-created and auto-migrated on first access (`src/lib/server/db.ts`). + +**Auth**: single shared password (`APP_PASSWORD` env var), bcrypt-hashed at first use, session cookie is HMAC-signed with `SESSION_SECRET`. + +**CSRF checkOrigin is disabled** globally in `svelte.config.js` — intentional for local network access. + +**Native modules** (`better-sqlite3`, `bcrypt`) require Python 3, `make`, and `g++` for `npm install`. Docker build stage installs these explicitly. + +## Important files + +| File | Purpose | +|---|---| +| `src/lib/server/db.ts` | DB singleton, schema + migration | +| `src/lib/server/scanner.ts` | Filesystem scanner, game/series detection | +| `src/lib/server/auth.ts` | Session signing, password verification | +| `src/lib/platform.ts` | Platform detection from file extensions | +| `src/routes/+layout.server.ts` | Runs scanner & auth check on every request | +| `src/routes/games/[slug]/+page.server.ts` | Game detail, meta editing, tag actions | +| `src/routes/api/download/[fileId]/+server.ts` | File download, on-the-fly .app zipping | +| `svelte.config.js` | adapter-node, CSRF disabled | +| `docker-compose.yml` | Volume mounts, env vars, port mapping | + +## Gotchas + +- **Scanner is slow on first load** — it walks every file in both libraries. Plan for this: refreshing while a scan is running will queue another scan. +- **No hot reload for `$env/dynamic/private`** — env var changes require a dev server restart. +- **`.svelte-kit/tsconfig.json` is generated** by `svelte-kit sync` and needed for TypeScript to resolve `$lib` etc. The `check` command runs sync first, but in an IDE you may need to run `npm run dev` once to generate it. +- **Game files are served directly off disk** — paths come from the DB and map to real filesystem paths under `GAMES_PATH`. If bind mounts change, re-scan (hit the app or `POST /api/scan`) to update the DB. +- **`.app` bundles** (macOS) are zipped on-the-fly for download — this is CPU-intensive for large bundles. diff --git a/src/lib/components/TagEditor.svelte b/src/lib/components/TagEditor.svelte index bfdaf11..1bf7af3 100644 --- a/src/lib/components/TagEditor.svelte +++ b/src/lib/components/TagEditor.svelte @@ -16,7 +16,11 @@ {tag.name} {#if loggedIn} -
+ { + return async ({ result, update }) => { + if (result.type === 'success') await update(); + }; + }} class="contents">