mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-26 17:04:35 +01:00
139 lines
15 KiB
Python
139 lines
15 KiB
Python
#!/usr/bin/env python3
|
|
"""Render the documentation from the same digest-scoped data used by the store."""
|
|
import argparse
|
|
from collections import Counter
|
|
import json
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def cell(value):
|
|
if isinstance(value, list):
|
|
value = ', '.join(str(v) for v in value) or 'none detected'
|
|
return str(value).replace('|', '|').replace('\n', ' ').replace('<', '<')
|
|
|
|
|
|
def render(data):
|
|
counts = Counter(p['status'] for p in data['plugins'])
|
|
lines = ['# Official Decky store compatibility with Framey', '',
|
|
f"Snapshot: {data['checkedAtUtc']}; {len(data['plugins'])} current visible official plugins from {data['source']}.", '',
|
|
'This table and both store views use [`ui/framey-compatibility.json`](../ui/framey-compatibility.json). '
|
|
'Results apply only to the exact store ID, version and SHA-256. A changed digest/version is **unverified**. '
|
|
'Regenerate this document with `python3 scripts/framey-compatibility-doc.py`; use `--check` in review.', '',
|
|
f"**Works: {counts['works']} · Partial: {counts['partial']} · Broken: {counts['broken']} · N/A: {counts['na']}.**", '',
|
|
'- **Works** requires verified useful plugin behavior with its real backend. Read the reason for the verified scope and remaining limits; it does not imply worn-VR verification.',
|
|
'- **Partial** means only a subset or a local fixture scope was verified, often just frontend/settings initialization. The remaining backend/device functionality is unverified; read the reason for the exact scope.',
|
|
'- **Broken** means a concrete archive, frontend or Steam dependency blocks the audited version. An artificial backend/network denial alone is not evidence that the real backend is broken.',
|
|
'- **N/A** means the plugin targets hardware or a display/UI surface that Framey does not provide. The store disables installation for these versions.', '',
|
|
'## Verification limits', '',
|
|
f"All exact archives were hash-checked and statically inspected. The local Chromium host used Framey commit `{data['hostCommit']}`, React 18.3.1 and an opaque `allow-scripts` iframe. "
|
|
'Each frontend was attempted for 1.2 seconds, including React effects. All plugin backend calls, fetches and websockets were denied. '
|
|
'Some plugins attempt mutating actions on mount; none reached a backend. Initialization (`ready`) does not guarantee React rendered, and delayed errors/actions may occur after the observation window. '
|
|
'The JSON preserves initializer errors, capped console observations and attempted method names.', '',
|
|
'The optional full-catalog fake-Frame audit exercises the real HTTP/SSH installer, receipt, frontend bytes and removal, '
|
|
'or expected rejection. It uses a private disposable Compose project with all plugin backend execution stubbed. '
|
|
'It checks archive transport and safeguards, not Python/native execution. Run it with:', '',
|
|
'```sh',
|
|
'python3 scripts/framey-audit-store.py --cache /tmp/framey-archives --output /tmp/framey-observations.json',
|
|
'python3 scripts/framey-audit-fake.py --cache /tmp/framey-archives --output /tmp/framey-fake/results.json',
|
|
'python3 scripts/framey-audit-browser.py --cache /tmp/framey-archives',
|
|
'```', '',
|
|
'Open the browser audit URL in local Chromium, run `runAudit()` and inspect/download `results`. All backend/network actions remain denied.', '',
|
|
'A [Free Loader duplicate-entry follow-up](evidence/framey-free-loader-duplicates-2026-10-26.md) accepts only byte-identical duplicate ZIP members whose modes differ at most in execute bits. The exact archive passed private local and focused fake-Frame install/remove; its frontend rendered in opaque Chromium and isolated Python settings/empty-deals reads passed with a Decky stub. The earlier full 116-plugin fake-Frame audit blocked this archive before the fix. Actual Decky, feed updates and worn VR remain unverified.', '',
|
|
'The current published digests are pinned in the JSON; if the store changed, retain/download those exact archives for reproduction. '
|
|
'Audit downloads permit larger ZIPs for inspection; production installer limits remain 50 MiB ZIP / 150 MiB unpacked / 30 MiB per member.', '',
|
|
'After the VR job released the shared lock, this audit acquired it and used a private temporary Decky 3.3.0 ARM64 user service. '
|
|
'Read-only ProtonDB `get_setting` and Steam Status `get_settings` calls succeeded through the live Steam CEF websocket. '
|
|
'The service and private base were removed and the lock released; normal managed services stayed inactive, battery was 100 → 99, '
|
|
'and no power setting was changed. [Redacted results](evidence/framey-official-backend-2026-10-25.json) '
|
|
'record exactly what ran. A [2026-10-26 follow-up](evidence/framey-events-backend-2026-10-26.json) '
|
|
'verified default Notebook drawing/save/reopen across a real backend restart and Simple Timer start/cancel, '
|
|
'countdown/completion events, a visible toast and persisted recents/subtle mode. '
|
|
'Only private test settings were written. Simple Timer remains partial because its own expired-timer startup '
|
|
'raises a missing `timer_task` error; sound/suspend are unsupported. '
|
|
'A [local audio follow-up](evidence/framey-audio-backends-2026-10-26.md) exercised Volume Mixer, Volume Boost and Mixer '
|
|
'through real Decky 3.3.0 amd64 backends on private silent virtual audio targets. Sliders, numeric volume entry, '
|
|
'independent server readbacks and Mixer filter persistence across a runtime restart passed. '
|
|
'An [ARM64 audio follow-up](evidence/framey-audio-arm64-2026-10-26.md) verified the unmodified official backends in actual Decky 3.3.0 on the Frame user audio session. Volume Mixer and Mixer now qualify as works for per-app volume: Chromium controls changed only a named silent stream, with independent Pulse readbacks. That run left Volume Boost partial because sink writes were denied. A [Volume Boost follow-up](evidence/framey-volume-boost-arm64-2026-10-26.md) now verifies linked/separate channel controls, re-link and reopen through the actual ARM64 backend. Independent Pulse reads confirmed 125%/150% gain writes while the default sink stayed muted; exact original volume/mute was restored. Volume Boost qualifies as works for sink controls. Audible output, Bluetooth playback and worn VR remain unverified. '
|
|
'A [running-context follow-up](evidence/framey-running-context-2026-10-26.md) supplies detached running-app/main-app reads and relays actual Steam lifetime callbacks while a panel is open. Real Frame checks verified an empty list, registration/cleanup and the exact Discord Status ARM64 backend reporting no IPC connection. Nonempty games and transitions were synthetic fixtures; real game events, Discord activity and worn VR remain unverified. Discord Status moves to partial; no new works claim is made. '
|
|
'A [library context follow-up](evidence/framey-library-context-2026-10-26.md) read 1,106 app overviews, 895 game IDs '
|
|
'and the current public Steam ID from real Frame CEF under the shared lock. Local Chromium replayed this detached snapshot '
|
|
'to render Deck Settings game selection, Steamback\'s empty save panel and PlayTime statistics/settings. '
|
|
'Steamback and PlayTime used actual Decky 3.3.0 amd64 backends in an isolated container; their ARM64 backends and automatic game hooks remain unverified. '
|
|
'Shotty\'s frontend now starts, but its published backend fails on missing `click`; it stays broken. '
|
|
'A [chunked frontend follow-up](evidence/framey-deck-shelves-browser-2026-10-26.md) loaded Deck Shelves 2.0.0 '
|
|
'through a managed JavaScript module route and rendered its settings in an opaque local Chromium panel. '
|
|
'Its backend was denied; Steam Home shelves and worn VR remain unverified. '
|
|
'A [local module lookup follow-up](evidence/framey-module-lookup-2026-10-26.md) supplies a finite registry of Framey-local controls and CSS. TabMaster QAM/docs now render; Steam library-tab editing remains unavailable. That pass exposed Junk-Store executable-script extraction failures; the follow-up below repairs them. SteamGridDB still requires Steam context-menu internals and DeckSP still fails its published MobX fallback. That pass tested TabMaster/Junk-Store in actual isolated amd64 Decky, without ARM64 or worn-VR coverage. A [script entrypoint follow-up](evidence/framey-script-entrypoints-2026-10-26.md) grants owner execute to shebang scripts and ZIP-declared executables without copying archive privilege/write bits. Junk-Store now passes static menu/backend calls in actual Decky 3.3.0 ARM64 and local Chromium Games/Epic navigation, back and reopen. It moves to partial: About still crashes on missing installed-app metadata, Legendary is absent, and login/game operations remain unverified. Existing installations require update/reinstall to repair permissions. A [read-only installed-metadata follow-up](evidence/framey-installed-context-2026-10-26.md) now repairs the About crash. The library snapshot copies only Steam-supplied installed booleans into detached metadata, preserving unknown values as undefined. Junk-Store About/Dependencies, Back and reopen render in local Chromium with actual Frame library data and the official ARM64 backend. It remains partial: dependency/login/game operations, RSS, the optional websocket and worn VR are unverified. Beyond the documented checks, official backends remain unexecuted. '
|
|
'The separate VR job proves Frame Control/sample compositor rendering, not any official plugin. '
|
|
'No worn-VR official-plugin result is claimed. '
|
|
'A [local UI follow-up](evidence/framey-ui-fallbacks-2026-10-26.json) rendered Pause Games and Tailscale Control settings '
|
|
'with all backend/network actions denied; it does not verify process pausing or Tailscale changes. '
|
|
'A [read-only Steam bridge follow-up](evidence/framey-steam-reads-2026-10-26.json) verified actual Frame country, '
|
|
'install folders and system information, plus IsThereAnyDeal\'s country dropdown in local Chromium. '
|
|
'The installed-plugin status was fixture-shaped in that relay; plugin backends stayed denied and the deployed headset HTTP endpoint remains unverified. '
|
|
'A [Web Browser frontend follow-up](evidence/framey-web-browser-2026-10-26.md) verified its exact archive now initializes with an inert null Steam React-root lookup. Its GamepadUI CDP/browser backend path remains unavailable, so it stays broken. '
|
|
'A [dialog and activation follow-up](evidence/framey-dialog-controls-2026-10-26.md) fixes DFL Focusable pointer/keyboard activation and confirmation descriptions, cancel/disabled actions, scoped close callbacks and nested dialogs. '
|
|
'AlarMe silent timer ticks/pause/cancel, private preset save/cancel-confirm/delete and stopwatch start/lap/pause/reset/reopen pass in local Chromium with its official Decky 3.3.0 ARM64 backend. '
|
|
'AlarMe stays partial: audio, alarms/reminders, sleep inhibition, Steam overlays and worn VR are unverified; notifications require the panel to remain open. '
|
|
'Earlier focused checks cover [ProtonDB](evidence/framey-browser-2026-10-25.md), '
|
|
'[Steam Status/cache](evidence/framey-cache-browser-2026-10-25.md), '
|
|
'[Storage Cleaner](evidence/framey-api-v1-browser-2026-10-25.md), and '
|
|
'[legacy MusicControl](evidence/framey-legacy-2026-10-25.md).', '',
|
|
'## Every current plugin', '',
|
|
'The API column shows manifest / actual bundled frontend API. Many manifests say v1 while their bundle connects API2. '
|
|
'Missing manifest API is labelled legacy; an unrecognized bundle is unknown. Globals and hardware are static signals, not exhaustive dependencies.', '',
|
|
'| Plugin / version | Manifest / bundle API | Status | Reason | Verified by |',
|
|
'| --- | --- | --- | --- | --- |']
|
|
for p in data['plugins']:
|
|
lines.append('| '+ ' | '.join(map(cell, [f"{p['id']}: {p['name']} {p['version']}",
|
|
f"{p['api']} / {p['frontendApi']}", 'N/A' if p['status']=='na' else p['status'], p['reason'], p['verification']]))+' |')
|
|
lines += ['', '## API, UI and backend inventory', '',
|
|
'DFL includes exports imported through decky-frontend-lib / @decky/ui. Steam stores and router/toaster/QAM signals are listed separately. '
|
|
'No signal means the static scan did not detect one, not that no dependency exists. Native binaries are classified by ELF machine or Windows MZ header; '
|
|
'Python files and source links are preserved in the JSON.', '',
|
|
'| Plugin | SteamClient methods | DFL / @decky/ui exports | Other Steam globals / UI surfaces | Backend | Hardware / OS signals |',
|
|
'| --- | --- | --- | --- | --- | --- |']
|
|
for p in data['plugins']:
|
|
native = sorted({n['arch'] for n in p['native']})
|
|
lines.append('| '+' | '.join(map(cell, [p['name'],p['steamClient'],p['dfl'],p['globals']+p.get('uiSurfaces',[]),
|
|
p['backend']+('; '+', '.join(native) if native else ''),p['hardware']]))+' |')
|
|
lines += ['', '## Native payload portability', '',
|
|
'All published Linux native payloads in this snapshot are x86_64; no published aarch64 payload was found. '
|
|
'The three Windows DLLs belong to Decky-Framegen. The installer still rejects these archives. '
|
|
'Apart from the explicitly described LocalSend experiment, ARM64 builds were not attempted: the constraints below remain unresolved.', '',
|
|
'[LocalSend ARM64 build/runtime evidence](evidence/framey-localsend-arm64-2026-10-26.md) '
|
|
'covers a reproducible MIT helper build and its isolated real-Frame protocol 2.0 info response. '
|
|
'The official x86 archive remains blocked; full plugin integration and file transfers are unverified.', '',
|
|
'| Plugin | Native payloads | ARM64 result / remaining blocker |', '| --- | --- | --- |']
|
|
for p in data['plugins']:
|
|
if p['native']:
|
|
binaries = [n['file'].removeprefix(p['folder']+'/') for n in p['native']]
|
|
if len(binaries)>5:
|
|
binaries = binaries[:5]+[f"… {len(binaries)} total; full list in JSON"]
|
|
lines.append('| '+' | '.join(map(cell,[p['name'],binaries,p['nativePort']]))+' |')
|
|
lines += ['', '## Evidence and maintenance', '',
|
|
'The canonical JSON contains full archive hashes, native paths, source URLs, frontend observations and fake-Frame outcomes. '
|
|
'Store compatibility is advisory except known installation/hardware blockers; removal always remains available. '
|
|
'A panel retains its compatibility reason after the initializer reports ready. Upstream fixes require a new digest-scoped audit. '
|
|
'Do not mark a plugin works based on archive installation, fake backend replies or initializer completion.', '']
|
|
return '\n'.join(lines)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--check', action='store_true')
|
|
args = parser.parse_args()
|
|
output = ROOT/'docs/framey-compatibility.md'
|
|
expected = render(json.loads((ROOT/'ui/framey-compatibility.json').read_text(encoding='utf-8')))
|
|
if args.check:
|
|
if not output.exists() or output.read_text(encoding='utf-8') != expected:
|
|
raise SystemExit('Compatibility documentation differs from canonical store data')
|
|
else:
|
|
output.write_text(expected, encoding='utf-8')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|