mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 04:04:21 +02:00
Package the Frame Control web UI as an installable Electron Mac app and bring in the tooling built alongside it. - app/: Electron wrapper that starts ui/server.py on a free loopback port, hardened window (sandbox, no navigation, runAsNode fuse off), login-shell PATH so Homebrew tools work from Finder, first-run offer to run connect.sh, ad-hoc signed DMG/zip via electron-builder. - ui/: headset view (OpenVR screenshots), device status, library, Steam "Get games" (owned games, install, store search), Android apps as persistent Lepton instances with a rated F-Droid catalogue and a private compatibility database, Android display controls over ADB, file and clipboard transfer, Flatpaks, remote and power actions. - apk-catalog/, compat-db/, frame/: catalogue build pipeline, Lakebed capsule for compatibility reports, Frame-side launchers. - tests/ and CI: server guard and validation tests plus Steam helper tests, run on Python 3.9 with script and app syntax checks. - Docs: README leads with the Mac app; new Android, panels, Steam games and field-notes docs; security notes on LAN-exposed ADB ports. Screenshot values for the headset's IP and Wi-Fi name are placeholders. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
59 lines
2.5 KiB
Markdown
59 lines
2.5 KiB
Markdown
# compat-db: Frame Control's compatibility database
|
|
|
|
A private [Lakebed](https://docs.lakebed.dev/) capsule holding compatibility
|
|
reports for Android apps on the Steam Frame. Only Frame Control can read or
|
|
write it.
|
|
|
|
- Live: `https://frame-compat.lakebed.app` (deploy `dep_dDmcsosVSiFirpW6`,
|
|
owned by `saphid`, doesn't expire). The browser page only says it's private.
|
|
- Access: `GET /v1/reports?since=<createdAt>` and `POST /v1/reports` with
|
|
`{"reports": [...]}`. Both need the `x-frame-control-key` header. There are
|
|
no Lakebed queries or mutations, so nothing else can reach the rows.
|
|
- Key: `FRAME_CONTROL_KEY` in `.env.lakebed.server` (git-ignored, synced on
|
|
deploy) and in the Mac's login Keychain (service `frame-control-compat-db`,
|
|
account `app-key`), where `ui/frame_compat_db.py` reads it.
|
|
- Duplicates: each report carries a `clientId`, and a report already stored is
|
|
skipped, so retries and restores are safe to repeat.
|
|
- Free-plan limits: 1 MiB of data and 16,384 rows per deploy, 1,000 writes a
|
|
day. A report is about 300 bytes, so roughly 3,000 reports fit.
|
|
|
|
## Backups
|
|
|
|
`scripts/compat-db-backup.sh` exports every report through the app key and
|
|
keeps dated copies in
|
|
`~/Library/Application Support/Frame Control/compat-db/backups` (newest 60).
|
|
When the data has changed, it also uploads them to Google Drive
|
|
(**the backup folder**, folder
|
|
`<drive-folder-id>`) with `gog`. The LaunchAgent
|
|
`frame-compat-backup` runs it daily at 03:40; the log is
|
|
`~/Library/Logs/frame-compat-backup.log`. If an export has fewer reports than
|
|
the last good backup (`backups/.last-good`), it's kept as `refused-*.json`,
|
|
nothing is uploaded, and every later run refuses too until you rerun with
|
|
`--accept-shrink`.
|
|
|
|
Reports that can't be sent (unreadable outbox lines, or ones the server
|
|
rejects, which it lists by `clientId`) are never dropped: they move to
|
|
`~/Library/Application Support/Frame Control/compat-db/compat-outbox.jsonl.rejected`,
|
|
with the reason.
|
|
|
|
Restore (to this deploy or a new one):
|
|
|
|
```sh
|
|
python3 ui/frame_compat_db.py import BACKUP.json # duplicates are skipped
|
|
python3 ui/frame_compat_db.py count
|
|
```
|
|
|
|
`npx lakebed db export dep_dDmcsosVSiFirpW6 --out full.json` is a second,
|
|
owner-only export path through the Lakebed CLI.
|
|
|
|
## Change and deploy
|
|
|
|
```sh
|
|
cd compat-db
|
|
npx lakebed dev --port 3917 # local; data resets on restart
|
|
npx lakebed deploy # updates frame-compat.lakebed.app
|
|
```
|
|
|
|
To rotate the key: generate a new one, update the Keychain item and
|
|
`.env.lakebed.server`, then deploy.
|