Desktop app
The desktop build is a Tauri 2 shell: a Rust process owns the window, tray and updater, starts the packaged backend as a sidecar, and renders the frontend in a WebView.
Installation
| Channel | Artifact | Dependency |
|---|---|---|
fat | Hetu_x.y.z_x64-setup.exe / .msi | None (bundles the .NET runtime) |
slim | Hetu.Slim._x.y.z_x64-setup.exe / .msi | Requires the .NET 10 runtime |
| Linux | .AppImage / .deb | AppImage needs no installation |
Auto-update
- Endpoint order: GitHub primary, then three mirrors (
ghproxy.net/gh-proxy.com/ghfast.top). - Each channel has its own manifest:
latest.json(fat) andlatest-slim.json(slim); they never overwrite each other. - Installers are signed; a signature mismatch aborts the install. Install mode is
passive. - An update badge appears next to the version; opening it shows the release notes.
Installers embed a preinstall hook that terminates leftover backend processes (
taskkill /F /IM Hetu.Api.exe) before overwriting files, so a locked sqlite-vec\vec0.dll can no longer break an upgrade.Tray and process lifecycle
| Behaviour | Details |
|---|---|
| Close window | Minimizes to the tray by default; the backend keeps running so background jobs continue. Disable in Settings → App |
| Quit | Tray menu “Quit Hetu” terminates the backend child process first |
| Hard kill | The backend remembers the shell PID (HETU_PARENT_PID); if the shell disappears it exits by itself, leaving no orphan holding the port |
| Dev reuse | In development, if HETU_API_DEV_PORT already has a backend, the shell reuses it |
Install and data directories
| Path (Windows example) | Content |
|---|---|
<install>\Hetu (Slim).exe | Shell executable (the fat channel ships Hetu.exe) |
<install>\Hetu.Api.exe | Backend sidecar — the install hook makes sure it is not running |
<install>\wwwroot\ | Frontend assets served by the backend |
<install>\sqlite-vec\vec0.dll | SQLite vector extension (locked by a leftover backend when installs fail) |
%LOCALAPPDATA%\Hetu\hetu.db | Database (plus -wal / -shm) |
%LOCALAPPDATA%\Hetu\logs\ | Logs |
Install hook
src-tauri/nsis-hooks.nsh runs before files are copied (NSIS_HOOK_PREINSTALL):
!macro NSIS_HOOK_PREINSTALL
DetailPrint "Stopping leftover Hetu backend..."
nsExec::Exec '"$SYSDIR\taskkill.exe" /F /IM Hetu.Api.exe /T'
Pop $0
Sleep 500
!macroendWorktree root and cleanup
| Item | Default / options |
|---|---|
| Root | .hetu-worktrees/<repo>/<worktree> next to the repository |
| Custom root | Settings → Workspace: absolute path, validated to be outside every repository |
| Cleanup criteria | Changes merged (or remote branch deleted) + clean working tree + idle past the threshold |
| Interval | 1 / 6 / 12 / 24 hours, or automatic cleanup off |
| Branch deletion | Off by default (directory only); can be enabled |
| Manual run | “Clean now” in settings returns checked / removed / kept counts |
Data location
The shell passes the data directory to the backend via HETU_DATA_DIR: on Windows that is %LOCALAPPDATA%\Hetu (hetu.db plus WAL, and logs/). Copy that directory to migrate machines.
Packaging it yourself
# 1) build the backend sidecar (fat or slim)
pwsh ./scripts/publish-backend.ps1 -Mode SelfContained -Rid win-x64
pwsh ./scripts/publish-backend.ps1 -Mode FrameworkDependent -Rid win-x64
# 2) build the installer
cd shell/hetu-desktop
npm run tauri:build # fat
npm run tauri:build -- --config src-tauri/tauri.slim.conf.json # slimSidecar naming must follow the Tauri convention: binaries/Hetu.Api-<rust-target-triple>(.exe).
Troubleshooting
| Symptom | Fix |
|---|---|
Error opening file for writing during install | A leftover backend holds the file: end all Hetu.Api.exe in Task Manager and retry. Newer installers handle this automatically |
Could not fetch a valid release JSON | The manifest could not be fetched. Open releases/latest/download/latest.json (slim: latest-slim.json) in a browser to confirm, then upgrade to the latest build |
| Window is gone but the app still runs | Click the tray icon to restore it; the backend intentionally keeps running |