Commit Graph
100 Commits
Author SHA1 Message Date
adrianbonpin 5713f5e792 fix(release): brace variable before unicode ellipsis (#4) 2026-08-20 19:38:20 +00:00
adrianbonpin e59aca9562 Migrate GitHub links to Gitea + release plugin via tea (#3) 2026-08-20 19:36:16 +00:00
adrianbonpin af13853a61 build: use bun for installs and pin better-auth core deps (#2) 2026-08-18 18:05:55 +00:00
adrianbonpin 4af95b0f0f chore: remove webhook test marker 2026-08-19 01:47:38 +08:00
adrianbonpin 5c02e91880 chore: webhook connectivity test 2026-08-19 01:46:57 +08:00
adrianbonpin ec2c21115b fix(auth): pin better-auth packages to exact 1.6.22 (#1) 2026-08-18 17:29:35 +00:00
adrianbonpin 2f9949c2bb Merge branch 'dev' into prod 2026-07-25 17:00:28 +08:00
adrianbonpin 56a916189b docs: add v1.1.0 update entry 2026-07-25 17:00:26 +08:00
adrianbonpin 7cc8ebcfb6 Merge branch 'dev' into prod 2026-07-25 16:59:00 +08:00
adrianbonpin bf29235b75 chore: update plugin page version to 1.1.0 2026-07-25 16:58:58 +08:00
adrianbonpin 8cc8db562d Merge branch 'dev' into prod 2026-07-13 07:08:44 +08:00
adrianbonpin a8e189ca84 fix(plugin): add 16px horizontal padding to stats row 2026-07-13 07:07:42 +08:00
adrianbonpin 3b27094973 fix(plugin): inject CSS !important to constrain DialogButtonPrimary width, drop PanelSectionRow wrapper 2026-07-13 07:05:27 +08:00
adrianbonpin 9b38b17eb0 fix(plugin): prevent overflow — shrink stats, constrain button to 110px, hidden overflow 2026-07-13 07:03:28 +08:00
adrianbonpin 2a1943cf35 fix(plugin): constrain View Details button width to 130px 2026-07-13 06:55:44 +08:00
adrianbonpin c02ae28982 fix(plugin): use DialogButtonPrimary for View Details (like HLTB) 2026-07-13 06:54:25 +08:00
adrianbonpin 210046c97e style: extend navbar breakpoints to lg to move to collapsable sidebar (for smaller devices) 2026-07-13 06:52:36 +08:00
adrianbonpin 4f503e373a fix(plugin): use Focusable for compact styled View Details button 2026-07-13 06:47:51 +08:00
adrianbonpin 17d70f175d fix(plugin): use ButtonItem for gamepad-navigable View Details 2026-07-13 06:44:36 +08:00
adrianbonpin a66c13daa0 fix(plugin): single row — stats + View Details inline, space-between 2026-07-13 06:41:15 +08:00
adrianbonpin eedcf9efa6 fix(plugin): show global fallback warning, compact View Details button 2026-07-13 06:39:09 +08:00
adrianbonpin ef96766659 fix(plugin): auto-detect device via DMI, remove selector, fall back to global 2026-07-13 06:37:27 +08:00
adrianbonpin 723885202d fix(plugin): space-between layout, no-shrink dropdown, horizontal padding 2026-07-13 06:33:01 +08:00
adrianbonpin ba218a52b5 Merge branch 'dev' into prod 2026-07-13 06:30:02 +08:00
adrianbonpin c5ac3ba567 fix(api): add tdpAvg to estFps type in buildPluginGameResponse args 2026-07-13 06:30:00 +08:00
adrianbonpin d409e27a95 fix(plugin): game URL by steamAppId, inline dropdown to save vertical space 2026-07-13 06:28:41 +08:00
adrianbonpin c80c1d5775 fix(plugin): centered stats, View Details button with fallback, separate rows 2026-07-13 06:25:55 +08:00
adrianbonpin 7021f4da07 fix(plugin): single row stats + dropdown + button, no filler text 2026-07-13 06:22:13 +08:00
adrianbonpin f2f600f206 Merge branch 'dev' into prod 2026-07-13 06:20:38 +08:00
adrianbonpin c974699024 feat: add TDP to quick stats + open-on-DeckyVault button 2026-07-13 06:20:30 +08:00
adrianbonpin b108f0436b fix(plugin): minimal library panel — single stats row, no header 2026-07-13 06:18:21 +08:00
adrianbonpin 91f6324bf1 Merge branch 'dev' into prod 2026-07-13 06:01:15 +08:00
adrianbonpin ed0ed6b089 fix(plugin): guard non-numeric appId, improve 404 error handling 2026-07-13 06:01:08 +08:00
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 1702c13dc1 Merge branch 'dev' into prod 2026-06-29 00:55:08 +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 d367665163 Merge branch 'dev' into prod 2026-06-29 00:49:43 +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 a0cc66e6bc Merge branch 'dev' into prod 2026-06-29 00:46:47 +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 88768bffb6 Merge branch 'dev' into prod 2026-06-29 00:40:14 +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 70438a6fd3 Merge branch 'dev' into prod 2026-06-29 00:37:20 +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 dc7f0c23ea Merge branch 'dev' into prod 2026-06-29 00:33:22 +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 e64cb5c8a3 Merge branch 'dev' into prod 2026-06-29 00:17:06 +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 1b8e1d465f Merge branch 'dev' into prod 2026-06-29 00:10:14 +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 44a103cf8f Merge branch 'dev' into prod 2026-06-28 23:43:31 +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 28c3166813 Merge branch 'dev' into prod 2026-06-28 23:34:32 +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 b9d36870ab Merge branch 'dev' into prod 2026-06-28 23:01:38 +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 146d642afd Merge branch 'dev' into prod 2026-06-28 22:49:16 +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 d575ca968e Merge branch 'dev' into prod 2026-06-28 22:22:49 +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 7a02d2f40e Merge branch 'dev' into prod 2026-06-28 22:19:53 +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 d486ca3021 Merge branch 'dev' into prod 2026-06-28 22:13:03 +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 f7ebd8fcad Merge branch 'dev' into prod 2026-06-28 22:09:44 +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 4395467ac6 Merge branch 'dev' into prod 2026-06-28 21:56:18 +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 62049fe00a Merge branch 'dev' into prod 2026-06-28 21:38:24 +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 799f53d7c1 Merge branch 'dev' into prod 2026-06-28 21:35:03 +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