VAPP-16: Agent install flow behind "+ New Device" #14

Merged
David merged 3 commits from feat/new-device-install-flow-vapp-16 into main 2026-06-07 00:01:26 +02:00
Owner

VAPP-16: Agent install flow behind "+ New Device"

The "+ New Device" topbar button was inert. This wires it (and a new empty state on /devices) to an enrollment dialog so an operator can onboard a device without leaving the app.

What it does

  • Opens a dialog from "+ New Device" and from the /devices empty state, both via a shared NewDeviceOpen context signal; the dialog is mounted once in Layout.
  • Mesh selector populated from list_meshes.
  • On mesh select, the new get_mesh_install server fn proxies vervain-server's session-gated /meshsettings.ashx?id=<short> route (forwarding the session as the mc_session cookie, the same way the control channel does) and parses the config's MeshServer line into the browser-facing https://host:port base.
  • Renders three paste-ready things for a Linux x86_64 host: the per-mesh .msh config download (a data: URL so the exact MeshID is preserved and previewed), the agent binary download (/meshagents/6, the unauthenticated route; AgentId 6 = Linux64), and a copy-paste install snippet (download, vervain-agent config seal --from <file>, vervain-agent install --system) with the real server URL substituted in.
  • Windows and macOS are stated as unavailable (vervain-agent ROADMAP Phase 6) rather than offered as dead links.

Acceptance criteria

  • Dialog opens from "+ New Device", mesh selectable, config and binary fetchable
  • meshsettings download carries the correct MeshID for the chosen mesh (the .msh text from /meshsettings.ashx is passed through verbatim and previewed)
  • Following the snippet on a clean Linux host enrolls the device and it appears on /devices (needs a live server + clean host to verify end to end; the snippet mirrors the recipe proven in PR #9)
  • Unsupported platforms are stated, not linked
  • Dialog reachable also from the empty-state of /devices

Checks

cargo check (server + wasm32), cargo clippy -D warnings, cargo fmt --check, and cargo test all pass. Added unit tests for the MeshServer URL parsing and Content-Disposition filename extraction.

🤖 Generated with Claude Code

## VAPP-16: Agent install flow behind "+ New Device" The "+ New Device" topbar button was inert. This wires it (and a new empty state on `/devices`) to an enrollment dialog so an operator can onboard a device without leaving the app. ### What it does - Opens a dialog from "+ New Device" and from the `/devices` empty state, both via a shared `NewDeviceOpen` context signal; the dialog is mounted once in `Layout`. - Mesh selector populated from `list_meshes`. - On mesh select, the new `get_mesh_install` server fn proxies vervain-server's session-gated `/meshsettings.ashx?id=<short>` route (forwarding the session as the `mc_session` cookie, the same way the control channel does) and parses the config's `MeshServer` line into the browser-facing `https://host:port` base. - Renders three paste-ready things for a Linux x86_64 host: the per-mesh `.msh` config download (a `data:` URL so the exact `MeshID` is preserved and previewed), the agent binary download (`/meshagents/6`, the unauthenticated route; AgentId 6 = Linux64), and a copy-paste install snippet (`download`, `vervain-agent config seal --from <file>`, `vervain-agent install --system`) with the real server URL substituted in. - Windows and macOS are stated as unavailable (vervain-agent ROADMAP Phase 6) rather than offered as dead links. ### Acceptance criteria - [x] Dialog opens from "+ New Device", mesh selectable, config and binary fetchable - [x] meshsettings download carries the correct MeshID for the chosen mesh (the `.msh` text from `/meshsettings.ashx` is passed through verbatim and previewed) - [ ] Following the snippet on a clean Linux host enrolls the device and it appears on /devices (needs a live server + clean host to verify end to end; the snippet mirrors the recipe proven in PR #9) - [x] Unsupported platforms are stated, not linked - [x] Dialog reachable also from the empty-state of /devices ### Checks `cargo check` (server + wasm32), `cargo clippy -D warnings`, `cargo fmt --check`, and `cargo test` all pass. Added unit tests for the `MeshServer` URL parsing and `Content-Disposition` filename extraction. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(new-device): agent install flow behind "+ New Device"
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 1m44s
24ffccff52
Wire the inert "+ New Device" topbar button (and a new empty state on /devices) to an enrollment dialog so an operator can onboard a device without leaving the app. The dialog picks a mesh from list_meshes, then renders three paste-ready things for a Linux x86_64 host: the per-mesh .msh config download, the agent binary download, and a copy-paste install snippet (download, vervain-agent config seal --from <file>, vervain-agent install --system) with the real server URL substituted in.

New get_mesh_install server fn proxies vervain-server's session-gated /meshsettings.ashx?id=<short> route, forwarding the session as the mc_session cookie the way the control channel does, and parses the config's MeshServer line into the browser-facing https://host:port base. The agent link points at the unauthenticated /meshagents/6 route (AgentId 6 = Linux64). Windows and macOS are stated as unavailable (vervain-agent ROADMAP Phase 6) rather than offered as dead links.

The dialog is mounted once in Layout and raised through a shared NewDeviceOpen context signal, so both the topbar button and the devices empty state open it.

#VAPP-16

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(new-device): emit ServerURL/GroupID so the sealed config boots
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 1m49s
Create release / Create release from merged PR (pull_request) Has been skipped
f7d1a6dc36
The /meshsettings.ashx config carries only the legacy MeshServer= and MeshID= keys, but vervain-agent's settings store requires ServerURL= and GroupID= and refuses to start without them ("required key `ServerURL` is missing"), so the dialog's verbatim .msh could not enroll a clean host and the snippet's seal step produced a non-booting config. get_mesh_install now appends the two keys derived from their legacy twins (never overwriting explicit values), keeping the legacy lines intact. Unit tests cover the derivation and the no-overwrite rule.

Verified end to end against a live vervain-server: fetched the dialog's payload through the real server fn, sealed it verbatim on a clean directory (no manual config set steps), ran the agent, and the device appeared on /devices. This closes the PR's previously unchecked acceptance criterion.

#VAPP-16

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
Owner

Fixed two things: (1) resolved the merge conflict with main (import union in src/server_fns/mod.rs after the user-management merge); (2) the previously unchecked acceptance criterion was failing for a real reason: the verbatim /meshsettings.ashx config carries only the legacy MeshServer=/MeshID= keys, but vervain-agent requires ServerURL=/GroupID= and refuses to boot without them, so the snippet's seal step produced a non-starting config. get_mesh_install now derives and appends the two keys (never overwriting explicit ones), with unit tests. Verified end to end against a live stack: fetched the dialog's payload through the real server fn, sealed it verbatim with no manual steps, ran the agent, and the device appeared on /devices via meshctrl and the app. All ACs now hold; just check clean (7 tests).

Fixed two things: (1) resolved the merge conflict with main (import union in src/server_fns/mod.rs after the user-management merge); (2) the previously unchecked acceptance criterion was failing for a real reason: the verbatim /meshsettings.ashx config carries only the legacy MeshServer=/MeshID= keys, but vervain-agent requires ServerURL=/GroupID= and refuses to boot without them, so the snippet's seal step produced a non-starting config. get_mesh_install now derives and appends the two keys (never overwriting explicit ones), with unit tests. Verified end to end against a live stack: fetched the dialog's payload through the real server fn, sealed it verbatim with no manual steps, ran the agent, and the device appeared on /devices via meshctrl and the app. All ACs now hold; just check clean (7 tests).
David merged commit 07278e210d into main 2026-06-07 00:01:26 +02:00
David deleted branch feat/new-device-install-flow-vapp-16 2026-06-07 00:01:26 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/vervain-apps!14
No description provided.