Commit Graph
7 Commits
Author SHA1 Message Date
saphidandClaude Opus 5.5 a954fc83c9 Devices: several headsets, several addresses each, and live connection status
Frame Control can now manage more than one Steam Frame, and reach each at any
of several addresses (LAN IPs per network, its .local name, Tailscale). A
connector in the server tries them all at once, picks the best one that
answers, follows ssh -v through each stage (network, finding, SSH, identity,
login) and streams that to the page. The header shows it live; a new Devices
tab (key 5) manages headsets, addresses and network names.

- ui/frame_devices.py: registry in devices.json, imported from the managed
  ~/.ssh/config blocks; per-headset host key pinning; config block updates.
- ui/frame_network.py: gateway IP+MAC fingerprint, Wi-Fi name, Tailscale.
- ui/frame_link.py: the connector, Test now, Tailscale/mDNS discovery, API.
- server.py: ensure_master delegates to the connector; /api/connection,
  /api/connection/events (SSE), /api/devices.
- Electron: headset switcher and Devices item in the Frame menu.
- frame_connect.py --alias; FRAME_CONTROL_DATA_DIR / FRAME_CONTROL_SSH_DIR
  keep tests off real data.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 21:13:58 +10:00
saphid fbe7ba9575 Find installable APK alternatives in F-Droid main and archive 2026-09-28 14:16:43 +10:00
saphidandClaude Opus 5.5 fd0a284942 Refuse APK entries Android can't read; ignore stale title lists
- Only stored and deflated entries are read: Python 3.9's bzip2 and lzma
  readers inflate without bound before trimming.
- loadTitles drops a response that a newer request has overtaken, so the
  install dialog's replace warning uses the fresh list.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 22:49:18 +10:00
saphidandClaude Opus 5.5 dfacf43e55 Fix the follow-up review's findings
- APK reader: read members with a bounded read, since ZipFile.read inflates
  a member fully before trimming it to a forged declared size; the reference
  walk counts every entry it examines, dead ends and cycles included.
- Titles: a path that exists under the root wins over stripping the archive
  prefix; the prefix is taken before a linked folder is staged elsewhere
  (another drive on Windows); the install dialog loads a fresh title list
  first and says so if it couldn't check.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 22:44:07 +10:00
saphidandClaude Opus 5.5 39d28790a1 Fix the cross-provider review's findings
- APK reader: cap AndroidManifest.xml, resources.arsc and icon sizes before
  inflating them (APKs can come from install links), and follow resource
  references without cycles and with a result budget.
- Sideloading: reserve devkit-steam (SteamOS's sideloaded-client trampoline);
  the install dialog warns when a name replaces an installed title; a
  manifest's exe may name the program as it is in the archive, above the
  folder the installer steps into.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 22:35:16 +10:00
saphidandClaude Opus 5.5 d145537d9a Harden the APK reader and build downloads after review
- frame_apk: android: attributes win over same-named attributes in
  other namespaces; string attributes that keep only a typed value (no
  raw string) still resolve; a failed icon read leaves the icon out
  instead of failing the install.
- The clipboard IPC origin check can't throw on odd frame URLs.
- fetch-deps.js: 60 s download timeout, at most 5 redirects, a SystemRoot
  fallback for tar.exe, and prunes pydoc_data, venv and the static
  libpython.
- Docs keep the clipboard-tool note for running the UI in a browser.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 20:44:40 +10:00
saphidandClaude Opus 5.5 1a0e54d8bd Bundle Python and adb so the app needs nothing installed
- app/build/fetch-deps.js downloads a standalone Python 3.12
  (python-build-standalone) for every build and adb from Google's
  platform-tools, pinned by SHA-256, and prunes what the server never
  uses. It replaces the Windows-only embeddable Python.
- The app runs the bundled Python with -I -u -B -X utf8, so a PYTHONHOME
  or PYTHONPATH meant for another Python can't break it and nothing is
  written inside the signed macOS bundle.
- An adb you already have still goes first, so two adb versions don't
  keep restarting each other's server. arm64 Linux has no official
  platform-tools and keeps using the system adb.
- ui/frame_apk.py reads APK badging (package, label, version, min SDK,
  ABIs, icon) from the binary manifest and resources.arsc, replacing
  aapt2. It matches aapt2 on nine F-Droid APKs and finds launcher icons
  the old path missed with adaptive icons.
- The app reads the computer's clipboard through Electron, so Linux no
  longer needs wl-clipboard or xclip.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-26 16:42:49 +10:00