feat(host,api): the host knows what OS it runs, and says so

Clients want to show which OS/distro a host runs. The host now detects it once
per process (new osinfo module: compile-time on Windows/macOS, os-release on
Linux) and advertises an icon-friendly specificity chain, generic → specific —
`windows`, `macos`, `linux[/<family>][/<id>]`, e.g. `linux/fedora/bazzite`,
`linux/arch/steamos`. A client walks the chain most-specific-first and shows the
first token it has art for, so an unknown distro degrades to its family's mark
and finally to plain Tux — the host emits the full chain precisely so clients
need zero distro→parent knowledge. The middle token is the first recognized
ID_LIKE ancestor (the spec orders them most-similar-first); the leaf is ID
verbatim, sanitized to TXT-safe `[a-z0-9._-]` because it feeds a DNS record.

Two carriers, both additive: a new advisory mDNS `os=` TXT key (same trust
posture as `mac` — unauthenticated, a wrong value only draws a wrong icon), and
`HostInfo.os` + `HostInfo.os_name` on the mgmt API (`os_name` is the os-release
PRETTY_NAME, REST-only so the TXT stays small). GameStream serverinfo and the
QUIC Welcome are untouched. api/openapi.json regenerated (drift test green on
Linux) and the TS SDK gen refreshed from it — which also catches the committed
gen up with earlier spec changes it had missed (monitors, native_paired_clients,
encoder_backend).

assets/os-icons/ gains the ten master SVG marks every client derives its
per-platform art from (Font Awesome Free brands CC BY 4.0 + Simple Icons CC0 —
provenance in its README), with attribution folded into THIRD-PARTY-NOTICES.txt
via the generator (regenerating also catches the stale crate manifest up with
the current lockfile).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-29 17:58:33 +02:00
co-authored by Claude Fable 5
parent e44baf6768
commit 4c2a6dd091
26 changed files with 1119 additions and 805 deletions
+12
View File
@@ -5335,6 +5335,8 @@
"abi_version",
"app_version",
"gfe_version",
"os",
"os_name",
"codecs",
"gamestream",
"ports"
@@ -5372,6 +5374,16 @@
"type": "string",
"description": "Best-effort primary LAN IP."
},
"os": {
"type": "string",
"description": "OS identity chain, generic → most specific, slash-separated (`windows` | `macos` |\n`linux[/<family>][/<id>]`). A client walks it most-specific-first and shows the first\ntoken it has an icon for, so an unknown distro still degrades to its family's mark.",
"example": "linux/fedora/bazzite"
},
"os_name": {
"type": "string",
"description": "Human-readable OS name (os-release `PRETTY_NAME`; `\"Windows\"`/`\"macOS\"` elsewhere).",
"example": "Bazzite 42 (Kinoite)"
},
"ports": {
"$ref": "#/components/schemas/PortMap"
},