feat(installer): drive in-app updates through the Tauri installer
Converge update on the same principle as bootstrap: one driver owns all
repo mutation. The desktop becomes a pure consumer that hands off to
Hermes-Setup.exe --update instead of re-implementing git/pip in Electron.
- hermes desktop --build-only: build without launching, so the installer
owns the post-update launch (CLI keeps build logic single-sourced).
- Installer AppMode {Install,Update} from argv; get_mode exposed to the UI.
- Installer self-copies to HERMES_HOME/hermes-setup.exe on install success
(no-op guard during --update re-invocation to avoid the locked-exe copy).
- Installer --update flow (update.rs): wait for the desktop to release the
venv shim, run 'hermes update --yes --gateway' (branch on exit 0/2/other),
then 'hermes desktop --build-only', then launch the rebuilt desktop. Reuses
the bootstrap event channel + progress UI via a synthetic two-stage manifest.
- Desktop applyUpdates() gutted (~105 lines of git/stash/pull/pyproject/pip
removed) -> thin handoff: spawn updater, app.quit() to free the shim.
Detection (checkUpdates, commit changelog, behind-count) kept intact.
- install.ps1 creates Start Menu + Desktop shortcuts to the packed Hermes.exe
(never bare 'hermes desktop', which would rebuild every launch).
This commit is contained in:
@@ -2073,9 +2073,11 @@ function Install-Desktop {
|
||||
"$desktopDir\release\win-arm64-unpacked\Hermes.exe"
|
||||
)
|
||||
$found = $false
|
||||
$desktopExe = $null
|
||||
foreach ($cand in $exeCandidates) {
|
||||
if (Test-Path $cand) {
|
||||
Write-Success "Desktop ready: $cand"
|
||||
$desktopExe = $cand
|
||||
$found = $true
|
||||
break
|
||||
}
|
||||
@@ -2083,6 +2085,49 @@ function Install-Desktop {
|
||||
if (-not $found) {
|
||||
throw "Desktop build completed but no Hermes.exe was found under $desktopDir\release\*-unpacked\"
|
||||
}
|
||||
|
||||
# 4. Create Start Menu + Desktop shortcuts pointing DIRECTLY at the packed
|
||||
# Hermes.exe. We deliberately do NOT point them at `hermes desktop`: that
|
||||
# command rebuilds (npm install + electron-builder) on every launch,
|
||||
# which would cost minutes each time. The packed exe is the consumer —
|
||||
# launching it directly is instant, and updates flow through the
|
||||
# installer's --update path (which rebuilds once, then relaunches).
|
||||
New-DesktopShortcuts -TargetExe $desktopExe
|
||||
}
|
||||
|
||||
function New-DesktopShortcuts {
|
||||
param([Parameter(Mandatory = $true)][string]$TargetExe)
|
||||
|
||||
# Best-effort: a shortcut failure must never fail an otherwise-good install.
|
||||
try {
|
||||
$shell = New-Object -ComObject WScript.Shell
|
||||
$workDir = Split-Path -Parent $TargetExe
|
||||
|
||||
$targets = @(
|
||||
(Join-Path ([Environment]::GetFolderPath('Programs')) 'Hermes.lnk'),
|
||||
(Join-Path ([Environment]::GetFolderPath('Desktop')) 'Hermes.lnk')
|
||||
)
|
||||
|
||||
foreach ($lnkPath in $targets) {
|
||||
try {
|
||||
$parent = Split-Path -Parent $lnkPath
|
||||
if (-not (Test-Path $parent)) {
|
||||
New-Item -ItemType Directory -Force -Path $parent | Out-Null
|
||||
}
|
||||
$sc = $shell.CreateShortcut($lnkPath)
|
||||
$sc.TargetPath = $TargetExe
|
||||
$sc.WorkingDirectory = $workDir
|
||||
$sc.IconLocation = "$TargetExe,0"
|
||||
$sc.Description = 'Hermes Agent'
|
||||
$sc.Save()
|
||||
Write-Success "Shortcut created: $lnkPath"
|
||||
} catch {
|
||||
Write-Warn "Could not create shortcut $lnkPath : $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Warn "Skipping shortcut creation: $($_.Exception.Message)"
|
||||
}
|
||||
}
|
||||
|
||||
function Install-PlatformSdks {
|
||||
|
||||
Reference in New Issue
Block a user