mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-10 08:32:09 +00:00
Hermes-Setup.exe is a small signed Rust+Tauri binary that drives
scripts/install.ps1 stage-by-stage with a native UI matching the
desktop's design language. Replaces the chicken-and-egg pattern of
shipping a 200MB Electron app whose first launch existed only to
run install.ps1.
The architecture:
Rust backend (src-tauri/):
bootstrap.rs orchestrator -- Tauri commands, stage iteration
install_script.rs resolve install.ps1 (dev checkout, cache, GitHub raw)
powershell.rs spawn powershell, line-stream stdout/stderr, parse JSON
events.rs BootstrapEvent types -- mirror bootstrap-runner.cjs
paths.rs HERMES_HOME resolution + tracing log setup
build.rs bakes BUILD_PIN_COMMIT / BUILD_PIN_BRANCH from
'git rev-parse HEAD' at compile time
React frontend (src/):
Tauri webview rendering 4 screens (welcome / progress / success /
failure), driven by nanostores subscribing to the Rust event stream.
Visual layer reuses the desktop's styles.css wholesale via @import
so the installer and desktop never drift visually.
Distribution:
targets = ['app', 'dmg', 'appimage'] -- no NSIS/MSI wrapper. The
raw target/release/Hermes-Setup.exe IS the artifact on Windows;
.dmg + .app on macOS; AppImage on Linux. One file, double-click,
no installer-installing-an-installer pattern.
Compile-time pinning:
build.rs reads 'git rev-parse HEAD' and emits
cargo:rustc-env=BUILD_PIN_COMMIT=<sha> + BUILD_PIN_BRANCH=<branch>.
bootstrap.rs's option_env!() picks these up so the binary fetches
install.ps1 from the exact SHA it was tested against. CI / release
builds can override via HERMES_BUILD_PIN_COMMIT env var.
Windows manifest:
hermes-setup.manifest declares level='asInvoker' so the
productName 'Hermes Setup' doesn't trip Windows's installer-
detection heuristic and refuse to launch without elevation.
Also declares PerMonitorV2 DPI + UTF-8 active code page + Common
Controls v6.
Limitations of this initial version:
* No code signing -- Windows SmartScreen will warn once on Hermes-Setup.exe
('More info -> Run anyway'). The downstream binaries it produces
(Hermes.exe in win-unpacked/, the hermes CLI) are locally-built and
therefore don't carry MOTW, so they launch without SmartScreen
intervention. Cert procurement tracked separately.
* macOS and Linux build paths defined but untested -- Windows-only V1.
51 lines
1.9 KiB
CSS
51 lines
1.9 KiB
CSS
/*
|
|
* Hermes Setup — defer entirely to the desktop's styles.css.
|
|
*
|
|
* Rather than re-implement the Hermes design system (and inevitably drift
|
|
* from it), we import apps/desktop/src/styles.css wholesale. The desktop
|
|
* is the canonical source of truth for fonts, color tokens, button chrome,
|
|
* scrollbars, layout utilities, and animations. Any change to the
|
|
* Hermes look propagates here automatically with no copy-paste maintenance.
|
|
*
|
|
* Path resolution caveats:
|
|
* - Tailwind v4's `@import` resolves relative to this file. The desktop's
|
|
* `@source '../../../node_modules/...'` declarations therefore re-resolve
|
|
* against apps/bootstrap-installer/src/. Since both apps live two levels
|
|
* deep under the same repo root, `../../../node_modules` lands in the
|
|
* same place. (Verify if either app ever moves.)
|
|
* - The desktop's `@font-face url('../../../node_modules/...')` references
|
|
* are baked into the *imported* stylesheet; CSS resolves url()s relative
|
|
* to the file that contains them, so they continue to point at the
|
|
* correct node_modules path even from here.
|
|
*
|
|
* Forced light mode: the desktop ships with a runtime theme switcher
|
|
* (ThemeProvider + applyTheme) that can flip to dark via document.documentElement.
|
|
* The installer has no UI for theme switching, so we stay on the desktop's
|
|
* default light surface (Nous-blue accent on near-white chrome).
|
|
*/
|
|
@import '../../desktop/src/styles.css';
|
|
|
|
/* Installer-only additions: a fade-in animation and a warm radial glow
|
|
for the welcome screen. Everything else inherits from the desktop. */
|
|
@keyframes hermes-fade-in {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(4px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.hermes-fade-in {
|
|
animation: hermes-fade-in 0.45s ease-out both;
|
|
}
|
|
|
|
.hermes-glow {
|
|
background: radial-gradient(
|
|
ellipse at center,
|
|
color-mix(in srgb, var(--ui-warm) 18%, transparent) 0%,
|
|
transparent 60%
|
|
);
|
|
}
|