Commit Graph
100 Commits
Author SHA1 Message Date
adrianbonpin 2303b9eb31 fix(wizard): always show remove button on existing screenshots
The 'showExistingRemove' guard was totalScreenshots >= 2, meaning you
could only delete existing screenshots when at maximum capacity.
Changed to >= 1 so the trash icon appears on every existing screenshot
during edit, regardless of the total count.
2026-06-29 00:40:12 +08:00
adrianbonpin 711e80efe1 fix(wizard): remove settings requirement gate for screenshot upload
The submission wizard required at least one game setting category before
allowing screenshot upload ('Add game settings to enable screenshot upload').
Removed that restriction — screenshots can now be attached to any entry
regardless of whether game settings were configured. The Decky plugin entries
typically don't include structured settings, and they should still support
screenshot attachments.
2026-06-29 00:37:18 +08:00
adrianbonpin 868faafb4d fix(plugin): screenshot limit, version/build fields, delete button, workspace scripts
- list_screenshots: bump limit 12 → 50 so users can scroll further back
- Add versionString + buildId to DeckyVaultImportV1, SessionData, and
  buildImportPayload. Import endpoint now saves them on new game versions.
- Screenshot delete button in preset detail modal: owner/admin sees a
  trash icon on hover that calls DELETE /api/performance/:id/screenshots/:sid
- Root workspace scripts for plugin workflow:
  bun run plugin:build  | plugin:zip | plugin:release | plugin:deploy
- Add deploy.sh (SSH scripts to push plugin to Deck)
2026-06-29 00:33:20 +08:00
adrianbonpin 8cff20c13e feat(plugin): thumbnail previews for screenshot picker
The screenshot picker now shows a live thumbnail next to each recent
Steam screenshot so users can identify the right one before selecting.

- read_screenshot() Python RPC: returns a base64 data URL for inline
  display. Tries Pillow downscale (320px), falls back to raw bytes
  (Steam Deck screenshots are ~78KB so this is fine without Pillow).
- Thumbnail component: 56x56 rounded image with loading placeholder.
- Thumbnails load progressively in both the picker list and the
  selected-shots rows via a useEffect.
2026-06-29 00:17:04 +08:00
adrianbonpin 59ecb4e4a6 feat(plugin page): robust SEO + sitemap inclusion
- Richer metadata: 14 targeted keywords, explicit robots directives
  (index/follow + googleBot max-image-preview), full OpenGraph with OG
  image, twitter summary_large_image, authors/creator/publisher fields
- 3 JSON-LD blocks: SoftwareApplication (version, downloadUrl, featureList,
  screenshot), FAQPage (4 install/usage Q&As), BreadcrumbList
- Add /plugin to STATIC_PAGES sitemap (monthly, priority 0.7)
- Update sitemap tests: static count 7→8, assert /plugin present
- All 25 sitemap tests pass
2026-06-29 00:10:07 +08:00
adrianbonpin b416f49e3d feat(plugin): attach Steam Deck screenshots to performance submissions
The plugin can now attach up to 2 Steam Deck screenshots (Steam + R1)
to a performance entry, uploaded together in one Submit tap.

Backend:
- Screenshot upload/delete endpoints now accept API key auth via
  requireRoleWithApiKeyFallback (was session-only), so the plugin's
  x-api-key header works. The 2-screenshot limit was already enforced
  server-side (MAX_SCREENSHOTS_PER_ENTRY = 2).

Plugin Python (main.py):
- list_screenshots(): scans ~/Pictures/Screenshots/ + Steam Client/
  subfolder, skips the most_recent.jpg duplicate, returns recent shots
- upload_screenshots(): hard-caps at 2, builds multipart/form-data with
  urllib, posts to /api/performance/:id/screenshots

Plugin UI (session-form.tsx):
- New Screenshots section (max 2) with a picker listing recent Steam
  screenshots (time + size), selected shots as removable rows
- Submit flow: upload entry → get entry ID → upload selected screenshots
  → combined success message (partial-success if screenshots fail)
2026-06-29 00:10:01 +08:00
adrianbonpin 841cbfe0c6 feat(game page): add dismissible plugin CTA banner above Performance Entries
Promotes the DeckyVault Decky plugin to Steam Deck owners browsing game
pages. Soft primary-tinted card with Gamepad2 icon, value-prop copy, and
'Get the plugin' CTA linking to /plugin. Dismissible via localStorage
(dv-plugin-cta-dismissed) so it stays gone across all games once closed.
Controller-navigable (data-gamepad-focusable), responsive layout.
2026-06-29 00:01:57 +08:00
adrianbonpin 9f40f52aab feat(plugin page): 3-act narrative layout + final screenshots
Redesign 'See it in action' as a 3-act story with clearer flow:
- Act 1: Get set up (3 cards: panel, pair, launch option)
- Act 2: Capture performance (2 cards: recording, session-form)
- Act 3: Share & compare (1 large featured card: entry-live)

Gradient line connectors between acts imply flow; numbered badges moved
from per-card to per-act so cards feel like supporting visuals.

Add root smooth scrolling (scroll-smooth on <html>) for hash-link anchors.

Add recording + session-form screenshots (in-game captures from Steam
pause overlay), each rendered with the device-photo treatment
(rounded + drop shadow) to match the other in-game-style shots.

Flip all HAS_SCREENSHOT flags to true — the full gallery is now live.
2026-06-28 23:52:53 +08:00
adrianbonpin 59332b4ce6 feat(plugin page): wire up screenshots + add compress script
- Update file paths to match provided .jpg captures (panel-overview, pair-qr,
  launch-option, entry-live)
- Flip HAS_SCREENSHOT for the 4 available ones; keep recording + session-form
  as placeholders for now (user will add in-game/phone photos later)
- entry-live.png → entry-live.jpg (smaller, still good quality at 1400px)
- All images compressed: Deck shots 1000px / q78, web shot 1400px / q78
- Add scripts/compress-screenshots.sh for re-compressing anytime
2026-06-28 23:43:23 +08:00
adrianbonpin 07933dca9e feat(plugin page): device-photo treatment for in-game screenshots
The QAM overlay can't be captured by Steam's screenshot shortcut while a game
runs, so the 'recording' and 'session-form' shots will be phone photos of the
Deck. These now render with rounded corners + drop shadow + ring so a device
photo looks intentional rather than like a broken screenshot. Placeholders
label them 'device photo coming soon'.
2026-06-28 23:34:30 +08:00
adrianbonpin 48758f4704 chore: add release script + use 16:10 aspect ratio for plugin screenshots
release.sh: build, package ZIP, tag, and create GitHub release in one command.
Screenshot slots now use 16:10 (matches Steam Deck's 1280x800 screen) with
object-contain so full-screen Deck captures fit without cropping.
2026-06-28 23:01:34 +08:00
adrianbonpin 4958220c55 feat: add /plugin docs page + TDP peripheral overhead
Plugin docs page (/plugin):
- Hero, feature grid, numbered install guide, screenshot gallery, install CTA
- Navbar 'Plugin' link added
- Screenshot slots with placeholders for 6 captures (flip HAS_SCREENSHOT
  once PNGs are dropped into /public/plugin/)
- Structured data (SoftwareApplication) + breadcrumbs

TDP fix:
- Add 3W fixed overhead to CPU+GPU power for screen/fan/speakers/peripherals
  so reported TDP is closer to total system power draw
2026-06-28 22:49:13 +08:00
adrianbonpin 383945ca14 build: add scripts/build-zip.sh to package plugin as a Decky-installable ZIP
The ZIP bundles plugin.json, main.py, package.json, dist/index.js (+ map) at
the archive root (no enclosing folder) — the format Decky's 'Install Plugin
from ZIP File' / 'Install Plugin from URL' expects.

Usage:
  bun run build:zip   # build + package → releases/plugin-v<version>.zip
  bun run zip         # package already-built dist only
2026-06-28 22:42:13 +08:00
adrianbonpin 3ed0ee3128 fix: API key test now actually verifies the key against a real auth endpoint
The old test hit /api/games/lookup which is a public endpoint with no auth,
so it never checked the key — any key (or a deleted one) reported as valid.

- Add GET /api/plugin/verify-key endpoint that uses authenticateWithApiKey
  to properly verify the x-api-key header via Better Auth
- Plugin test_api_key now calls /api/plugin/verify-key instead of games-lookup
- Returns the linked user's name + avatar on success for richer feedback
2026-06-28 22:22:47 +08:00
adrianbonpin 763114df6f fix: correct 'Manage API Keys' link from /pair success screen
- Profile page now reads ?tab= query param to open Settings tab directly
- Settings container reads ?subtab= query param to open API Keys directly
- /pair success link updated to /profile?tab=settings&subtab=api-keys (was /profile/settings?tab=api-keys which 404'd)
2026-06-28 22:19:51 +08:00
adrianbonpin 02553445b1 refactor: redesign plugin panel layout
Consolidate 7 flat sections into 5 logical groups with clear hierarchy:
1. Recording (primary action)
2. Account (QR pairing + manual key + test, with readiness indicator)
3. MangoHud Setup (merge config write/verify + launch option + numbered guide)
4. System (MangoHud check + game/app info)
5. Advanced (server, paths, hardware, config backup)

Add reusable helpers (SectionHint, StatusRow, InfoRow, CodeBlock, BtnContent)
for consistent styling. Improve recording timer with radial glow, error/success
states with colored backgrounds, and recent recordings as cards.
2026-06-28 22:12:57 +08:00
adrianbonpin 1de08ed4ec feat: QR code phone pairing for Decky plugin + MangoHud guide revision + SteamOS version fix
- Add plugin_pairings table + migration (0028) for short-lived pairing sessions
- Add pairing API: POST /api/plugin/pair/initiate, GET /status/:token, POST /confirm
- Add /pair web page: user scans QR on phone, confirms, API key auto-created
- Plugin: 'Pair with Phone' button renders QR code (qrcode.react), polls for status, saves API key
- Plugin: new initiate_pair + check_pair_status Python RPCs
- Revise MangoHud Setup Guide into clean numbered steps
- Fix SteamOS version detection: read VERSION_ID + BUILD_ID (was just 'SteamOS')
2026-06-28 22:09:39 +08:00
adrianbonpin b637b55011 fix: remove settingsJson IS NOT NULL filter from game page and API queries 2026-06-28 21:56:08 +08:00
adrianbonpin 2a90a2d6f0 docs: add v1.0.0 changelog for DeckyVault plugin release 2026-06-28 21:38:19 +08:00
adrianbonpin 4c531beb11 chore(plugin): bump version to 1.0.0 2026-06-28 21:37:07 +08:00
adrianbonpin c67d99ad63 fix(plugin): use currentColor instead of white for icon so it doesn't disappear on hover 2026-06-28 21:36:23 +08:00
adrianbonpin dedc756dde fix(api): remove settingsJson IS NOT NULL filter so entries without in-game settings show up 2026-06-28 21:34:14 +08:00
adrianbonpin f7c7ed7bbe feat(plugin): show game name and app ID in status section 2026-06-28 21:30:58 +08:00
adrianbonpin 234877cef2 fix(plugin): detect Steam App ID from compatdata, read proper game name from appmanifest 2026-06-28 21:28:56 +08:00
adrianbonpin 9b6b37f8a4 fix(plugin): poll-based game detection via Python backend, remove broken SteamClient events 2026-06-28 21:25:57 +08:00
adrianbonpin 0c44b39e9e fix(plugin): use correct SteamClient.GameSessions.RegisterForAppLifetimeNotifications API for game detection 2026-06-28 21:21:29 +08:00
adrianbonpin 83ab7fa1e6 fix(plugin): browser-like UA for Cloudflare, detect current game, fix proton version, single-line notes 2026-06-28 21:15:17 +08:00
adrianbonpin 7ebb2669a1 fix(plugin): sum cpu_power + gpu_power for TDP, remove in-game settings, single-line notes 2026-06-28 21:03:00 +08:00
adrianbonpin ec1d4a0746 fix(plugin): remove in-game settings, single-line notes, record-while-in-game flow 2026-06-28 21:01:53 +08:00
adrianbonpin e3c3ed54c6 fix(plugin): update copy button to use wrapper script path 2026-06-28 20:56:40 +08:00
adrianbonpin b98528fbaf fix(plugin): add wrapper script to force MangoHud config file 2026-06-28 20:54:01 +08:00
adrianbonpin 7a653198e7 fix(plugin): update verify config check, add debug list tmp 2026-06-28 20:51:47 +08:00
adrianbonpin 2b53b30be6 fix(plugin): read mangohud version from script file instead of running it 2026-06-28 20:48:27 +08:00
adrianbonpin 6a486ed257 fix(plugin): add debug logging to check_mangohud 2026-06-28 20:47:43 +08:00
adrianbonpin 55bc86874a fix(plugin): use os.popen instead of subprocess for mangohud version 2026-06-28 20:46:42 +08:00
adrianbonpin 6b2dada082 fix(plugin): use full path for mangohud, return empty string instead of unknown 2026-06-28 20:45:28 +08:00
adrianbonpin 912b783593 fix(plugin): fallback version check with full binary path 2026-06-28 20:43:37 +08:00
adrianbonpin e1269b2de1 fix(plugin): clean up MangoHud version display 2026-06-28 20:40:32 +08:00
adrianbonpin 928ec8ec9a fix(plugin): retry mangohudctl start logging until game launches 2026-06-28 20:38:18 +08:00
adrianbonpin 37cc24ff60 fix(plugin): add control socket, autostart_log=1, timeout-safe mangohudctl 2026-06-28 20:33:12 +08:00
adrianbonpin aa52e0feb6 fix(plugin): use autostart_log instead of mangohudctl, improve log search 2026-06-28 20:29:38 +08:00
adrianbonpin f61227e7fc fix(plugin): move Recording to top, clean up setup guide layout 2026-06-28 20:25:23 +08:00
adrianbonpin ea3b01b28b fix(plugin): add User-Agent header to API requests for Cloudflare compat 2026-06-28 20:23:58 +08:00
adrianbonpin 6e1957524b feat(plugin): restructure layout like LSFG-VK, use mangohudctl for logging 2026-06-28 20:21:33 +08:00
adrianbonpin c230367d14 fix(plugin): search for any MangoHud log in /tmp/ instead of fixed filename 2026-06-28 19:04:35 +08:00
adrianbonpin 545d1c5cfa fix(plugin): add missing useState import 2026-06-28 18:59:20 +08:00
adrianbonpin 65e56702b0 fix(plugin): add manual game name input, autostart MangoHud logging 2026-06-28 18:57:51 +08:00
adrianbonpin 7ab7af468a fix(plugin): autostart MangoHud logging on record, write config on start 2026-06-28 18:56:43 +08:00
adrianbonpin 677adc5ad0 fix(plugin): revert to RegisterForGameStarted/Stopped for runtime compat 2026-06-28 18:54:46 +08:00
adrianbonpin a49aca93c7 fix(plugin): add missing Field import for textareas 2026-06-28 18:54:05 +08:00
adrianbonpin 80caa167cc fix(plugin): use correct SteamClient API, alwaysRender true, wrap stop in try-catch 2026-06-28 18:51:53 +08:00
adrianbonpin df66e0405d fix(plugin): set icon to 16x16 2026-06-28 18:43:56 +08:00
adrianbonpin 297fbc0320 fix(plugin): remove explicit icon size, let container handle scaling 2026-06-28 18:40:09 +08:00
adrianbonpin 1ea079917f fix(plugin): add second gear path layer for proper icon rendering 2026-06-28 18:36:24 +08:00
adrianbonpin 88f6c3dadf fix(plugin): use full DeckyVault SVG icon with all paths and transforms 2026-06-28 18:31:53 +08:00
adrianbonpin 7b2f031c3b fix(plugin): fix SVG viewBox for proper icon scaling 2026-06-28 18:28:28 +08:00
adrianbonpin f97bc0b8b7 feat(plugin): use DeckyVault brand SVG icon 2026-06-28 18:06:13 +08:00
adrianbonpin f7d36e82ef feat(plugin): add verify config and copy launch option buttons 2026-06-28 17:59:05 +08:00
adrianbonpin bd14fdaf82 feat(web): add Download Plugin Config button to API key creation 2026-06-28 17:45:32 +08:00
adrianbonpin 3196812c0d fix(plugin): dropdown data prop, always show guide, add config export/import 2026-06-28 17:43:36 +08:00
adrianbonpin 4b7efd3c5c fix: accept steamAppId=0 in games lookup, treat 400 as valid key in plugin test 2026-06-28 17:36:32 +08:00
adrianbonpin 046e483861 fix(plugin): hybrid SSL context - verify when possible, fall back gracefully 2026-06-28 17:33:55 +08:00
adrianbonpin 961c81e97f fix(plugin): use unverified SSL context for DeckyVault API calls 2026-06-28 17:32:14 +08:00
adrianbonpin 2168d31052 fix(plugin): merge tabs into single panel, use TextField for controller input 2026-06-28 17:29:22 +08:00
adrianbonpin 5a6211ebea fix(plugin): replace raw buttons with ButtonItem for controller navigation 2026-06-28 17:26:20 +08:00
adrianbonpin b7f9df8439 docs: update README with monorepo structure and Decky Loader plugin docs 2026-06-28 17:07:54 +08:00
adrianbonpin 7d016a7b8c chore(plugin): build plugin and verify dist output 2026-06-28 08:00:56 +08:00
adrianbonpin 793d7bb9f4 feat(plugin): wire together entry point with definePlugin and SteamClient events 2026-06-28 07:59:39 +08:00
adrianbonpin 82fbd86fb0 feat(plugin): add settings panel (API key, export path, MangoHud setup) 2026-06-28 07:58:34 +08:00
adrianbonpin 092071e410 feat(plugin): add session form component (manual inputs + export/upload) 2026-06-28 07:58:04 +08:00
adrianbonpin 87eeb3fb39 feat(plugin): add main panel component (record/stop + recent sessions) 2026-06-28 07:57:34 +08:00
adrianbonpin ad816d1ae5 feat(plugin): add frontend state management (settings + session hooks) 2026-06-28 07:57:11 +08:00
adrianbonpin 026bd299ca feat(plugin): add typed RPC wrappers for Python backend 2026-06-28 07:56:26 +08:00
adrianbonpin ab6a91e13f feat(plugin): update SteamClient type declarations 2026-06-28 07:56:08 +08:00
adrianbonpin 6c5ac9814d feat(plugin): add upload and API key test methods in backend 2026-06-28 07:55:56 +08:00
adrianbonpin 890fab3da5 feat(plugin): add export-to-file method in backend 2026-06-28 07:55:32 +08:00
adrianbonpin 6b7dfdd53c feat(plugin): add system info reader (hardware, OS, Proton, launch options) 2026-06-28 07:55:00 +08:00
adrianbonpin e48efe86b1 feat(plugin): add MangoHud log parser with unit tests 2026-06-28 07:54:32 +08:00
adrianbonpin dc1281411d feat(plugin): add MangoHud status check and config writing to backend 2026-06-28 07:53:02 +08:00
adrianbonpin 67e9e2cf63 feat(plugin): add Python backend skeleton with settings management 2026-06-28 07:52:33 +08:00
adrianbonpin 5598e0db59 feat(plugin): update tsconfig for Decky frontend build 2026-06-28 07:51:38 +08:00
adrianbonpin c1eba0c047 feat(plugin): update plugin.json with correct Decky metadata fields 2026-06-28 07:51:26 +08:00
adrianbonpin bcd208c7c8 feat(plugin): use @decky/rollup for build config 2026-06-28 07:51:05 +08:00
adrianbonpin 004da4afff feat(plugin): update package.json with @decky SDK dependencies 2026-06-28 07:50:29 +08:00
adrianbonpin 57e5cf2dc6 docs: add DeckyVault plugin implementation plan 2026-06-28 07:48:25 +08:00
adrianbonpin 927bbe13a3 docs: add DeckyVault plugin design spec 2026-06-28 07:38:41 +08:00
adrianbonpin eaa7c85e09 fix: prevent passkey conditional ui unhandled rejection blocking login 2026-06-28 05:55:00 +08:00
adrianbonpin 4cf8a42742 fix: add zod as direct dependency for bun workspace resolution 2026-06-28 05:44:46 +08:00
adrianbonpin a63cc52108 fix: upgrade better-auth to v1.6.22 for api-key plugin compatibility 2026-06-28 05:41:45 +08:00
adrianbonpin 835fab2600 chore: add .worktrees/ to gitignore 2026-06-28 05:33:13 +08:00
adrianbonpin 6cb407acaa merge: convert to bun workspaces monorepo 2026-06-28 05:31:30 +08:00
adrianbonpin f7eda2bfc0 feat: add better-auth api-key plugin, import endpoint, and API key UI 2026-06-28 05:30:48 +08:00
adrianbonpin cd72b7a948 refactor: convert to bun workspaces monorepo
- Move web app into apps/web/
- Create packages/shared/ with shared types
- Create plugins/decky-vault/ scaffold
- Root package.json manages workspaces only
2026-06-28 05:20:28 +08:00
adrianbonpin c4bede20d4 fix: remove duplicate sitemap route
- app/sitemap.ts already generates the sitemap index via generateSitemaps()
- app/sitemap.xml/route.ts was a duplicate manual version at the same path
2026-06-26 22:12:37 +08:00
adrianbonpin 9ee927ce77 fix: prevent scroll capture on card rows with pointer-events
- Wrap card containers in overflow-x-auto with pointer-events: none
- Inner flex div gets pointer-events: auto so cards remain interactive
- Main page scrolling works normally when cursor is over card rows
2026-06-26 22:03:44 +08:00
adrianbonpin 26fc600266 fix: replace horizontal scroll with flex-wrap on card rows
- Remove overflow-x-auto so cards don't capture scroll events
- Cards now wrap naturally into rows with flex-wrap
- Main page scrolling works normally even when cursor is over cards
2026-06-26 22:00:58 +08:00
adrianbonpin 945d0dc96d fix: prevent vertical overflow on card scroll containers
- Add overflow-y-hidden to all three card containers (skeleton, GameSection, SaleSection)
- Keeps horizontal scrolling but prevents any vertical scroll
2026-06-26 21:59:59 +08:00
adrianbonpin b91068ac64 fix: prevent vertical overscroll on card scroll containers 2026-06-26 21:58:20 +08:00
adrianbonpin 38c58cdbd2 style: add rounded corners to card images and hide scrollbars
- Add rounded-xl to card images so corners match the card border radius
- Replace scrollbar-thin with scrollbar-none on horizontal scroll containers
2026-06-26 21:57:13 +08:00
adrianbonpin 236f293879 refactor: redesign landing page card hover behavior
- Remove card-level scale-up animation (whileHover/whileTap)
- Image now scales down slightly on hover instead of scaling up
- Keeps border/background color transitions for hover feedback
2026-06-26 21:54:53 +08:00