5
Passed
1
Failed
0
Skipped
6
Total
10.2s
Duration
Step durations
TypeScript typecheck2.2s
Build (production)577 ms
Unit tests (vitest)1.2s
Package (.zip)931 ms
Verify package148 ms
Compat validation5.1s
TypeScript typecheck2.2sPASS▶
> deck-shelves@2.4.0 typecheck /Users/santojon/Projects/Deck-Shelves > tsc --noEmit
Build (production)577 msPASS▶
> deck-shelves@2.4.0 build:release /Users/santojon/Projects/Deck-Shelves > node scripts/build/build-decky.mjs --mode production vite v8.0.14 building client environment for production... transforming...✓ 294 modules transformed. rendering chunks... computing gzip size... dist/chunks/rolldown-runtime-B-pNeFgv.js 0.91 kB │ gzip: 0.47 kB dist/chunks/steamHost-BuRog5c8.js 0.96 kB │ gzip: 0.45 kB dist/chunks/customfilters-CeiM60HE.js 2.87 kB │ gzip: 1.06 kB dist/chunks/pluginApi-BswdxDmF.js 8.46 kB │ gzip: 2.33 kB dist/chunks/onlineStore-BIRGpWmE.js 11.59 kB │ gzip: 3.92 kB dist/chunks/zh-CN-lBMdrjgV.js 59.74 kB │ gzip: 21.38 kB dist/chunks/zh-TW-CmPsZ8lA.js 60.96 kB │ gzip: 21.51 kB dist/chunks/en-GB-CFzLVGFl.js 61.25 kB │ gzip: 19.18 kB dist/chunks/nl-NL-BVOAV8Vc.js 64.03 kB │ gzip: 20.68 kB dist/chunks/pl-PL-B9FVe1ck.js 64.36 kB │ gzip: 21.36 kB dist/chunks/it-IT-BwOFOb9t.js 65.00 kB │ gzip: 20.58 kB dist/chunks/tr-TR-D58aJvCi.js 65.52 kB │ gzip: 21.22 kB dist/chunks/de-DE-BiT0h-bz.js 65.67 kB │ gzip: 21.25 kB dist/chunks/es-419-BErkqhFc.js 65.93 kB │ gzip: 20.78 kB dist/chunks/ko-KR-D1I2ndzX.js 65.99 kB │ gzip: 21.40 kB dist/chunks/pt-BR-D2WvEsk1.js 66.04 kB │ gzip: 20.23 kB dist/chunks/pt-PT-IgHuzrF5.js 66.22 kB │ gzip: 20.45 kB dist/chunks/es-ES-UiRHFs_B.js 66.39 kB │ gzip: 20.72 kB dist/chunks/fr-CA-CqmeUwQl.js 67.00 kB │ gzip: 21.11 kB dist/chunks/fr-FR-BlY7_-Lr.js 67.61 kB │ gzip: 21.04 kB dist/chunks/ja-JP-DWWoK62h.js 70.99 kB │ gzip: 22.18 kB dist/chunks/uk-UA-EJtJjTT3.js 83.05 kB │ gzip: 23.47 kB dist/chunks/ru-RU-CweGqEJt.js 83.33 kB │ gzip: 23.78 kB dist/chunks/steam-ekxMWt5I.js 88.87 kB │ gzip: 22.01 kB dist/chunks/settingsStore-D85apjLo.js 131.50 kB │ gzip: 29.17 kB dist/index.js 864.20 kB │ gzip: 197.81 kB ✓ built in 172ms
Unit tests (vitest)1.2sPASS▶
> deck-shelves@2.4.0 test /Users/santojon/Projects/Deck-Shelves > vitest run RUN v4.1.7 /Users/santojon/Projects/Deck-Shelves (node:45715) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45720) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45717) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45718) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45726) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45732) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45739) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45714) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) (node:45741) ExperimentalWarning: localStorage is not available because --localstorage-file was not provided. (Use `node --trace-warnings ...` to show where the warning was created) Test Files 23 passed (23) Tests 339 passed (339) Start at 11:10:52 Duration 836ms (transform 1.36s, setup 0ms, import 2.48s, tests 225ms, environment 531ms)
Package (.zip)931 msPASS▶
> deck-shelves@2.4.0 build:release /Users/santojon/Projects/Deck-Shelves > node scripts/build/build-decky.mjs --mode production vite v8.0.14 building client environment for production... transforming...✓ 294 modules transformed. rendering chunks... computing gzip size... dist/chunks/rolldown-runtime-B-pNeFgv.js 0.91 kB │ gzip: 0.47 kB dist/chunks/steamHost-BuRog5c8.js 0.96 kB │ gzip: 0.45 kB dist/chunks/customfilters-CeiM60HE.js 2.87 kB │ gzip: 1.06 kB dist/chunks/pluginApi-BswdxDmF.js 8.46 kB │ gzip: 2.33 kB dist/chunks/onlineStore-BIRGpWmE.js 11.59 kB │ gzip: 3.92 kB dist/chunks/zh-CN-lBMdrjgV.js 59.74 kB │ gzip: 21.38 kB dist/chunks/zh-TW-CmPsZ8lA.js 60.96 kB │ gzip: 21.51 kB dist/chunks/en-GB-CFzLVGFl.js 61.25 kB │ gzip: 19.18 kB dist/chunks/nl-NL-BVOAV8Vc.js 64.03 kB │ gzip: 20.68 kB dist/chunks/pl-PL-B9FVe1ck.js 64.36 kB │ gzip: 21.36 kB dist/chunks/it-IT-BwOFOb9t.js 65.00 kB │ gzip: 20.58 kB dist/chunks/tr-TR-D58aJvCi.js 65.52 kB │ gzip: 21.22 kB dist/chunks/de-DE-BiT0h-bz.js 65.67 kB │ gzip: 21.25 kB dist/chunks/es-419-BErkqhFc.js 65.93 kB │ gzip: 20.78 kB dist/chunks/ko-KR-D1I2ndzX.js 65.99 kB │ gzip: 21.40 kB dist/chunks/pt-BR-D2WvEsk1.js 66.04 kB │ gzip: 20.23 kB dist/chunks/pt-PT-IgHuzrF5.js 66.22 kB │ gzip: 20.45 kB dist/chunks/es-ES-UiRHFs_B.js 66.39 kB │ gzip: 20.72 kB dist/chunks/fr-CA-CqmeUwQl.js 67.00 kB │ gzip: 21.11 kB dist/chunks/fr-FR-BlY7_-Lr.js 67.61 kB │ gzip: 21.04 kB dist/chunks/ja-JP-DWWoK62h.js 70.99 kB │ gzip: 22.18 kB dist/chunks/uk-UA-EJtJjTT3.js 83.05 kB │ gzip: 23.47 kB dist/chunks/ru-RU-CweGqEJt.js 83.33 kB │ gzip: 23.78 kB dist/chunks/steam-ekxMWt5I.js 88.87 kB │ gzip: 22.01 kB dist/chunks/settingsStore-D85apjLo.js 131.50 kB │ gzip: 29.17 kB dist/index.js 864.20 kB │ gzip: 197.81 kB ✓ built in 153ms [package] Created installable archive: deck-shelves-v2.4.0.zip [verify] Found: plugin.json [verify] Found: package.json [verify] Found: main.py [verify] Found: dist/index.js [verify] Found: i18n/en-US.json [verify] main.py is executable [verify] plugin.json flags OK (no debug) [verify] package.json matches repo [verify] Package OK: /Users/santojon/Projects/Deck-Shelves/deck-shelves-v2.4.0.zip
Verify package148 msFAIL▶
⚠ Files with issues
index.js — /index.js
en-US.js — /en-US.json
package.js — /var/folders/h3/lcv_r50n5vn5m7c9wrmfglr00000gn/T/tmp.S4CtVmXV3c/deck-shelves/package.json 2026-05-29 17:12:27
report.py — scripts/ci/report.py --rebuild --root .",
build-decky.mjs — scripts/build/build-decky.mjs --mode development",
perf-test.sh — scripts/deck/perf-test.sh",
logs-decky.sh — scripts/deck/logs-decky.sh",
validate.mjs — scripts/build/validate.mjs",
validate-compat.mjs — scripts/build/validate-compat.mjs",
validate-compat.sh — scripts/build/validate-compat.sh",
cli.py — scripts/devtools/deck/cli.py screenshot",
validate-screenshots.mjs — scripts/build/validate-screenshots.mjs",
update.sh — scripts/devtools/update.sh all",
[verify] Found: plugin.json [verify] Found: package.json [verify] Found: main.py [verify] Found: dist/index.js [verify] Found: i18n/en-US.json [verify] main.py is executable [verify] plugin.json flags OK (no debug) [verify] package.json in ZIP differs from repo version --- package.json 2026-06-05 10:58:24 +++ /var/folders/h3/lcv_r50n5vn5m7c9wrmfglr00000gn/T/tmp.S4CtVmXV3c/deck-shelves/package.json 2026-05-29 17:12:27 @@ -1,6 +1,6 @@ { "name": "deck-shelves", - "version": "2.4.0", + "version": "2.3.2", "description": "Decky Loader plugin that injects configurable shelves into Steam Deck Home and provides a Steam Deck focused QAM editor.", "type": "module", "scripts": { @@ -12,11 +12,6 @@ "reports:rebuild": "python3 scripts/ci/report.py --rebuild --root .", "test": "vitest run", "typecheck": "tsc --noEmit", - "lint:complexity": "eslint --no-warn-ignored --pass-on-unpruned-suppressions 'src/**/*.{ts,tsx}'", - "lint:js": "eslint --no-warn-ignored --pass-on-unpruned-suppressions 'src/**/*.{ts,tsx}'", - "lint:js:prune": "eslint --no-warn-ignored --prune-suppressions 'src/**/*.{ts,tsx}'", - "lint:py": "python3 -m ruff check main.py scripts/", - "lint": "pnpm run lint:js && pnpm run lint:py", "build": "node scripts/build/build-decky.mjs --mode development", "build:plugin": "pnpm run build", "build:release": "node scripts/build/build-decky.mjs --mode production", @@ -61,8 +56,7 @@ "deck:perf": "bash scripts/deck/perf-test.sh", "logs:decky": "bash scripts/deck/logs-decky.sh", "check": "pnpm run typecheck && node scripts/build/validate.mjs", - "dev:check": "pnpm run typecheck && pnpm run lint && pnpm run test", - "validate:compat": "node scripts/build/validate-compat.mjs", + "validate:compat": "bash scripts/build/validate-compat.sh", "screenshots": "python3 scripts/devtools/deck/cli.py screenshot", "screenshots:validate": "node scripts/build/validate-screenshots.mjs", "devtools:cli": "python3 scripts/devtools/deck/cli.py", @@ -70,7 +64,7 @@ "devtools:diag": "python3 scripts/devtools/deck/cli.py diag list", "test:all": "pnpm run test && python3 -m pip install -U pip setuptools && python3 -m pip install pytest && python3 -m pytest src/test/ -v", "clean": "rm -rf build dist .deploy build/package *.zip", - "precommit": "pnpm run typecheck && pnpm run lint && pnpm run test:all && pnpm run build:release && pnpm run validate:compat && node scripts/build/validate-screenshots.mjs", + "precommit": "pnpm run typecheck && pnpm run test:all && pnpm run build:release && pnpm run validate:compat && node scripts/build/validate-screenshots.mjs 2>/dev/null || true", "deploy:verify": "pnpm run deploy:deck:hard && sleep 20 && pnpm run devtools:cli -- probe --mode smoke", "update": "bash scripts/devtools/update.sh all", "update:all": "YES=1 bash scripts/devtools/update.sh all", @@ -97,11 +91,8 @@ "@decky/ui": "^4.11.4", "@types/react": "19.2.15", "@types/react-dom": "19.2.3", - "@typescript-eslint/parser": "^8.60.1", "@vitejs/plugin-react": "^6.0.2", "esbuild": "^0.28.0", - "eslint": "^10.4.1", - "eslint-plugin-react-hooks": "^7.1.1", "jsdom": "29.1.1", "typescript": "^6.0.3", "vite": "^8.0.14", [verify] Package verification failed
Compat validation5.1sPASS▶
> deck-shelves@2.4.0 validate:compat /Users/santojon/Projects/Deck-Shelves > node scripts/build/validate-compat.mjs ╔══════════════════════════════════════════════╗ ║ Deck Shelves — Compatibility Checks ║ ╚══════════════════════════════════════════════╝ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Build Output (Vite/ESM) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ dist/index.js exists ✅ dist/index.js is non-empty (864202 bytes) ✅ dist/index.js size under 2.5MB ✅ dist/index.js has ESM exports ✅ No node_modules imports in bundle Result: 5 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TypeScript / Node (Build Toolchain) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ tsconfig.json exists ✅ package.json exists ✅ pnpm-lock.yaml exists (lockfile) ✅ Node.js v26.0.0 ✅ pnpm 10.33.0 ✅ node_modules installed ✅ Vite config exists Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Decky Loader 3.x (API v1) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ api_version == 1 (Decky 3.x compatible) ✅ Uses @decky/api package ✅ Uses @decky/ui package ✅ Plugin._main lifecycle method ✅ Plugin._unload lifecycle method ✅ Uses 'import decky' (v3 style) ✅ No legacy decky_plugin imports Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Decky Loader (API v1) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ plugin.json api_version == 1 ✅ plugin.json has name ✅ plugin.json has author ✅ main.py exists ✅ main.py has Plugin class ✅ decky-api shim exists ✅ decky-ui shim exists Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Decky Store (Publishing) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ plugin.json has publish tags ✅ plugin.json has publish description ✅ LICENSE file exists ✅ README.md exists ✅ assets/ directory exists ✅ package.json has version Result: 6 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Decky Store Submission (Review Checklist) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ plugin.json is valid JSON ✅ package.json name and version conform to npm standard ✅ pnpm-lock.yaml lockfileVersion: 9.0 ✅ LICENSE file present ✅ No unused backend/ directory ✅ No unused defaults/ directory ✅ No remote code execution patterns in source ✅ Built output is not heavily obfuscated (25397 lines) ✅ No private/local dependencies ✅ assets/icon.png not required (store uses publish.image) ✅ No debug flag in plugin.json Result: 11 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CheatDeck (Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ References CheatDeck without overwriting (203 files) ✅ No high z-index values that would cover CheatDeck overlay (portal-scoped badge excluded) ✅ DOM mount uses unique 'deck-shelves-' prefixed ID ✅ No global-level input event listeners ✅ Apps API uses safe access patterns ✅ MutationObservers are scoped (not on document.body) Result: 6 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader (ArtHero Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ cssLoaderDetect helper present ✅ Detection helper exports isCssLoaderActive + isArtHeroActive ✅ HeroBackground render gated by replaceInjecting (no duplicate hero) ✅ First ds-shelf promoted to recents slot when CSS Loader active ✅ Class promotion is additive (does not strip ds-*) ✅ Native recents class read from runtime DOM (no hardcoded token) ✅ Detection probes <style class="css-loader-style"> tags ✅ ArtHero detected by structural signature (heroInner + mask-image) ✅ Invariant 1: promotion requires hideRecentsSetting ✅ Invariant 2: promotion targets only the first visible shelf ✅ Invariant 3: promotion requires CSS Loader active ✅ HeroBackground only renders when hideRecents is true Result: 12 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Center Home) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No unsafe 'center home' coupling (CSS custom-property detection is allowed) Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Clean Game View (CSS Loader Theme) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Card dimensions defined as explicit constants ✅ Card backgrounds are explicitly set or use the --ds-shell-bg variable ✅ No reliance on native Steam card hover/focus classes ✅ Focus indicator uses scoped .ds-card classes ✅ Border-radius uses --ds-card-radius custom property with fallback ✅ Card shadow defined on own .ds-card-art class ✅ Image sizing uses explicit object-fit Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader (Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Injected styles are in files with scoped selectors ✅ Style elements use unique 'deck-shelves-' prefixed IDs ✅ Style injection checks for existing element (no duplicates) ✅ All !important declarations are within files using scoped selectors ✅ All className values are namespaced or from Decky UI ✅ No direct document.styleSheets manipulation ✅ Root mount element has unique deck-shelves-* ID Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Colored Compatibility Icons) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No colored compatibility-icon references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Delly Footer) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'Delly Footer' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Delly Volume) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'Delly Volume' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Focus Highlight Color) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ isFocusRoundCompatActive() detection present ✅ Detection uses unique keyframe signature (appportrait_blinker + flangrande) ✅ Round Compat flag set on .deck-shelves-root / <html> ✅ Round Compat suppression rule present in shelfStyles ✅ Theme variables read-only (no flangrande writes) Result: 5 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Fullscreen Menus) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'Fullscreen Menus' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Game Cover Shine Animation Color) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Native card class promoted onto .ds-card (shine reaches DS cards) ✅ ::after opacity left to the theme (no forced opacity 1) ✅ Shine ::after suppressed under Round Compat flag ✅ Theme variable read-only Result: 4 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Main Menu Hide Tabs) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'main menu hide tabs' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Obsidian Theme (CSS Loader Theme) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Custom styles scoped under #deck-shelves-home-root ✅ Font sizes inside scoped selectors or using relative units ✅ Explicit color values (13) — not dependent on theme variables ✅ Explicit background colors in components ✅ No reliance on generic Steam panel class styling ✅ z-index values are reasonable (≤ 100; portal-scoped badge excluded) ✅ Modal styles scoped under .deck-shelves-modal-scope Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Outrun) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'outrun' references in code (comments OK) Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (QAM Hide Tabs) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'QAM hide tabs' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (QAM Select Bar Icon Hider) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'QAM selectbar icon hider' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Round (CSS Loader Theme) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Runtime border-radius detection from native Steam cards ✅ --ds-card-radius CSS variable allows theme override ✅ Card art border-radius reads from CSS variable ✅ Card containers use overflow:hidden (content clipped to border-radius) ✅ No hardcoded borderRadius: 0 overriding theme ✅ Radius detection uses 129 selector references for broad theme support ✅ Detected radius is cached (no repeated DOM queries) Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Switch-Like Banners) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'switch-like banners' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Switch-Like Home) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'switch-like home' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ CSS Loader Theme (Top Bar Transparency) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No 'top bar transparency' references found Result: 1 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ HLTB (Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No HLTB namespace collision ✅ AppOverview playtime fields read-only ✅ No app detail page modifications ✅ Shelf DOM elements use unique 'deck-shelves-' prefix ✅ AppOverview access patterns reviewed ✅ Playtime field access is guarded ✅ No ServerAPI fetch calls (no API contention with HLTB) Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Non-Steam Badges (Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ NonSteamBadge(s) global uses optional chaining ✅ No hard dependency on nonsteam module outside integrations/ ✅ No NonSteamBadges namespace collision ✅ Shortcuts/shortcutsStore access is guarded by try/catch ✅ Dynamic probing includes shortcuts/shortcutsStore Result: 5 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SteamGridDB (Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No SteamGridDB namespace collision ✅ Image fallback includes /customimages/ path (SteamGridDB writes here) ✅ Multiple image candidates per app (resilient to art replacements) ✅ Reads library_capsule from AppOverview (picks up SteamGridDB changes) ✅ Steam CDN URLs used only as final fallback (SteamGridDB custom art checked first) ✅ AppOverview art fields not mutated ✅ Image loading has error fallback Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TabMaster (Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ TabMasterStore uses optional chaining ✅ TabMaster global uses optional chaining ✅ TabMaster access in files with try/catch guards ✅ No hard dependency on TabMaster outside integrations/ ✅ Dynamic tab store probing includes TabMasterStore ✅ No TabMaster namespace collision ✅ Collection fallback aware of TabMaster Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ UnifiDeck (Coexistence) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ UnifiDeckStore uses optional chaining ✅ UnifiDeck global uses optional chaining ✅ UnifiDeck access in files with try/catch guards ✅ No hard dependency on UnifiDeck ✅ Handles both UnifiDeck and UnifyDeck spellings ✅ No UnifiDeck namespace collision ✅ Dynamic collection store probing includes UnifiDeck Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Internationalization (i18n) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ i18n/ directory exists ✅ en-US.json base locale exists ✅ All locale files are valid JSON ✅ Base locale has 776 keys ✅ All locales have consistent keys Result: 5 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Python Backend (Decky Python) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ main.py syntax valid ✅ Plugin class defined ✅ _main lifecycle method found ✅ _unload lifecycle method found ✅ No dangerous module imports Result: 5 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SteamOS 3.5 (Stable) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Build target compatible with SteamOS 3.5 CEF ✅ No top-level await in bundle ✅ No Python 3.10+ match/case syntax ✅ main.py parses as valid Python Result: 4 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SteamOS 3.6 (Stable) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ React shim uses GamepadUI shared React ✅ ESM output format ✅ No direct window.location manipulation ✅ SP_REACTDOM used as shim fallback (backward compat) Result: 4 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SteamOS 3.7 (Stable) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Platform abstraction layer exists ✅ Error boundary pattern found ✅ No hardcoded obfuscated CSS class selectors in components ✅ Home route detection present Result: 4 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SteamOS 3.8 (Preview/Beta) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Modern ES target ✅ Chunk splitting configured ✅ Uses @decky/api (v3 API) ✅ No legacy ServerAPI imports ✅ Diagnostics module for cross-version debugging ✅ Settings use DECKY_PLUGIN_SETTINGS_DIR ✅ No system path access from backend Result: 7 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SteamOS 3.9 (Stable) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ Modern ES target (ES2020+) ✅ Uses @decky/api (v3 API) ✅ No legacy ServerAPI imports ✅ Duck-typing / optional chaining used for API detection ✅ FocusNavController/GamepadUI pattern referenced ✅ vgp_* event patterns used ✅ Decky patcher utilities used (afterPatch/findInReactTree) ✅ Settings use DECKY_PLUGIN_SETTINGS_DIR ✅ Python 3.10+ match/case syntax available ✅ No hardcoded SteamOS version comparisons ✅ No system path access from backend Result: 11 passed, 0 failed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SteamOS GamepadUI (3.5–3.9) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ shims/ directory exists ✅ shim: react.ts ✅ shim: react-dom.ts ✅ shim: react-dom-client.ts ✅ shim: react-jsx-runtime.ts ✅ Vite config isolates React (shims or externals) ✅ Vite config targets ES module format ✅ No direct DOM manipulation in components ✅ Platform abstraction layer exists ✅ Diagnostics module exists Result: 10 passed, 0 failed ╔══════════════════════════════════════════════╗ ║ Summary ║ ╚══════════════════════════════════════════════╝ ✅ Build Output (Vite/ESM) ✅ TypeScript / Node (Build Toolchain) ✅ Decky Loader 3.x (API v1) ✅ Decky Loader (API v1) ✅ Decky Store (Publishing) ✅ Decky Store Submission (Review Checklist) ✅ CheatDeck (Coexistence) ✅ CSS Loader (ArtHero Coexistence) ✅ CSS Loader Theme (Center Home) ✅ Clean Game View (CSS Loader Theme) ✅ CSS Loader (Coexistence) ✅ CSS Loader Theme (Colored Compatibility Icons) ✅ CSS Loader Theme (Delly Footer) ✅ CSS Loader Theme (Delly Volume) ✅ CSS Loader Theme (Focus Highlight Color) ✅ CSS Loader Theme (Fullscreen Menus) ✅ CSS Loader Theme (Game Cover Shine Animation Color) ✅ CSS Loader Theme (Main Menu Hide Tabs) ✅ Obsidian Theme (CSS Loader Theme) ✅ CSS Loader Theme (Outrun) ✅ CSS Loader Theme (QAM Hide Tabs) ✅ CSS Loader Theme (QAM Select Bar Icon Hider) ✅ Round (CSS Loader Theme) ✅ CSS Loader Theme (Switch-Like Banners) ✅ CSS Loader Theme (Switch-Like Home) ✅ CSS Loader Theme (Top Bar Transparency) ✅ HLTB (Coexistence) ✅ Non-Steam Badges (Coexistence) ✅ SteamGridDB (Coexistence) ✅ TabMaster (Coexistence) ✅ UnifiDeck (Coexistence) ✅ Internationalization (i18n) ✅ Python Backend (Decky Python) ✅ SteamOS 3.5 (Stable) ✅ SteamOS 3.6 (Stable) ✅ SteamOS 3.7 (Stable) ✅ SteamOS 3.8 (Preview/Beta) ✅ SteamOS 3.9 (Stable) ✅ SteamOS GamepadUI (3.5–3.9) 🎉 All 39 compatibility checks passed!