Skip to content

Commit f02b60f

Browse files
committed
chore(desktop): simplify installation and remove switchyard-menubar
Signed-off-by: Elyas Mehtabuddin <emehtabuddin@nvidia.com>
1 parent c8f48e7 commit f02b60f

27 files changed

Lines changed: 130 additions & 3011 deletions

‎Cargo.lock‎

Lines changed: 0 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ members = [
1515
"crates/switchyard-nemo-relay-plugin",
1616
"crates/switchyard-runner",
1717
"crates/switchyard-desktop",
18-
"crates/switchyard-menubar",
1918
"crates/switchyard-costs",
2019
"crates/switchyard-server",
2120
"crates/switchyard-skill-distillation",

‎INSTALLATION.md‎

Lines changed: 119 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,73 @@ See [Getting Started](docs/getting_started.md#server-path) for a complete TOML
3636
deployment and [`switchyard-server`](crates/switchyard-server/README.md) for the
3737
configuration reference.
3838

39-
## Desktop installer
39+
## Server Keys
40+
41+
In a server config, each LLM client and decision client names its API key
42+
variable with `api_key_env`. A server you start from a terminal reads those
43+
variables from your shell, as it always has. The installed server does not: on
44+
macOS launchd starts it, on Linux systemd, and on Windows Task Scheduler. None
45+
of them runs your shell, so the installed server never sees the variables that
46+
`~/.zshrc` or `~/.bashrc` exports.
47+
48+
The installed server reads each key from the system credential store instead:
49+
macOS Keychain, Windows Credential Manager, or the Linux Secret Service (GNOME
50+
Keyring on Ubuntu and GNOME, KDE Wallet on Plasma). A key is saved under its
51+
variable name, such as `NVIDIA_API_KEY`. Before each start, the installed
52+
helper reads the keys that the config names and passes them to the server. A
53+
saved key replaces any value the service manager passes. If a variable has no
54+
saved key, the server does not start, and the server log names the variable.
55+
56+
To save, replace, or remove a key in the desktop app, open **Settings → Server
57+
keys**. Type or paste the key, or choose **Import from shell** to read the
58+
variable once from your login shell. From a terminal on macOS or Linux, run the
59+
installed helper:
4060

41-
From a source checkout, run `cargo desktop --help` for the commands and
42-
`cargo desktop install --dry-run` to preview installation. This checkout has
43-
the installer helper but does not yet build the desktop app executable, so
44-
full installation cannot complete. Uninstall keeps settings, history, and
45-
recovery copies.
61+
```bash
62+
~/.switchyard/bin/switchyard-desktop-install key status --config ~/.switchyard/composite.toml
63+
~/.switchyard/bin/switchyard-desktop-install key set NVIDIA_API_KEY # prompts without echo
64+
~/.switchyard/bin/switchyard-desktop-install key import NVIDIA_API_KEY # reads it from your login shell
65+
~/.switchyard/bin/switchyard-desktop-install key remove NVIDIA_API_KEY
66+
```
4667

47-
The installer requires the repository's Rust toolchain. macOS uses LaunchAgents;
48-
Linux requires a systemd user session. Windows requires MSVC build tools,
49-
WebView2, and a Task Scheduler user session.
68+
On Windows, the installer puts the helper in
69+
`%LOCALAPPDATA%\Programs\Switchyard`. There `key set` reads the key from
70+
standard input without a prompt, and `key import` reads the variable from your
71+
Windows environment variables. From PowerShell:
72+
73+
```powershell
74+
$helper = "$env:LOCALAPPDATA\Programs\Switchyard\switchyard-desktop-install.exe"
75+
& $helper key status --config "$env:USERPROFILE\.switchyard\composite.toml"
76+
[Net.NetworkCredential]::new('', (Read-Host 'Key' -AsSecureString)).Password | & $helper key set NVIDIA_API_KEY
77+
& $helper key import NVIDIA_API_KEY
78+
& $helper key remove NVIDIA_API_KEY
79+
```
5080

51-
On Windows, run install and uninstall from the source checkout with Cargo.
52-
The installed helper rejects changes to its own installation because Windows
53-
locks running executables. The app's Update command uses a temporary helper
54-
copy. The installed helper still supports `uninstall --dry-run`.
81+
Restart the server after you change a key. If you rename a variable in
82+
`api_key_env`, save a key under the new name. The old key stays saved until you
83+
remove it in Keychain Access, Credential Manager, or Seahorse.
84+
85+
`cargo desktop install` never saves, reads, or changes a key, even when your
86+
terminal sets the variable. It checks the config without keys, then lists each
87+
variable that has no saved key. On a first install, the server starts after you
88+
save those keys in **Settings → Server keys** and restart it. In the terminal
89+
app, press `7` to open the Settings page. There `k` lists the variables that the
90+
config names and whether each has a saved key, `s` saves a key, and `i` imports
91+
it from your login shell. Press `b` and then `y` to restart the server.
92+
Uninstalling keeps the saved keys, the config, and history. Switchyard never
93+
writes keys to app settings, service definitions, or logs. Model-list keys that
94+
you enter in Routes are stored separately.
95+
96+
On macOS, Keychain ties each key to the helper that saved it. Keychain treats a
97+
rebuilt helper as a new program, so after `cargo desktop install` macOS may ask
98+
once per key whether to allow `switchyard-desktop-install`. Choose **Always
99+
Allow**.
100+
101+
On Linux, the login keyring must be unlocked. A desktop login normally unlocks
102+
it. When the server service starts after login, it waits up to a minute for the
103+
keyring to unlock. Over SSH without a desktop session, or with a window manager
104+
that does not unlock the keyring, the server does not start and its log says
105+
the keyring is locked.
55106

56107
## Linux Codex Service
57108

@@ -63,13 +114,16 @@ port while the service is stopped and receive your login and prompts.
63114
From a checkout, preview or install the service:
64115

65116
```bash
66-
make install-linux-dry-run
67-
make install-linux
117+
cargo desktop install --dry-run
118+
cargo desktop install
68119
systemctl --user status switchyard
69120
codex -p sy
70121
```
71122

72-
The installer builds and installs `~/.switchyard/bin/switchyard-server`.
123+
The installer builds and installs `~/.switchyard/bin/switchyard-server` and
124+
`~/.switchyard/bin/switchyard-desktop`. Run the same command to reinstall from
125+
the current checkout; update the checkout first to install newer code.
126+
Run `~/.switchyard/bin/switchyard-desktop --tui` to open the terminal app.
73127
It creates `~/.switchyard/composite.toml` if missing and keeps existing edits.
74128
It replaces `~/.config/systemd/user/switchyard.service` and restarts the service.
75129
It writes `~/.codex/sy.config.toml`, backing up a changed profile first.
@@ -79,20 +133,61 @@ The profile format requires [Codex 0.134.0 or newer](https://developers.openai.c
79133
Remove any old `[profiles.sy]` table from `~/.codex/config.toml` before using it.
80134

81135
Set `SY_HOME` or `SY_PORT` to change the server directory or port (default 4123).
82-
`SY_HOME` must not contain whitespace, control characters, or a trailing
83-
backslash; `SY_PORT` must contain only digits. `XDG_CONFIG_HOME` and `CODEX_HOME`
136+
`SY_HOME` must be an absolute UTF-8 path without ASCII control characters.
137+
`SY_PORT` must be a number from 1 to 65535. `XDG_CONFIG_HOME` and `CODEX_HOME`
84138
set the systemd and Codex config directories.
85139

86140
Read server logs with `journalctl --user -u switchyard`. Routing records are
87141
stored in `~/.switchyard/routing.jsonl`. Use `systemctl --user edit switchyard`
88142
for service changes that survive reinstalling.
89143

90-
Remove the service and profile with `make uninstall-linux`. This also removes
144+
Remove the service and profile with `cargo desktop uninstall`. This also removes
91145
marked Codex aliases left by older installs from existing `.bashrc` and
92146
`.zshrc` files. If upgrading an older install, uninstall first and run
93147
`unalias codex` in any open shell. The server directory, routing records,
94-
profile backups, and systemd drop-in files stay in place. Use the same path
95-
overrides when installing and uninstalling.
148+
profile backups, and systemd drop-in files stay in place. Uninstall uses the
149+
recorded installation. Conflicting environment overrides require
150+
`cargo desktop uninstall --settings FILE` to select it explicitly.
151+
152+
## Windows Desktop App
153+
154+
From PowerShell in the repository, run:
155+
156+
```powershell
157+
cargo desktop install --dry-run
158+
cargo desktop install
159+
```
160+
161+
Windows needs the Rust MSVC toolchain, Visual Studio C++ build tools, and
162+
[WebView2](https://v2.tauri.app/start/prerequisites/#windows).
163+
The installer uses Task Scheduler for the current logged-in user. It installs
164+
executables in `%LOCALAPPDATA%\Programs\Switchyard`, falling back to
165+
`%USERPROFILE%\AppData\Local\Programs\Switchyard` when `LOCALAPPDATA` is unset.
166+
It saves that location and adds a Start menu shortcut. Two independent tasks
167+
start the server and desktop app after login with ordinary user privileges.
168+
Quitting the app leaves the server running.
169+
170+
Run `cargo desktop install` again to build and install the current checkout.
171+
This Cargo command waits for installation to finish. The app's source update
172+
uses the saved checkout and runs from a temporary Rust executable so Windows
173+
can release and replace the installed files; read `SY_HOME\logs\update.log` for
174+
its progress and errors. The installed installer cannot install, update, or
175+
uninstall its own installation, because Windows keeps a running program from
176+
being replaced. Use `cargo desktop` from the source checkout instead.
177+
The installer builds and validates before stopping the tasks. If a binary
178+
replacement fails, it tries to restore the previous binaries. If restoration
179+
also fails, the error names the directory containing recovery files.
180+
Rerun installation if a later task or settings operation fails; the complete
181+
installation is not one transaction.
182+
183+
Settings, server config, accounts, and routing history stay in
184+
`%USERPROFILE%\.switchyard` unless `SY_HOME` changes the directory. Server and app
185+
logs are in `SY_HOME\logs`. Model-list keys entered in Routes are saved in the
186+
current user's Windows Credential Manager. Coding tools keep their own login files.
187+
188+
Use `cargo desktop uninstall` to stop and remove both tasks, the shortcut, and
189+
the installed executables. Uninstall preserves settings, accounts, and history,
190+
and makes a recovery copy of the Codex profile before removing it.
96191

97192
## Rust Libraries
98193

@@ -123,3 +218,6 @@ uv run pytest tests/ -v
123218

124219
The `dev` dependency group contains testing and linting tools and is not exposed
125220
in the published wheel metadata.
221+
222+
See the [desktop and terminal quickstart](crates/switchyard-desktop/README.md) for
223+
first-run setup, reviewed settings changes, usage, recovery, and safe uninstall.

‎Makefile‎

Lines changed: 0 additions & 37 deletions
This file was deleted.

‎README.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ LiteLLM and NeMo Relay run in your own deployment. Follow each gateway's guidanc
5656

5757
[Try routing locally](docs/getting_started.md#server-path) with the standalone proxy for demos and evaluation, then [verify routing is active](docs/getting_started.md#verify-routing-is-active).
5858

59+
The [desktop and terminal quickstart](crates/switchyard-desktop/README.md) covers
60+
local installation, coding-tool connections, sessions, usage, recovery, and uninstall.
61+
5962
Agent-specific guides are available for [pi](docs/integrations/pi.md) and
6063
[Oh My Pi](docs/integrations/oh_my_pi.md).
6164

@@ -80,7 +83,7 @@ Features and integrations recently merged into `main`.
8083
Select models in Node.js or try automatic routing through Pi’s virtual models. [TypeScript bindings →](bindings/typescript/README.md) · [Pi example →](examples/pi/README.md)
8184

8285
- **2026-10-08 · Run Codex with Switchyard on macOS**\
83-
Install a background router and Codex profile, then track usage and estimated savings from the menu bar. [Setup guide →](crates/switchyard-menubar/README.md)
86+
Install a background router and Codex profile, then track usage and estimated savings in the desktop app. [Setup guide →](crates/switchyard-desktop/README.md)
8487

8588
## Routing algorithms
8689

‎crates/switchyard-desktop/src/gui.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ pub fn run(controller: Controller, settings: PathBuf) -> Result<(), String> {
662662
_ => {}
663663
})
664664
.build(app)?;
665-
// Like the menu bar app, the tray rereads usage on the settings interval.
665+
// Like the earlier menu bar app, the tray rereads usage on the settings interval.
666666
let handle = app.handle().clone();
667667
std::thread::spawn(move || {
668668
loop {

‎crates/switchyard-menubar/Cargo.toml‎

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)