Skip to content

launch app with a predefined config - #1114

Merged
Micheal Parks (micheal-parks) merged 5 commits into
mainfrom
launch-app-with-config
Oct 21, 2026
Merged

Micheal Parks (micheal-parks) merged 5 commits into
mainfrom
launch-app-with-config

Conversation

@DTCurrie

@DTCurrie Devin T. Currie (DTCurrie) commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Lets the desktop app connect to a machine on boot from a launch file, so the Viam CLI can open the visualizer for one part with no machine picker involved. This is phase 2 of the CLI launch effort, the next phase adds the viam machines part visualize command that writes the file.

Desktop shell

  • launch_config::find_launch_file reads --launch-file <path> or --launch-file=<path> from argv. read_and_remove reads the file, deletes it, then parses it and requires version to be the integer 1. Every error names the path and never the contents, and also goes to stderr.
  • LaunchConfigState holds the LaunchConfigPayload (config or error, one set) as managed state. The launch_config command returns it, or null when the app started with no flag.
  • The single-instance callback now runs the same parser over the second launch's argv. A new file replaces the state and emits launch-config-changed, so the running window switches machine without a restart.
  • Argv is parsed with std::env::args, not tauri-plugin-cli, see Why.

Visualization

  • launchConfig.ts is the version 1 contract: LaunchConfig, LaunchCredentials (access-token or api-key), the command and event names, and the payload shape.
  • parseLaunchConfig validates a raw payload and throws a message naming the first bad field or the unsupported version. launchConfigToDialConf maps it to DialWebRTCConf with sessions disabled.
  • resolveConnection picks what to dial: a launch config always wins over the picker's active config. It also returns the credentials for ViamAppProvider, so an access token works with no machine API key.
  • useLaunchConfig wraps invoke and listen behind isTauri(). Outside Tauri it is ready immediately with no config. It exposes ready, current, and error.
  • +layout.svelte derives dialConfigs, partID, and dialConfig from resolveConnection, and passes serviceHost and credentials from the launch config when present.
  • Machines takes a launch prop. A launched part renders as a read-only entry (machine name, part name, host) and every config Switch is disabled while launched. A launch error renders in a prime Banner inside a role="alert" wrapper and is logged once per message through the Logs plugin.
  • ConnectionConfig moves to connectionConfig.ts. configs.ts and useConnectionConfigs.svelte.ts import it instead of each declaring a copy.
  • README documents the launch file shape under the Desktop app subsection.

Why?

Why a file and not argv JSON or a URL scheme?

The file carries a token. Argv is visible to every local user through ps, and a custom URL scheme leaks the token to OS handler logs and needs an installed app to register on macOS. The CLI writes the file with 0600 and the app deletes it on read.

Why std::env::args instead of tauri-plugin-cli?

The single-instance plugin hands the second launch's argv over as a Vec<String>. One parser serves both the first launch and a relaunch. The CLI plugin would add a dependency, a config block, and a capability for the startup path only.

Why does the picker go read-only instead of adding the launched part to the list?

The launched entry carries a short-lived token, so it must not reach IndexedDB. Keeping it out of the editable list means nothing persists it.

Testing

Ran pnpm check, pnpm test (137 files, 2000 tests), pnpm lint, and in src-tauri/, cargo clippy --all-targets -- -D warnings and cargo test (7 tests). pnpm tauri:build produced the bundle.

Added specs for parseLaunchConfig (both credential types, version mismatch, each missing field, unknown credential type), launchConfigToDialConf, resolveConnection (launch wins, picker alone, neither), and useLaunchConfig (non-Tauri path, resolved config, Rust error, rejected invoke, parse error, event replacing the config, unlisten on teardown). Rust tests cover both argv spellings, the missing value, and read_and_remove on a version 1 file, a version 2 file, invalid JSON, and a missing path, asserting the file is gone afterwards.

Smoke-tested the built binary: --launch-file pointing at a version 2 file prints Launch file version 2 is not supported, expected 1 to stderr and the file is deleted. A missing path prints Cannot read launch file <path>.

Not verified: a live connection with each credential type. That needs a CLI-held token, which the next phase produces. The accessibility review could not settle from source whether prime Switch exposes disabled to assistive tech.

@DTCurrie
Devin T. Currie (DTCurrie) added this pull request to stack #1115 October 13, 2026 21:50
@changeset-bot

changeset-bot Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: f2d8b05

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@viamrobotics/visualization Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-21 20:22 UTC

Base automatically changed from add-tauri-app to main October 14, 2026 15:04
@DTCurrie
Devin T. Currie (DTCurrie) force-pushed the launch-app-with-config branch 3 times, most recently from f251847 to de4849f Compare October 15, 2026 19:19
@DTCurrie
Devin T. Currie (DTCurrie) force-pushed the launch-app-with-config branch 2 times, most recently from 362d326 to a636ff9 Compare October 20, 2026 17:15
@micheal-parks
Micheal Parks (micheal-parks) merged commit 538fdf7 into main Oct 21, 2026
8 checks passed
@micheal-parks
Micheal Parks (micheal-parks) deleted the launch-app-with-config branch October 21, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants