- Render the control-mode radio group only while editing, so the read-only
view can no longer mutate the store without passing the 2FA-gated Edit flow
- Show a dedicated message when no private key exists at the given path
instead of the raw transport error
- Share parseHostAddress between the SSH target and host key steps so
bracketed IPv6 loopback targets no longer trigger the remote-address warning
- Keep a stale host key scan or connection test from clearing the loading
state of a newer in-flight run
- Align the E2E spec with the read-only control mode view
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Assert the control-mode editor exposes Host via SSH and the wizard route
stops at the two-factor guard without calling the host setup API.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The demo now fabricates most of what it shows — geo lookups, upstream and site
probes, connection counters, DNS records, a synthetic access log — and refuses
a set of routes outright. Nothing verified that any of it actually reaches the
screen, so a provider could silently stop being installed and every page would
still look plausible.
Eleven Playwright specs, split into per-module data assertions and the
cross-cutting guardrails: /api/pty returns the typed demo refusal rather than a
404 or a successful upgrade, the simulated shell answers `help` and `nginx -t`
without opening a WebSocket, and the destructive routes return code 40300.
Kept as its own top-level package rather than joining the app/ Bun workspace,
so the frontend build is untouched. Not wired into CI yet: it needs a running
container, and the job shape is worth deciding separately.
Also hides the Preference > Terminal tab in demo mode, which the terminal work
had specified but never implemented — the tab was still reachable and led to a
panel with nothing behind it. The tab renders only once the demo flag has
resolved, so a normal installation is unaffected.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>