Adom Bridge
Public Made by Adomby adom
Adom Bridge unleashes your AI onto your full PC: full power, full safety. The AI breaks out of the container it runs in and onto your real machine, managing and running your entire laptop as you: launch apps, move files, drive any window, control KiCad, Fusion 360 or your real signed-in browser. Works with any AI, cloud or local (Claude Desktop, Claude Code, Codex), no Hydrogen required. Bridge and its bridges are an operating system for AI, with managed Node and Python runtimes, and a human-onl
name: adom-desktop-installer description: How to invoke the Adom Desktop NSIS installer from a parent installer (especially Adom Hydrogen's setup steps) — silent install, /NOLAUNCH switch for HD-managed bundling, live progress via the structured log file at %TEMP%\adom-desktop-install.log. Use when bundling AD inside another Windows installer, writing an install supervisor / setup-step UI, detecting AD's installed version, or upgrading an existing AD install programmatically.
Adom Desktop installer integration
Adom Desktop (AD) ships as a single NSIS installer:
Adom Desktop_<version>_x64-setup.exe (~4.8 MB on v1.8.45)
It installs to %LOCALAPPDATA%\Adom Desktop\ — no UAC prompt, no admin needed. Tauri-2 bundled NSIS with our customisations in src-tauri/installer-hooks.nsh.
Command-line surface
| Flag | Meaning |
|---|---|
| (none) | Installs silently, auto-launches adom-desktop.exe after install |
/S |
Standard NSIS silent flag — same behavior since the top-level SilentInstall silent directive already suppresses UI |
/NOLAUNCH |
v1.8.45+ — install silently, do NOT auto-launch after install. Caller is responsible for spawning AD with the desired flags |
/D=<path> |
Install destination override. Default is $LOCALAPPDATA\Adom Desktop. Rarely needed |
<uninstall.exe> /S |
Silent uninstall. The uninstaller lives at %LOCALAPPDATA%\Adom Desktop\uninstall.exe |
UI behavior: zero UI in all cases. SilentInstall silent is set at the top of the NSIS script, so even setup.exe invoked from Explorer runs without a window. No Welcome page, no progress bar, no Finish page.
Auto-launch: by default the installer calls ExecShell "" "$INSTDIR\adom-desktop.exe" at the end of POSTINSTALL. Pass /NOLAUNCH to suppress this. Used by Hydrogen when bundling AD because Hydrogen wants to spawn AD with --embedded --start-hidden --relay-url ... --session-token ... itself, not let AD launch standalone first and get respawned via single-instance.
Live progress log
The installer writes structured progress to %TEMP%\adom-desktop-install.log (Windows expands %TEMP% to the user's temp dir, typically C:\Users\<name>\AppData\Local\Temp). Each line is [STAGE] message\r\n:
[START] adom-desktop installer 1.8.45 starting
[PREINSTALL] Cleaning legacy desktop shortcuts
[PREINSTALL] Done. Tauri will now copy bundle files.
[POSTINSTALL] Bundle files copied. Cleaning Tauri's auto-created desktop shortcut.
[POSTINSTALL] /NOLAUNCH passed — skipping auto-launch (caller will spawn)
[DONE] adom-desktop installer complete (no-launch mode)
[START] opens with a truncated write (fresh log per install). [DONE] is always the final line — readers tailing the file can use that as the completion sentinel without needing to wait for the process exit.
Stage tags currently emitted:
[START]— once, at the top[PREINSTALL]— Tauri's beforeBuildCommand hook ran, files about to be copied[POSTINSTALL]— files copied; Tauri's standard shortcuts created and our hook is cleaning the unwanted ones[DONE]— final line, installer about to exit
The uninstaller writes the same log with [PREUNINSTALL] / [POSTUNINSTALL] stages.
Recipe: Hydrogen's setup-step UI tails the log
Spawn the installer with /NOLAUNCH, poll the log file on a 200 ms timer, surface each new line to Hydrogen's UI. When [DONE] shows up OR the process exits, the install is complete.
Rust (Hydrogen's installer driver)
use std::{env, fs, path::PathBuf, process::Command, time::Duration};
use std::os::windows::process::CommandExt;
use tokio::time::sleep;
const CREATE_NO_WINDOW: u32 = 0x08000000;
async fn install_adom_desktop<F: FnMut(String)>(
installer_path: &str,
mut on_line: F,
) -> Result<(), String> {
let log_path: PathBuf = [&env::var("TEMP").map_err(|e| e.to_string())?, "adom-desktop-install.log"]
.iter()
.collect();
// Pre-clear so we don't read stale lines from a previous install.
let _ = fs::remove_file(&log_path);
let mut child = Command::new(installer_path)
.args(["/S", "/NOLAUNCH"])
.creation_flags(CREATE_NO_WINDOW)
.spawn()
.map_err(|e| format!("spawn installer: {e}"))?;
let mut last_pos = 0usize;
loop {
// Tail any new content
if let Ok(content) = fs::read_to_string(&log_path) {
if content.len() > last_pos {
let slice = &content[last_pos..];
if let Some(last_nl) = slice.rfind('\n') {
let consumed = &slice[..=last_nl];
for line in consumed.lines() {
on_line(line.to_string());
if line.starts_with("[DONE]") {
// Don't return yet — wait for process exit
// so we surface the actual exit code, but
// we know progress streaming is finished.
}
}
last_pos += consumed.len();
}
}
}
// Check if installer has exited
if let Some(status) = child.try_wait().map_err(|e| e.to_string())? {
return if status.success() {
Ok(())
} else {
Err(format!("installer exited with {}", status))
};
}
sleep(Duration::from_millis(200)).await;
}
}
// Caller:
// install_adom_desktop(r"C:\path\to\Adom Desktop_1.8.45_x64-setup.exe", |line| {
// hd_setup_step.append_live_output(&line);
// }).await?;
Bash (debugging / scripting)
# Pre-clear stale log
rm -f "$TEMP/adom-desktop-install.log" 2>/dev/null
# Spawn installer in background, tail the log
"./Adom Desktop_1.8.45_x64-setup.exe" /S /NOLAUNCH &
INSTALLER_PID=$!
# Tail until process exits OR [DONE] appears
while kill -0 $INSTALLER_PID 2>/dev/null; do
[ -f "$TEMP/adom-desktop-install.log" ] && tail -F "$TEMP/adom-desktop-install.log" &
sleep 0.2
done
wait
echo "Installer exited"
Recipe: detect if AD is already installed (and at what version)
AD writes its uninstall info to the Windows registry under HKCU (current-user install, no admin needed):
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\AdomDesktop
DisplayName = "Adom Desktop"
DisplayVersion = "1.8.45"
InstallLocation = "C:\Users\<name>\AppData\Local\Adom Desktop"
UninstallString = "C:\Users\<name>\AppData\Local\Adom Desktop\uninstall.exe"
Publisher = "Adom Industries, Inc."
use winreg::enums::HKEY_CURRENT_USER;
use winreg::RegKey;
fn adom_desktop_installed_version() -> Option<String> {
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let key = hkcu
.open_subkey(r"Software\Microsoft\Windows\CurrentVersion\Uninstall\AdomDesktop")
.ok()?;
key.get_value("DisplayVersion").ok()
}
Compare with semver::Version::parse to decide whether to skip / upgrade / leave-alone.
Recipe: Hydrogen's setup-step ladder for embedding AD
The full pattern Hydrogen's setup-step UI runs when embedding AD:
1. Check installed version → registry read above
2. Decide:
no install → install bundled AD
older than bundled → install bundled AD (upgrade)
same or newer → skip install entirely
3. Run installer (silent + /NOLAUNCH) → tail log, surface to UI
4. Write embedded marker file → %LOCALAPPDATA%\Adom Desktop\embedded.json
5. Delete AD's user-facing shortcuts → Start Menu, Desktop, Startup folder
(so user can't double-launch standalone)
6. Spawn AD with embedded flags → adom-desktop.exe --embedded
--start-hidden
--relay-url ws://127.0.0.1:8765
--relay-name adom-hydrogen
--session-token <hydrogen's token>
7. Poll AD's direct API for liveness → GET http://127.0.0.1:47200/health
Steps 4 and 5 are also covered by AD's installer if you pass --embedded at AD's first launch (the embedded-mode detection writes the marker and AD's autostart-upgrade routine handles its own shortcuts). Doing them in Hydrogen's installer is belt-and-suspenders.
Bundle-resource pattern
Hydrogen's tauri.conf.json should include the AD installer as a bundle resource so it ships inside Hydrogen's NSIS installer:
"bundle": {
"resources": {
"resources/Adom Desktop_1.8.45_x64-setup.exe": "resources/"
}
}
At runtime Hydrogen finds it under its install dir at $INSTDIR\resources\Adom Desktop_<ver>_x64-setup.exe — pass that path to the install function above.
Versioning + upgrade strategy
| Scenario | What Hydrogen's installer should do |
|---|---|
| No AD installed | Install bundled version |
| AD older than bundled | Install bundled version (upgrade) |
| AD same as bundled | Skip install step; still spawn with embedded flags |
| AD newer than bundled | Skip install step; spawn with embedded flags. Don't downgrade — embedded mode works for any AD ≥ v1.8.42 |
The bundled AD installer is the minimum supported version for the Hydrogen release. Hydrogen can spawn newer ADs without modification.
Exit codes
NSIS returns:
0— install succeeded2— user cancelled (won't happen withSilentInstall silentsince there's no UI to cancel)- Other — install error (rare with our hooks; typical cause is disk full or
%LOCALAPPDATA%not writable)
Treat anything non-zero as a hard failure and surface the log file's last 20 lines to the user.
Where the installer lives
Public download (the user's wiki, which is what end users hit):
https://wiki.adom.inc/static/apps/adom-desktop/Adom%20Desktop_<version>_x64-setup.exe
The wiki page's metadata.install.windows_installer field points at the canonical filename for the current published version. Hydrogen's release build can fetch the latest via:
curl -fL https://wiki.adom.inc/static/apps/adom-desktop/version.json | jq -r .windows.installer_filename
# → "Adom Desktop_1.8.45_x64-setup.exe"
curl -fL "https://wiki.adom.inc/static/apps/adom-desktop/$FILENAME" -o resources/ad-setup.exe
version.json also carries the SHA256 hash of the installer so Hydrogen's build pipeline can verify the download before bundling.
---
name: adom-desktop-installer
description: How to invoke the Adom Desktop NSIS installer from a parent installer (especially Adom Hydrogen's setup steps) — silent install, /NOLAUNCH switch for HD-managed bundling, live progress via the structured log file at %TEMP%\adom-desktop-install.log. Use when bundling AD inside another Windows installer, writing an install supervisor / setup-step UI, detecting AD's installed version, or upgrading an existing AD install programmatically.
---
# Adom Desktop installer integration
Adom Desktop (AD) ships as a single NSIS installer:
```
Adom Desktop_<version>_x64-setup.exe (~4.8 MB on v1.8.45)
```
It installs to `%LOCALAPPDATA%\Adom Desktop\` — no UAC prompt, no admin needed. Tauri-2 bundled NSIS with our customisations in `src-tauri/installer-hooks.nsh`.
## Command-line surface
| Flag | Meaning |
|---|---|
| (none) | Installs silently, auto-launches `adom-desktop.exe` after install |
| `/S` | Standard NSIS silent flag — same behavior since the top-level `SilentInstall silent` directive already suppresses UI |
| `/NOLAUNCH` | **v1.8.45+** — install silently, do NOT auto-launch after install. Caller is responsible for spawning AD with the desired flags |
| `/D=<path>` | Install destination override. Default is `$LOCALAPPDATA\Adom Desktop`. Rarely needed |
| `<uninstall.exe> /S` | Silent uninstall. The uninstaller lives at `%LOCALAPPDATA%\Adom Desktop\uninstall.exe` |
**UI behavior**: zero UI in all cases. `SilentInstall silent` is set at the top of the NSIS script, so even `setup.exe` invoked from Explorer runs without a window. No Welcome page, no progress bar, no Finish page.
**Auto-launch**: by default the installer calls `ExecShell "" "$INSTDIR\adom-desktop.exe"` at the end of POSTINSTALL. Pass `/NOLAUNCH` to suppress this. Used by Hydrogen when bundling AD because Hydrogen wants to spawn AD with `--embedded --start-hidden --relay-url ... --session-token ...` itself, not let AD launch standalone first and get respawned via single-instance.
## Live progress log
The installer writes structured progress to `%TEMP%\adom-desktop-install.log` (Windows expands `%TEMP%` to the user's temp dir, typically `C:\Users\<name>\AppData\Local\Temp`). Each line is `[STAGE] message\r\n`:
```
[START] adom-desktop installer 1.8.45 starting
[PREINSTALL] Cleaning legacy desktop shortcuts
[PREINSTALL] Done. Tauri will now copy bundle files.
[POSTINSTALL] Bundle files copied. Cleaning Tauri's auto-created desktop shortcut.
[POSTINSTALL] /NOLAUNCH passed — skipping auto-launch (caller will spawn)
[DONE] adom-desktop installer complete (no-launch mode)
```
**`[START]`** opens with a truncated write (fresh log per install). **`[DONE]`** is always the final line — readers tailing the file can use that as the completion sentinel without needing to wait for the process exit.
Stage tags currently emitted:
- `[START]` — once, at the top
- `[PREINSTALL]` — Tauri's beforeBuildCommand hook ran, files about to be copied
- `[POSTINSTALL]` — files copied; Tauri's standard shortcuts created and our hook is cleaning the unwanted ones
- `[DONE]` — final line, installer about to exit
The uninstaller writes the same log with `[PREUNINSTALL]` / `[POSTUNINSTALL]` stages.
## Recipe: Hydrogen's setup-step UI tails the log
Spawn the installer with `/NOLAUNCH`, poll the log file on a 200 ms timer, surface each new line to Hydrogen's UI. When `[DONE]` shows up OR the process exits, the install is complete.
### Rust (Hydrogen's installer driver)
```rust
use std::{env, fs, path::PathBuf, process::Command, time::Duration};
use std::os::windows::process::CommandExt;
use tokio::time::sleep;
const CREATE_NO_WINDOW: u32 = 0x08000000;
async fn install_adom_desktop<F: FnMut(String)>(
installer_path: &str,
mut on_line: F,
) -> Result<(), String> {
let log_path: PathBuf = [&env::var("TEMP").map_err(|e| e.to_string())?, "adom-desktop-install.log"]
.iter()
.collect();
// Pre-clear so we don't read stale lines from a previous install.
let _ = fs::remove_file(&log_path);
let mut child = Command::new(installer_path)
.args(["/S", "/NOLAUNCH"])
.creation_flags(CREATE_NO_WINDOW)
.spawn()
.map_err(|e| format!("spawn installer: {e}"))?;
let mut last_pos = 0usize;
loop {
// Tail any new content
if let Ok(content) = fs::read_to_string(&log_path) {
if content.len() > last_pos {
let slice = &content[last_pos..];
if let Some(last_nl) = slice.rfind('\n') {
let consumed = &slice[..=last_nl];
for line in consumed.lines() {
on_line(line.to_string());
if line.starts_with("[DONE]") {
// Don't return yet — wait for process exit
// so we surface the actual exit code, but
// we know progress streaming is finished.
}
}
last_pos += consumed.len();
}
}
}
// Check if installer has exited
if let Some(status) = child.try_wait().map_err(|e| e.to_string())? {
return if status.success() {
Ok(())
} else {
Err(format!("installer exited with {}", status))
};
}
sleep(Duration::from_millis(200)).await;
}
}
// Caller:
// install_adom_desktop(r"C:\path\to\Adom Desktop_1.8.45_x64-setup.exe", |line| {
// hd_setup_step.append_live_output(&line);
// }).await?;
```
### Bash (debugging / scripting)
```bash
# Pre-clear stale log
rm -f "$TEMP/adom-desktop-install.log" 2>/dev/null
# Spawn installer in background, tail the log
"./Adom Desktop_1.8.45_x64-setup.exe" /S /NOLAUNCH &
INSTALLER_PID=$!
# Tail until process exits OR [DONE] appears
while kill -0 $INSTALLER_PID 2>/dev/null; do
[ -f "$TEMP/adom-desktop-install.log" ] && tail -F "$TEMP/adom-desktop-install.log" &
sleep 0.2
done
wait
echo "Installer exited"
```
## Recipe: detect if AD is already installed (and at what version)
AD writes its uninstall info to the Windows registry under `HKCU` (current-user install, no admin needed):
```
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\AdomDesktop
DisplayName = "Adom Desktop"
DisplayVersion = "1.8.45"
InstallLocation = "C:\Users\<name>\AppData\Local\Adom Desktop"
UninstallString = "C:\Users\<name>\AppData\Local\Adom Desktop\uninstall.exe"
Publisher = "Adom Industries, Inc."
```
```rust
use winreg::enums::HKEY_CURRENT_USER;
use winreg::RegKey;
fn adom_desktop_installed_version() -> Option<String> {
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
let key = hkcu
.open_subkey(r"Software\Microsoft\Windows\CurrentVersion\Uninstall\AdomDesktop")
.ok()?;
key.get_value("DisplayVersion").ok()
}
```
Compare with `semver::Version::parse` to decide whether to skip / upgrade / leave-alone.
## Recipe: Hydrogen's setup-step ladder for embedding AD
The full pattern Hydrogen's setup-step UI runs when embedding AD:
```
1. Check installed version → registry read above
2. Decide:
no install → install bundled AD
older than bundled → install bundled AD (upgrade)
same or newer → skip install entirely
3. Run installer (silent + /NOLAUNCH) → tail log, surface to UI
4. Write embedded marker file → %LOCALAPPDATA%\Adom Desktop\embedded.json
5. Delete AD's user-facing shortcuts → Start Menu, Desktop, Startup folder
(so user can't double-launch standalone)
6. Spawn AD with embedded flags → adom-desktop.exe --embedded
--start-hidden
--relay-url ws://127.0.0.1:8765
--relay-name adom-hydrogen
--session-token <hydrogen's token>
7. Poll AD's direct API for liveness → GET http://127.0.0.1:47200/health
```
Steps 4 and 5 are also covered by AD's installer if you pass `--embedded` at AD's first launch (the embedded-mode detection writes the marker and AD's autostart-upgrade routine handles its own shortcuts). Doing them in Hydrogen's installer is belt-and-suspenders.
## Bundle-resource pattern
Hydrogen's `tauri.conf.json` should include the AD installer as a bundle resource so it ships inside Hydrogen's NSIS installer:
```json
"bundle": {
"resources": {
"resources/Adom Desktop_1.8.45_x64-setup.exe": "resources/"
}
}
```
At runtime Hydrogen finds it under its install dir at `$INSTDIR\resources\Adom Desktop_<ver>_x64-setup.exe` — pass that path to the install function above.
## Versioning + upgrade strategy
| Scenario | What Hydrogen's installer should do |
|---|---|
| No AD installed | Install bundled version |
| AD older than bundled | Install bundled version (upgrade) |
| AD same as bundled | Skip install step; still spawn with embedded flags |
| AD newer than bundled | Skip install step; spawn with embedded flags. Don't downgrade — embedded mode works for any AD ≥ v1.8.42 |
The bundled AD installer is the minimum supported version for the Hydrogen release. Hydrogen can spawn newer ADs without modification.
## Exit codes
NSIS returns:
- `0` — install succeeded
- `2` — user cancelled (won't happen with `SilentInstall silent` since there's no UI to cancel)
- Other — install error (rare with our hooks; typical cause is disk full or `%LOCALAPPDATA%` not writable)
Treat anything non-zero as a hard failure and surface the log file's last 20 lines to the user.
## Where the installer lives
Public download (the user's wiki, which is what end users hit):
```
https://wiki.adom.inc/static/apps/adom-desktop/Adom%20Desktop_<version>_x64-setup.exe
```
The wiki page's `metadata.install.windows_installer` field points at the canonical filename for the current published version. Hydrogen's release build can fetch the latest via:
```bash
curl -fL https://wiki.adom.inc/static/apps/adom-desktop/version.json | jq -r .windows.installer_filename
# → "Adom Desktop_1.8.45_x64-setup.exe"
curl -fL "https://wiki.adom.inc/static/apps/adom-desktop/$FILENAME" -o resources/ad-setup.exe
```
`version.json` also carries the SHA256 hash of the installer so Hydrogen's build pipeline can verify the download before bundling.