Two reported issues against v0.3.7 — both fixed.

## Reinstall step

After updating the desktop app, click **Install / Update** on the Management Service card so the refreshed on-host service binary is pushed.

## Fixed

- **`Install management service` failed with `install: No such file or directory` when SSH'ing in as `root`** on Ubuntu 24.04+. Root cause: the install-init and write-token steps piped base64-decoded content into `sudo install /dev/stdin <dest>`, and sudoers' `Defaults use_pty` (default on noble) allocates a pty for the child process which severs the upstream pipe. The same flow worked when SSH'ing as `dune` because that account's sudoers entry bypasses `use_pty`. Both steps now stage their payload to a real temp file via `mktemp` first, then `sudo install <tmp> <dest>`, sidestepping the pty entirely.
- **Director tunnel button grayed out even on a fully running BattleGroup**. We were parsing the vendor wrapper's `battlegroup status` text table for phase information, but newer Funcom operator builds changed the row vocabulary (the "Status" column now shows the partial world name, "Director" shows an `N/M` ready ratio, "Uptime" shows a `Healthy` / `Unhealthy` word instead of a duration). None of those values matched our phase allowlist, so the UI thought the BattleGroup was not started. We now read phase / serverGroupPhase / directorPhase / databasePhase / uptime / per-server stats directly from the BattleGroup CR's `status` object via `kubectl get battlegroup ... -o json`, which is the stable Kubernetes schema and immune to future wrapper text format changes.

## Changed

- Server status reads no longer go through the vendor wrapper. Start, stop, restart, and update lifecycle actions still use the wrapper (where it's the source of truth for orchestration).
