CI / Automatedv2.4.0

June 05, 2026 at 11:10:49  ·  6 steps
FAIL
5
Passed
1
Failed
0
Skipped
6
Total
10.2s
Duration

Step durations

TypeScript typecheck
2.2s
Build (production)
577 ms
Unit tests (vitest)
1.2s
Package (.zip)
931 ms
Verify package
148 ms
Compat validation
5.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
✓ 23 passed
> 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
✓ 5 passed
> 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!