Commit Graph
100 Commits
Author SHA1 Message Date
adrianbonpin 7e016bfa50 chore: bump plugin version to 1.1.0 2026-07-13 05:50:24 +08:00
adrianbonpin bfd36ad632 fix: address final review — 404 error field, aggregate estFps, recent entries, panel props 2026-07-13 05:30:17 +08:00
adrianbonpin d63ec4a42e fix(plugin): handle fetch errors, race conditions, and error states in library panel 2026-07-13 05:21:28 +08:00
adrianbonpin 66d16bc25c feat(plugin): inject DeckyVault section into library app-details page 2026-07-13 05:17:35 +08:00
adrianbonpin ed04b87f16 fix(plugin): don't cache error responses, add SSRF guard to plugin_get 2026-07-13 05:13:01 +08:00
adrianbonpin 4dfc23d35f feat(plugin): plugin_get proxy + typed library-panel fetch/cache 2026-07-13 05:10:04 +08:00
adrianbonpin 5b107bddf7 fix(api): align /devices version scope, add Vary header, add validation + tests 2026-07-13 05:07:51 +08:00
adrianbonpin 0ad133492b feat(api): public plugin game-lookup endpoint for library panel 2026-07-13 05:03:26 +08:00
adrianbonpin 3d2f1384df fix(plugin): extract _collect_screenshots pure function, add fallback test 2026-07-13 04:59:17 +08:00
adrianbonpin 0018673747 fix(plugin): discover Steam Game Mode screenshots + safe preview fallback 2026-07-13 04:54:17 +08:00
adrianbonpin 5759fdbafd fix(plugin): align _find_mangohud_log with scoped clear, reset lastLogPath on error 2026-07-13 04:51:29 +08:00
adrianbonpin 61154dbda3 fix(plugin): safe recording start — no mid-game config rewrite, scoped log clear 2026-07-13 04:45:37 +08:00
adrianbonpin fd47803127 fix(plugin): guard against NaN fpsAvg bypassing upload check 2026-07-13 04:42:03 +08:00
adrianbonpin a975497c16 fix(plugin): block no-FPS uploads and clamp FPS before submit 2026-07-13 04:38:56 +08:00
adrianbonpin bf33f8735d fix(api): raise FPS caps to 1000 and validate FPS before game lookup 2026-07-13 04:35:24 +08:00
adrianbonpin dfd900581a docs: implementation plan for plugin bugs + library injection 2026-07-12 18:49:43 +08:00
adrianbonpin 75507b4984 docs: design spec for plugin bugs + library-injection features 2026-07-12 09:21:27 +08:00
adrianbonpin ab8a213ba6 feat(plugin page): document full install path with screenshots
The plugin isn't on the Decky Loader store yet, so the install section
needs to walk users through the manual path:

- Enable Developer mode in Decky → General settings
- Download the plugin ZIP from GitHub Releases
- Install Plugin from ZIP File in Decky → Developer tab

Adds two new screenshots to the 3-act narrative (now 4 acts):
'Install the plugin' is the new act 1, the existing setup/capture/share
acts are renumbered to 2/3/4. The How it works step list grows from 4
to 6 entries to match the new flow.

The old step 1 still pointed users at the Plugin Browser, which is no
longer accurate — copy now describes Decky Loader as a one-time
prerequisite and points users at the GitHub release for the plugin.
2026-06-29 00:54:51 +08:00
adrianbonpin c3215d9766 fix(api): replace raw = ANY() SQL with Drizzle inArray()
The sql template literal '= ANY()' was causing 500 errors during
screenshot deletion in the PATCH edit endpoint. Replaced all 3 occurrences
with Drizzle's native inArray() which safely handles array parameters,
including empty arrays.
2026-06-29 00:49:41 +08:00
adrianbonpin 60266ad9c9 fix(api): filter empty/invalid screenshot IDs before ANY query
The PATCH /api/performance/:id/edit endpoint was passing raw
removedScreenshotIds from the client to an = ANY() SQL clause.
Empty strings or invalid values would crash the query. Added a filter
to ensure only non-empty string IDs are used.
2026-06-29 00:46:45 +08:00
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