Address review findings in the app, server and tests

- app: startup shell, python and ssh probes run asynchronously so a slow
  shell profile can't freeze the window; PATH comes from the user's real
  login shell and a failed lookup isn't cached; a server that never
  answers is killed; the setup offer runs once per launch, only after the
  UI loads, and decides from HostName alone; connect.sh is started through
  `env ... zsh` so it works whatever the login shell is.
- server: volume validates the level before muting or changing anything.
- Steam: null-safe install-manager fields, http.client errors caught in
  store ratings, price fallback when a sale has no final price.
- tests: server output kept for diagnosis, any startup error retried, and
  captures asserted non-cacheable.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
saphidandClaude Opus 5.5 committed 2026-09-25 22:44:54 +10:00
1 parent d4486a7681
commit 99653151c4
13 files changed
+340 -38

No files matched your search

+8 -4
View File
@@ -8,6 +8,7 @@ Usage: ui/server.py [--port 47810] (normally started by scripts/frame-ui.sh)
Env: FRAME_ALIAS (default frame)
"""
import argparse
import http.client
import json
import os
import re
@@ -204,7 +205,7 @@ def steam_frame(*args, timeout=40):
except Failure as e:
# frame_steam.py prints {"error": ...} on stdout when it fails, but ssh()
# reports stderr instead if there was any, so look in both.
for line in reversed([*getattr(e, "stdout", "").splitlines(), *str(e).splitlines()]):
for line in [*reversed(getattr(e, "stdout", "").splitlines()), *reversed(str(e).splitlines())]:
try:
raise Failure(json.loads(line)["error"]) from None
except (ValueError, KeyError, TypeError):
@@ -230,17 +231,20 @@ def steam_search(query):
raise Failure("cc must be a two-letter country code", 400)
try:
return {"results": frame_store.search((q.get("q") or [""])[0], cc)}
except (OSError, ValueError, TypeError, AttributeError) as e:
except (OSError, ValueError, TypeError, AttributeError, http.client.HTTPException) as e:
raise Failure(f"Steam store search failed: {e}")
def set_volume(body):
if "muted" in body:
ssh(f"wpctl set-mute @DEFAULT_AUDIO_SINK@ {1 if body['muted'] else 0}")
# Validate everything before touching the headset.
level = None
if "level" in body:
level = float(body["level"])
if not 0 <= level <= 1:
raise Failure("level must be 0..1", 400)
if "muted" in body:
ssh(f"wpctl set-mute @DEFAULT_AUDIO_SINK@ {1 if body['muted'] else 0}")
if level is not None:
ssh(f"wpctl set-volume @DEFAULT_AUDIO_SINK@ {level:.2f}")
return {"message": "Volume updated"}