Source: SteamVR's built-in v4l2cam headset view (steamvr-v4l2cam.service -> v4l2loopback 'SteamVR'),
encoded with x264 on the Frame (fps=30 before scaling, nice 10, 3 threads) as fragmented MP4 over an
SSH exec channel; ffmpeg stops when the channel closes. A relay on 127.0.0.1 keeps the init segment and
the fragments since the last keyframe for late viewers and serves an MSE player page, opened in the
default browser (Flet can't show video outside flet build bundles). Verified on the dev Frame: 30 fps
in Edge, ~0.1 s behind the newest frame, 0.34 core at 720p with a quiet picture.
Agent v45: list_screenshots (screenshots.vdf + folders, every account; the Frame files headset shots under SteamVR
250820, so launch.sh now logs start/end to <anchor>/plays.log and upgrade_launchers adds it to existing launchers) and
delete_screenshots (only images in userdata/<id>/760/remote/<appid>/screenshots, links refused, vdf left to Steam).
PC: install/screenshots.py (thumbnail/full-image cache under screenshots-cache/<frame>, cancellable download).
GUI: Screenshots nav item (grid by day, game filter, viewer with prev/next, multi-select download/delete), game menu
entry; ui_smoke --fake-frame sample shots.
- reflowed long lines (texts unchanged; generated launcher/PowerShell/README texts byte-identical)
- CONTRIBUTING, SECURITY, CODE_OF_CONDUCT, THIRD_PARTY_NOTICES; pyproject metadata (SPDX licence, authors, urls,
classifiers, keywords)
- maintainer-only notes moved to a git-ignored CLAUDE.local.md; CLAUDE.md facts updated
- README: what kinds of apps run and how; INSTALL: PC VR and Files wording, new labels
- frameport/i18n.py: tr() (English text as key, JSON translations in locales/<language>.json, English fallback),
tr_n() plurals, size formatting; language from setting ui.language, loaded before the UI modules
- all GUI texts wrapped (templates with .format(), no f-strings inside tr()); hand-built plurals replaced
- help texts translated on lookup (unknown keys are errors); patch titles, descriptions and reasons translated
where shown; unused help texts removed
- no decisions based on displayed text: the library's quick action returns a kind, Show more keeps its state,
Files location names come from ids
- scripts/i18n_extract.py writes locales/template.json (802 texts); tests keep it current and fail on untranslated
literals in text controls
- agent: finalize checks the game data before replacing the installed APK; uninstalling a game removes its Steam
shortcut with Steam closed (detached worker, like adding); grid art deleted by exact appid; cleanup refuses dot
folders and the install folder; shortcuts.vdf backups capped at 5
- PC: exact grid art matching when pruning old shortcuts
- activity panel: refreshes serialized; a running job's log updates in place (its Cancel button isn't rebuilt)
- SSH key created private (0600) from the first byte; remote catalog ids validated; None checks in install and
adapter settings; navigate() follows NAV
- removed unused functions
Replaces the Send files dialog. Locations: Videos/Downloads/Documents (shared by every Quest game), each installed
game's own storage, the home folder. SFTP over the app's connection; every operation stays inside the chosen
location; Lepton's links in a game's storage are protected. Uploads/downloads are resumable jobs. Tested against
the Frame; ui_smoke --fake-frame serves sample files for the docs screenshot.
Found in the end-to-end test (0.3.1 -> 0.3.2): PowerShell started with DETACHED_PROCESS from the packaged app exits
without running the script, so the app quit and nothing was updated. apply() now waits until the script logs that it
runs and raises otherwise. The smoke test uses the same non-waiting launch as the app. The Linux bundle built on
24.04 needed GLib 2.80.
- The overport CLI now comes from Android-XR-Bridge/OVRPort (fallback ovrport/app); its four new patches are
described and shown only where they apply; parity classifies the 1.2.5 differences (VR metadata, config version,
CLI-added platform compat) as expected: 34/34 at parity.
- README rewritten (purpose, getting started, what works, credits, legal), INSTALL tightened, screenshots in
docs/images (scripts/scrub_library.py + ui_smoke --docs --fake-frame), Quest2Frame references removed.
- Game page: store descriptions without Markdown/[media] markup; themed labels on all switches.
- `frameport install --apk` installs a given build (headset A/B tests).
FramePort finds new GitHub releases by itself and updates in one click: sidebar card + Library bar, a dialog with
the release notes, "Update and restart" (download, SHA256SUMS check, Windows signer check, swap script, relaunch),
optional automatic installs at the next start. CLI: --version, `frameport update [--check] [--yes]` and a
once-a-day hint. One version source (_version.py); releases also ship the CLI wheel and "What's new" from the
annotated tag; CI runs an update smoke test with each OS's archive.
- "Share working config…" (game menu, `frameport share-recipe`): saves the recipe as known-good and opens a
prefilled working-config issue form; labelling it `catalog-accepted` runs catalog-from-issue.yml, which
validates the YAML (scripts/catalog_from_issue.py) and opens a PR adding catalog/games/<pkg>.yaml
- "Collect logs" / "Report a problem…" (game menu, Settings, failure pop-up, `frameport diag collect|report`):
redacted diagnostics zip (app + job logs, library entry, recipe, launch logs + re-triage, APK/ELF/PE listings
instead of game files, Frame launcher/settings/Lepton/logcat/XRService logs via agent v21 `collect_diag`) and
a prefilled bug-report issue to attach it to; `frameport diag inspect <zip>` re-triages a bundle offline
- diag/redact.py scrubs IPs, MACs, host/user names, home dirs, Steam ids, data and dump folders
- App log (<data>/logs/app.log) and saved GUI job logs (<data>/logs/jobs/)
- catalog.entry_from_library shared by "Save as known-good" and sharing; docs/DIAGNOSTICS.md
Adds Oculus Rift (PC VR) games alongside Quest:
- analysis/rift.py (own PE reader: imports incl. delay-imports, GUI-subsystem
filter, exe ranking, icons), sources/rift_dump.py (recursive scan, one game
per folder, collections), catalog rift fields + Rick and Morty recipe.
- patches/pcvr.py (category "pcvr", shown as patches): Revive (LibOVR->OpenXR,
default on for Oculus games), revive_openvr, no_crash_reporter (Unreal),
oculus_unreal (OculusHMDConnected helper), xr_timefix (Frame OpenXR layer),
proton_*. tools/revive.py (find/install Revive, never replaces the user's).
- targets/pc_revive.py (run on this Windows/WSL PC via Revive + local Steam;
core/winhost.py helpers) and frame_lepton Proton path; agent handles Proton
install, prepare/finalize_pcvr, launch, list_files (AGENT_VERSION 17).
- native/oculushmd (fp_oculushmd.exe) and native/xrlayer (Frame OpenXR 1.1->1.0
+ timespec-time layer); prebuilt artifacts + SHA256SUMS.
Runtime findings (Frame, SteamOS 0.4.2 / Proton 11 arm64): the SteamVR runtime
only accepts OpenXR 1.0, so Proton's vrhelper (1.1) needs the compat layer;
Oculus/LibOVR games need a VR runtime (Revive on PC with SteamVR, or SteamVR-
native builds run directly). Platform-SDK / signature-checked repacks can't run
on the Frame; those are flagged, never bypassed.
GUI overhaul (ui/): streaming persistent Library with tags/filters/sort, a
background job queue + activity panel, per-game page, Frame tab with installed
list + file browser, Settings (incl. agent version), Play + launch-test actions,
resumable/interruptible installs with up-front interventions, dark theme, help
hints, uninstaller (uninstall.py). Faster uploads via a direct link (USB /
Frame hotspot) when reachable. Artwork/details from OculusDB + Steam + ovrp,
composed Steam art sets and tags, thumbnails served by URL.
Docs (PLAYBOOK/FRAME_RUNTIME/ARCHITECTURE/INSTALL/CLAUDE.md), triage signatures,
and unit tests throughout (130 pass).
- New analysis signals: MR-only (passthrough required + boundaryless), required hand tracking, CryEngine,
Unreal version, which libs reference com.oculus.os, data size.
- Evidence-based detect() rules (force passthrough, scene emulation, meta permissions, controller passthrough,
space warp for heavy OVRPlugin games, nodebug for old UE4 / Unreal Meta XR Audio, oculusos, Unity MSAA,
CryEngine VRS config). With the catalog switched off they reproduce 33/34 verified recipes
(scripts/eval_heuristics.py); Phantom's no-ForceQuit build stays a runtime (triage) finding.
- Patch.applies(): GUI and CLI hide patches that can't matter for a game (engine/XR/graphics), with a
show-all toggle; enabled patches are always shown.
Python core + Flet GUI + CLI that turns the manual Steam Frame porting work
into a pipeline: scan dumps, analyze, suggest patches (overport + Frame fixes,
catalog of 34 verified recipes), build, static-validate, install over SSH via
a Frame-side agent, add Steam shortcuts with artwork, headless launch test and
log triage. Includes the native sources (FrameBridge adapter, VrApi bridge
patches, GL shim), prebuilt artifacts, docs (playbook, runtime notes) and a
parity harness (34/34 games reproduce the known-good builds).