6
Passed
0
Failed
0
Skipped
6
Total
27.9s
Duration
Step durations
TypeScript typecheck10.4s
Build (production)1.6s
Unit tests (vitest)7.8s
Package (.zip)1.9s
Verify package66 ms
Compat validation6.0s
TypeScript typecheck10.4sPASS▶
api | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. api | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. host | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. host | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. > deck-shelves@3.2.1 typecheck /home/runner/work/Deck-Shelves/Deck-Shelves > tsc --noEmit
Build (production)1.6sPASS▶
api | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. api | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. host | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. host | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. > deck-shelves@3.2.1 build:release /home/runner/work/Deck-Shelves/Deck-Shelves > node scripts/build/build-decky.mjs --mode production vite v8.1.5 building client environment for production... transforming...✓ 503 modules transformed. rendering chunks... computing gzip size... dist/chunks/rolldown-runtime-BrULcNsR.js 1.00 kB │ gzip: 0.51 kB dist/chunks/steamHost-CN1-fhon.js 1.01 kB │ gzip: 0.47 kB dist/chunks/home-CoGR96rA.js 1.41 kB │ gzip: 0.86 kB dist/chunks/home--kA8IRQT.js 1.42 kB │ gzip: 0.87 kB dist/chunks/home-B00duZcY.js 1.43 kB │ gzip: 0.72 kB dist/chunks/home-CNCeQCQA.js 1.48 kB │ gzip: 0.80 kB dist/chunks/home-DXL0wPZl.js 1.48 kB │ gzip: 0.78 kB dist/chunks/home-DOo2y2NX.js 1.48 kB │ gzip: 0.81 kB dist/chunks/home-B7LdJmfU.js 1.49 kB │ gzip: 0.80 kB dist/chunks/home-CHxkrvRY.js 1.49 kB │ gzip: 0.78 kB dist/chunks/home-D541xmAe.js 1.49 kB │ gzip: 0.78 kB dist/chunks/home-CRbUDANM.js 1.50 kB │ gzip: 0.83 kB dist/chunks/home-CY5_N85D.js 1.50 kB │ gzip: 0.79 kB dist/chunks/home-BTpUkCSb.js 1.51 kB │ gzip: 0.78 kB dist/chunks/home-B9ZQQY0B.js 1.52 kB │ gzip: 0.90 kB dist/chunks/home-BPpRI2-u.js 1.53 kB │ gzip: 0.80 kB dist/chunks/home-BpyzDfh9.js 1.53 kB │ gzip: 0.80 kB dist/chunks/home-DcQ3KEDo.js 1.63 kB │ gzip: 0.94 kB dist/chunks/home-CT-Hs2yC.js 1.78 kB │ gzip: 0.95 kB dist/chunks/home-DoKv1jgA.js 1.81 kB │ gzip: 0.95 kB dist/chunks/customfilters-Fg9Z7KDQ.js 3.36 kB │ gzip: 1.20 kB dist/chunks/defaults-u_dcuplS.js 3.39 kB │ gzip: 1.21 kB dist/chunks/qam-1HPV--FN.js 3.88 kB │ gzip: 1.92 kB dist/chunks/qam-CJ00NCGT.js 3.98 kB │ gzip: 1.96 kB dist/chunks/qam-D0YvlHCU.js 3.99 kB │ gzip: 1.62 kB dist/chunks/qam-DKwfIZmu.js 4.21 kB │ gzip: 1.76 kB dist/chunks/qam-C-OJ9ttD.js 4.24 kB │ gzip: 1.83 kB dist/chunks/qam-CMOTAVjA.js 4.27 kB │ gzip: 1.75 kB dist/chunks/qam-Bjz4sG4C.js 4.28 kB │ gzip: 1.78 kB dist/chunks/qam-B4UUWcbg.js 4.29 kB │ gzip: 1.78 kB dist/chunks/qam-CIzGA5nf.js 4.32 kB │ gzip: 1.80 kB dist/chunks/qam-Cs19n02e.js 4.32 kB │ gzip: 1.88 kB dist/chunks/qam-B8hIOfvd.js 4.32 kB │ gzip: 1.79 kB dist/chunks/qam-DYkpEqGr.js 4.39 kB │ gzip: 1.98 kB dist/chunks/qam-cm3RpfbD.js 4.39 kB │ gzip: 1.82 kB dist/chunks/qam-CfPXq91F.js 4.43 kB │ gzip: 1.85 kB dist/chunks/qam-BtO6wAUm.js 4.44 kB │ gzip: 1.84 kB dist/chunks/common-B_8TLJ5l.js 4.75 kB │ gzip: 2.39 kB dist/chunks/common-DzGAuzTa.js 4.79 kB │ gzip: 2.42 kB dist/chunks/qam-DjOe_6Ge.js 4.80 kB │ gzip: 2.05 kB dist/chunks/common-B2lDbKNM.js 4.82 kB │ gzip: 2.06 kB dist/chunks/common-VYHKNc2Y.js 5.00 kB │ gzip: 2.19 kB dist/chunks/common-BAixOYiE.js 5.02 kB │ gzip: 2.29 kB dist/chunks/common-D4q6-oO7.js 5.08 kB │ gzip: 2.35 kB dist/chunks/common-zQWsmfSV.js 5.11 kB │ gzip: 2.21 kB dist/chunks/common-ThCdmn_n.js 5.13 kB │ gzip: 2.28 kB dist/chunks/common-B8yV35bt.js 5.18 kB │ gzip: 2.25 kB dist/chunks/common-DRJ7Y16F.js 5.18 kB │ gzip: 2.25 kB dist/chunks/common-Cqg2Pv-p.js 5.21 kB │ gzip: 2.47 kB dist/chunks/common-B_SdqihE.js 5.22 kB │ gzip: 2.26 kB dist/chunks/common-C9T43Gj4.js 5.24 kB │ gzip: 2.28 kB dist/chunks/common-3_wUgc3f.js 5.25 kB │ gzip: 2.29 kB dist/chunks/common-BBmETqjR.js 5.26 kB │ gzip: 2.28 kB dist/chunks/integrations-3eb92juQ.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-6-6GKPcy.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-B5tfkfk3.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-BBFOajZJ.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-BX_X0Tkx.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-BcNlPPqC.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-Bx9rl-Oa.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-CWbDj0Ll.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-ChokzVH9.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-D-VBEleW.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-DI0dwpq8.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-DO45bjjT.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-DOvEn7wc.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-qm5CHWsr.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-u4ty62sP.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-x56LcmII.js 5.29 kB │ gzip: 1.93 kB dist/chunks/qam-C0emnjHj.js 5.48 kB │ gzip: 2.14 kB dist/chunks/integrations--PaAVRgi.js 5.56 kB │ gzip: 2.11 kB dist/chunks/integrations-D9vEcspi.js 5.56 kB │ gzip: 2.11 kB dist/chunks/qam-BfaUcs0l.js 5.58 kB │ gzip: 2.16 kB dist/chunks/common-DYiJxBpH.js 5.60 kB │ gzip: 2.59 kB dist/chunks/common-DMBucQiW.js 6.34 kB │ gzip: 2.66 kB dist/chunks/common-MSyIYOQO.js 6.44 kB │ gzip: 2.68 kB dist/chunks/decky-aoKoe0NY.js 8.77 kB │ gzip: 3.25 kB dist/chunks/about-BbKGidi5.js 10.18 kB │ gzip: 5.25 kB dist/chunks/about-CF3MGAns.js 10.44 kB │ gzip: 5.34 kB dist/chunks/about-CkKd-7W5.js 10.47 kB │ gzip: 4.46 kB dist/chunks/about-DOsl4wqt.js 10.77 kB │ gzip: 4.75 kB dist/chunks/about-DUjB8r6P.js 11.04 kB │ gzip: 5.06 kB dist/chunks/about-DV5V7Xfy.js 11.08 kB │ gzip: 4.92 kB dist/chunks/about-yf-d9y87.js 11.10 kB │ gzip: 5.26 kB dist/chunks/about-BL3LmGvQ.js 11.12 kB │ gzip: 4.77 kB dist/chunks/about-fOHgAFUZ.js 11.22 kB │ gzip: 4.97 kB dist/chunks/about-B0wrk_XS.js 11.29 kB │ gzip: 4.87 kB dist/chunks/about-Cq-47fET.js 11.33 kB │ gzip: 4.89 kB dist/chunks/about-D1FaUckz.js 11.45 kB │ gzip: 4.85 kB dist/chunks/about-Bcev3ONf.js 11.52 kB │ gzip: 4.87 kB dist/chunks/about-BZoelT-O.js 11.53 kB │ gzip: 4.96 kB dist/chunks/about-2YlkBqra.js 11.53 kB │ gzip: 4.97 kB dist/chunks/about-CmS57MG9.js 12.27 kB │ gzip: 5.52 kB dist/chunks/about-7J7KCH4b.js 14.39 kB │ gzip: 5.75 kB dist/chunks/about-B-rQNaQ7.js 14.52 kB │ gzip: 5.79 kB dist/chunks/onlineStore-D7lfRjxF.js 14.94 kB │ gzip: 4.97 kB dist/chunks/settings-Dj0x7a3a.js 90.18 kB │ gzip: 31.32 kB dist/chunks/settings-C4aDYkEg.js 90.96 kB │ gzip: 31.41 kB dist/chunks/settings-BznGrZuj.js 91.72 kB │ gzip: 28.76 kB dist/chunks/settings-DDizsA4J.js 95.21 kB │ gzip: 30.51 kB dist/chunks/settings-BRBnm_Ym.js 95.35 kB │ gzip: 31.28 kB dist/chunks/settings-CVC5rkjp.js 96.24 kB │ gzip: 30.25 kB dist/chunks/settings-BkBtZC4J.js 96.54 kB │ gzip: 31.07 kB dist/chunks/settings-CieI-1Mb.js 96.69 kB │ gzip: 31.29 kB dist/chunks/settings-B66KzPCm.js 96.76 kB │ gzip: 31.00 kB dist/chunks/settings-9SQRYdZB.js 97.43 kB │ gzip: 30.63 kB dist/chunks/settings-SLvEuswu.js 97.73 kB │ gzip: 29.84 kB dist/chunks/settings-ZbjRhvJu.js 97.88 kB │ gzip: 30.56 kB dist/chunks/settings-DcvqxYeU.js 98.00 kB │ gzip: 30.12 kB dist/chunks/settings-zM5sKfmv.js 98.45 kB │ gzip: 30.99 kB dist/chunks/settings-CtNelsxL.js 99.07 kB │ gzip: 30.96 kB dist/chunks/settings-CkJNPkVe.js 102.58 kB │ gzip: 32.27 kB dist/chunks/settings-Cs2L7bt6.js 116.04 kB │ gzip: 33.66 kB dist/chunks/settings-x4cA6zOI.js 116.16 kB │ gzip: 34.00 kB dist/chunks/settingsStore-CvYyWlFq.js 135.74 kB │ gzip: 29.20 kB dist/chunks/steam-gKdfv4mr.js 378.89 kB │ gzip: 103.59 kB dist/index.js 1,223.65 kB │ gzip: 268.08 kB ✓ built in 938ms [INEFFECTIVE_DYNAMIC_IMPORT] src/steam/index.ts is dynamically imported by src/core/shelfRefresh.ts but also statically imported by src/components/Shelf.tsx, src/components/ShelfManageRoute.tsx, src/components/filter/DeveloperFilterOptions.tsx, src/components/filter/PublisherFilterOptions.tsx, src/components/qam/list/ShelfActions.tsx, ..., dynamic import will not move module into another chunk.
Unit tests (vitest)7.8sPASS▶
api | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. api | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. host | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. host | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. > deck-shelves@3.2.1 test /home/runner/work/Deck-Shelves/Deck-Shelves > NODE_NO_WARNINGS=1 vitest run RUN v4.1.10 /home/runner/work/Deck-Shelves/Deck-Shelves ✓ src/test/domain/settings.test.ts (43 tests) 31ms ✓ src/test/steam/smartShelves.test.ts (51 tests) 42ms ✓ src/test/steam/smartShelvesRuntime.test.ts (19 tests) 23ms ✓ src/test/steam/evaluateFilterGroup.test.ts (45 tests) 24ms ✓ src/test/components/saveHelpers.test.ts (32 tests) 14ms ✓ src/test/domain/statistics.test.ts (24 tests) 24ms ✓ src/test/runtime/buttonBindings.test.ts (30 tests) 20ms ✓ src/test/domain/customfilters.test.ts (17 tests) 23ms ✓ src/test/regression.test.ts (41 tests) 69ms ✓ src/test/runtime/deviceState.test.ts (12 tests) 22ms ✓ src/test/features/settings/controller/profiles.test.ts (13 tests) 13ms ✓ src/test/domain/shelfStats.test.ts (17 tests) 15ms ✓ src/test/domain/shelfOrder.test.ts (20 tests) 13ms ✓ src/test/steam/applySortToIds.test.ts (13 tests) 25ms ✓ src/test/steam.test.ts (8 tests) 8ms ✓ src/test/steam/resolveQuickLaunchAction.test.ts (15 tests) 11ms ✓ src/test/steam/smartTemplatesCoverage.test.ts (58 tests) 30ms ✓ src/test/domain/syntheticCards.test.ts (11 tests) 23ms ✓ src/test/domain/snapshot.test.ts (5 tests) 7ms ✓ src/test/core/issueReport.test.ts (5 tests) 15ms ✓ src/test/components/notify.test.ts (9 tests) 19ms ✓ src/test/runtime/profileTriggers.test.ts (6 tests) 13ms ✓ src/test/domain/templates.test.ts (13 tests) 14ms ✓ src/test/steam/compositeFilters.test.ts (9 tests) 11ms ✓ src/test/core/exportImportHandlers.test.ts (3 tests) 14ms ✓ src/test/core/onlineMetadata.test.ts (4 tests) 11ms ✓ src/test/steam/mergeCompositeResults.test.ts (15 tests) 12ms ✓ src/test/domain/timeContext.test.ts (8 tests) 12ms ✓ src/test/components/trailingCards.test.ts (13 tests) 11ms ✓ src/test/steam/heuristics.test.ts (9 tests) 12ms ✓ src/test/steam/v3BatchExposure.test.ts (51 tests) 43ms ✓ src/test/components/gameInfoCoupling.test.ts (6 tests) 8ms ✓ src/test/domain/usageStats.test.ts (7 tests) 10ms ✓ src/test/qa/qam-visibility.test.ts (10 tests) 30ms ✓ src/test/runtime/sessionState.test.ts (5 tests) 11ms ✓ src/test/core/webpackCompat.test.ts (7 tests) 200ms ✓ src/test/runtime/diagnosticsInfo.test.ts (6 tests) 23ms ✓ src/test/domain/schemas.test.ts (8 tests) 29ms ✓ src/test/core/reorder.test.ts (14 tests) 14ms ✓ src/test/steam/normalizeTitleForMatch.test.ts (10 tests) 7ms ✓ src/test/runtime/logger.test.ts (3 tests) 12ms ✓ src/test/runtime/cacheRegistry.test.ts (5 tests) 10ms ✓ src/test/runtime/perfState.test.ts (4 tests) 11ms ✓ src/test/core/pluginApiCatalog.test.ts (4 tests) 12ms ✓ src/test/steam/familySharingFilter.test.ts (4 tests) 8ms ✓ src/test/runtime/debugOverlay.test.ts (6 tests) 7ms ✓ src/test/runtime/ownerGuard.test.ts (4 tests) 7ms ✓ src/test/steam/applyManualOrder.test.ts (9 tests) 7ms ✓ src/test/runtime/peripheralsState.test.ts (1 test) 6ms ✓ src/test/components/labelOverhang.test.ts (5 tests) 7ms ✓ src/test/store/schemaVersion.test.ts (4 tests) 8ms ✓ src/test/components/refreshableSmartModes.test.ts (3 tests) 8ms ✓ src/test/compareAdded.test.ts (3 tests) 6ms ✓ src/test/scrollUtils.test.ts (2 tests) 3ms Test Files 54 passed (54) Tests 749 passed (749) Start at 07:43:09 Duration 7.08s (transform 2.41s, setup 0ms, import 8.53s, tests 1.07s, environment 978ms)
Package (.zip)1.9sPASS▶
api | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. api | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. host | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. host | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. > deck-shelves@3.2.1 build:release /home/runner/work/Deck-Shelves/Deck-Shelves > node scripts/build/build-decky.mjs --mode production vite v8.1.5 building client environment for production... transforming...✓ 503 modules transformed. rendering chunks... computing gzip size... dist/chunks/rolldown-runtime-BrULcNsR.js 1.00 kB │ gzip: 0.51 kB dist/chunks/steamHost-CN1-fhon.js 1.01 kB │ gzip: 0.47 kB dist/chunks/home-CoGR96rA.js 1.41 kB │ gzip: 0.86 kB dist/chunks/home--kA8IRQT.js 1.42 kB │ gzip: 0.87 kB dist/chunks/home-B00duZcY.js 1.43 kB │ gzip: 0.72 kB dist/chunks/home-CNCeQCQA.js 1.48 kB │ gzip: 0.80 kB dist/chunks/home-DXL0wPZl.js 1.48 kB │ gzip: 0.78 kB dist/chunks/home-DOo2y2NX.js 1.48 kB │ gzip: 0.81 kB dist/chunks/home-B7LdJmfU.js 1.49 kB │ gzip: 0.80 kB dist/chunks/home-CHxkrvRY.js 1.49 kB │ gzip: 0.78 kB dist/chunks/home-D541xmAe.js 1.49 kB │ gzip: 0.78 kB dist/chunks/home-CRbUDANM.js 1.50 kB │ gzip: 0.83 kB dist/chunks/home-CY5_N85D.js 1.50 kB │ gzip: 0.79 kB dist/chunks/home-BTpUkCSb.js 1.51 kB │ gzip: 0.78 kB dist/chunks/home-B9ZQQY0B.js 1.52 kB │ gzip: 0.90 kB dist/chunks/home-BPpRI2-u.js 1.53 kB │ gzip: 0.80 kB dist/chunks/home-BpyzDfh9.js 1.53 kB │ gzip: 0.80 kB dist/chunks/home-DcQ3KEDo.js 1.63 kB │ gzip: 0.94 kB dist/chunks/home-CT-Hs2yC.js 1.78 kB │ gzip: 0.95 kB dist/chunks/home-DoKv1jgA.js 1.81 kB │ gzip: 0.95 kB dist/chunks/customfilters-Fg9Z7KDQ.js 3.36 kB │ gzip: 1.20 kB dist/chunks/defaults-u_dcuplS.js 3.39 kB │ gzip: 1.21 kB dist/chunks/qam-1HPV--FN.js 3.88 kB │ gzip: 1.92 kB dist/chunks/qam-CJ00NCGT.js 3.98 kB │ gzip: 1.96 kB dist/chunks/qam-D0YvlHCU.js 3.99 kB │ gzip: 1.62 kB dist/chunks/qam-DKwfIZmu.js 4.21 kB │ gzip: 1.76 kB dist/chunks/qam-C-OJ9ttD.js 4.24 kB │ gzip: 1.83 kB dist/chunks/qam-CMOTAVjA.js 4.27 kB │ gzip: 1.75 kB dist/chunks/qam-Bjz4sG4C.js 4.28 kB │ gzip: 1.78 kB dist/chunks/qam-B4UUWcbg.js 4.29 kB │ gzip: 1.78 kB dist/chunks/qam-CIzGA5nf.js 4.32 kB │ gzip: 1.80 kB dist/chunks/qam-Cs19n02e.js 4.32 kB │ gzip: 1.88 kB dist/chunks/qam-B8hIOfvd.js 4.32 kB │ gzip: 1.79 kB dist/chunks/qam-DYkpEqGr.js 4.39 kB │ gzip: 1.98 kB dist/chunks/qam-cm3RpfbD.js 4.39 kB │ gzip: 1.82 kB dist/chunks/qam-CfPXq91F.js 4.43 kB │ gzip: 1.85 kB dist/chunks/qam-BtO6wAUm.js 4.44 kB │ gzip: 1.84 kB dist/chunks/common-B_8TLJ5l.js 4.75 kB │ gzip: 2.39 kB dist/chunks/common-DzGAuzTa.js 4.79 kB │ gzip: 2.42 kB dist/chunks/qam-DjOe_6Ge.js 4.80 kB │ gzip: 2.05 kB dist/chunks/common-B2lDbKNM.js 4.82 kB │ gzip: 2.06 kB dist/chunks/common-VYHKNc2Y.js 5.00 kB │ gzip: 2.19 kB dist/chunks/common-BAixOYiE.js 5.02 kB │ gzip: 2.29 kB dist/chunks/common-D4q6-oO7.js 5.08 kB │ gzip: 2.35 kB dist/chunks/common-zQWsmfSV.js 5.11 kB │ gzip: 2.21 kB dist/chunks/common-ThCdmn_n.js 5.13 kB │ gzip: 2.28 kB dist/chunks/common-B8yV35bt.js 5.18 kB │ gzip: 2.25 kB dist/chunks/common-DRJ7Y16F.js 5.18 kB │ gzip: 2.25 kB dist/chunks/common-Cqg2Pv-p.js 5.21 kB │ gzip: 2.47 kB dist/chunks/common-B_SdqihE.js 5.22 kB │ gzip: 2.26 kB dist/chunks/common-C9T43Gj4.js 5.24 kB │ gzip: 2.28 kB dist/chunks/common-3_wUgc3f.js 5.25 kB │ gzip: 2.29 kB dist/chunks/common-BBmETqjR.js 5.26 kB │ gzip: 2.28 kB dist/chunks/integrations-3eb92juQ.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-6-6GKPcy.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-B5tfkfk3.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-BBFOajZJ.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-BX_X0Tkx.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-BcNlPPqC.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-Bx9rl-Oa.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-CWbDj0Ll.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-ChokzVH9.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-D-VBEleW.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-DI0dwpq8.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-DO45bjjT.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-DOvEn7wc.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-qm5CHWsr.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-u4ty62sP.js 5.29 kB │ gzip: 1.93 kB dist/chunks/integrations-x56LcmII.js 5.29 kB │ gzip: 1.93 kB dist/chunks/qam-C0emnjHj.js 5.48 kB │ gzip: 2.14 kB dist/chunks/integrations--PaAVRgi.js 5.56 kB │ gzip: 2.11 kB dist/chunks/integrations-D9vEcspi.js 5.56 kB │ gzip: 2.11 kB dist/chunks/qam-BfaUcs0l.js 5.58 kB │ gzip: 2.16 kB dist/chunks/common-DYiJxBpH.js 5.60 kB │ gzip: 2.59 kB dist/chunks/common-DMBucQiW.js 6.34 kB │ gzip: 2.66 kB dist/chunks/common-MSyIYOQO.js 6.44 kB │ gzip: 2.68 kB dist/chunks/decky-aoKoe0NY.js 8.77 kB │ gzip: 3.25 kB dist/chunks/about-BbKGidi5.js 10.18 kB │ gzip: 5.25 kB dist/chunks/about-CF3MGAns.js 10.44 kB │ gzip: 5.34 kB dist/chunks/about-CkKd-7W5.js 10.47 kB │ gzip: 4.46 kB dist/chunks/about-DOsl4wqt.js 10.77 kB │ gzip: 4.75 kB dist/chunks/about-DUjB8r6P.js 11.04 kB │ gzip: 5.06 kB dist/chunks/about-DV5V7Xfy.js 11.08 kB │ gzip: 4.92 kB dist/chunks/about-yf-d9y87.js 11.10 kB │ gzip: 5.26 kB dist/chunks/about-BL3LmGvQ.js 11.12 kB │ gzip: 4.77 kB dist/chunks/about-fOHgAFUZ.js 11.22 kB │ gzip: 4.97 kB dist/chunks/about-B0wrk_XS.js 11.29 kB │ gzip: 4.87 kB dist/chunks/about-Cq-47fET.js 11.33 kB │ gzip: 4.89 kB dist/chunks/about-D1FaUckz.js 11.45 kB │ gzip: 4.85 kB dist/chunks/about-Bcev3ONf.js 11.52 kB │ gzip: 4.87 kB dist/chunks/about-BZoelT-O.js 11.53 kB │ gzip: 4.96 kB dist/chunks/about-2YlkBqra.js 11.53 kB │ gzip: 4.97 kB dist/chunks/about-CmS57MG9.js 12.27 kB │ gzip: 5.52 kB dist/chunks/about-7J7KCH4b.js 14.39 kB │ gzip: 5.75 kB dist/chunks/about-B-rQNaQ7.js 14.52 kB │ gzip: 5.79 kB dist/chunks/onlineStore-D7lfRjxF.js 14.94 kB │ gzip: 4.97 kB dist/chunks/settings-Dj0x7a3a.js 90.18 kB │ gzip: 31.32 kB dist/chunks/settings-C4aDYkEg.js 90.96 kB │ gzip: 31.41 kB dist/chunks/settings-BznGrZuj.js 91.72 kB │ gzip: 28.76 kB dist/chunks/settings-DDizsA4J.js 95.21 kB │ gzip: 30.51 kB dist/chunks/settings-BRBnm_Ym.js 95.35 kB │ gzip: 31.28 kB dist/chunks/settings-CVC5rkjp.js 96.24 kB │ gzip: 30.25 kB dist/chunks/settings-BkBtZC4J.js 96.54 kB │ gzip: 31.07 kB dist/chunks/settings-CieI-1Mb.js 96.69 kB │ gzip: 31.29 kB dist/chunks/settings-B66KzPCm.js 96.76 kB │ gzip: 31.00 kB dist/chunks/settings-9SQRYdZB.js 97.43 kB │ gzip: 30.63 kB dist/chunks/settings-SLvEuswu.js 97.73 kB │ gzip: 29.84 kB dist/chunks/settings-ZbjRhvJu.js 97.88 kB │ gzip: 30.56 kB dist/chunks/settings-DcvqxYeU.js 98.00 kB │ gzip: 30.12 kB dist/chunks/settings-zM5sKfmv.js 98.45 kB │ gzip: 30.99 kB dist/chunks/settings-CtNelsxL.js 99.07 kB │ gzip: 30.96 kB dist/chunks/settings-CkJNPkVe.js 102.58 kB │ gzip: 32.27 kB dist/chunks/settings-Cs2L7bt6.js 116.04 kB │ gzip: 33.66 kB dist/chunks/settings-x4cA6zOI.js 116.16 kB │ gzip: 34.00 kB dist/chunks/settingsStore-CvYyWlFq.js 135.74 kB │ gzip: 29.20 kB dist/chunks/steam-gKdfv4mr.js 378.89 kB │ gzip: 103.59 kB dist/index.js 1,223.65 kB │ gzip: 268.08 kB ✓ built in 921ms [verify] Found: plugin.json [verify] Found: package.json [verify] Found: main.py [verify] Found: paths.py [verify] Found: storage.py [verify] Found: sanitizer.py [verify] Found: launchers.py [verify] Found: dist/index.js [verify] Found: i18n/en-US/settings.json [verify] Found: assets/tab-icon.svg [verify] main.py is executable [verify] plugin.json flags OK (no debug) [verify] plugin.json icon resolves (assets/tab-icon.svg) [verify] package.json matches repo [verify] Package OK: deck-shelves-v3.2.1.zip [package] Created installable archive: deck-shelves-v3.2.1.zip [INEFFECTIVE_DYNAMIC_IMPORT] src/steam/index.ts is dynamically imported by src/core/shelfRefresh.ts but also statically imported by src/components/Shelf.tsx, src/components/ShelfManageRoute.tsx, src/components/filter/DeveloperFilterOptions.tsx, src/components/filter/PublisherFilterOptions.tsx, src/components/qam/list/ShelfActions.tsx, ..., dynamic import will not move module into another chunk.
Verify package66 msPASS▶
[verify] Found: plugin.json [verify] Found: package.json [verify] Found: main.py [verify] Found: paths.py [verify] Found: storage.py [verify] Found: sanitizer.py [verify] Found: launchers.py [verify] Found: dist/index.js [verify] Found: i18n/en-US/settings.json [verify] Found: assets/tab-icon.svg [verify] main.py is executable [verify] plugin.json flags OK (no debug) [verify] plugin.json icon resolves (assets/tab-icon.svg) [verify] package.json matches repo [verify] Package OK: deck-shelves-v3.2.1.zip
Compat validation6.0sPASS▶
api | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. api | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/api/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. host | WARN The field "pnpm.onlyBuiltDependencies" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.onlyBuiltDependencies" at the root of the workspace instead. host | WARN The field "pnpm.overrides" was found in /home/runner/work/Deck-Shelves/Deck-Shelves/host/package.json. This will not take effect. You should configure "pnpm.overrides" at the root of the workspace instead. > deck-shelves@3.2.1 validate:compat /home/runner/work/Deck-Shelves/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 (1223657 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 v20.20.2 ✅ 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 (40005 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) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ No CheatDeck namespace collision (no references) ✅ 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 (15) — 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 7 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 base locale exists ✅ All locale slice files are valid JSON ✅ Base locale has 1510 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 ⚠️ hardware_info.py imports subprocess/shutil (review security) ⚠️ perf_probe.py imports subprocess/shutil (review security) ⚠️ peripherals.py imports subprocess/shutil (review security) ⚠️ storage.py imports subprocess/shutil (review security) ✅ All 12 backend modules compile ✅ Backend /proc + /sys access is read-only Result: 7 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!