DocsDevelopers
Desktop app and releases
The desktop app is a thin Tauri shell around the same server you can run from source. It ships the studio's code, the setup screens and a copy of uv; PyTorch and the models are downloaded on the person's computer, matched to its hardware.
What the app does#
The app is deliberately small. It carries three things: the setup screens (desktop/installer/, plain HTML, CSS and JavaScript), the studio's code, and uv for the target platform. The Rust shell (desktop/) detects the hardware, runs the installer, and starts and stops the studio server.
| When | What happens |
|---|---|
| First launch | The setup screens check the hardware, ask where models should run, and install the engine with installer/, streaming its progress into the window. Then the studio opens and offers models to download |
| Later launches | A short splash while the server starts, then the studio in the window |
| Closing the app | The server is asked to stop (SIGTERM, or taskkill on Windows), which ejects every model first. After eight seconds it is ended |
| A force quit or crash | The server watches the app's process (BASAL_PARENT_PID) and shuts down cleanly within two seconds of it disappearing |
The server listens on 127.0.0.1 on the port it used last time if that is free, else 8420, else the first free port from 8421 to 8440. The port is remembered in studio-port, because the window's saved state (your draft, the theme, choices already made) belongs to the page's address. The first start can take a while on a cold disk, because the server imports PyTorch; the shell waits up to three minutes and shows the server's log if it does not come up.
On Linux, the AppImage adds itself to the applications menu, as the .deb and .rpm packages do. On macOS, the app offers to move itself into Applications when it runs from elsewhere.
How the engine is bundled#
desktop/ runs before every tauri dev and tauri build. It copies:
basal/,ui/,installer/engine.pyand therequirements*.txtfiles intosrc-tauri/engine/, which the app bundles as a resource;- the brand mark, the Inter font, the icons and the interface's colour tokens into the setup screens, so setup looks like the studio;
- uv for the target platform into
src-, from yourtauri/ binaries/ bud- uv- <target> PATHwhen it matches, otherwise downloaded from uv's latest release.
On the person's computer the code stays inside the app, and only the libraries are installed into the app-data folder (engine-env/). The server runs with the bundled code as its working directory. So installing a new version of the app updates the studio's code at once, while PyTorch, the models, settings and history are kept.
The app removes PYTHONHOME, PYTHONPATH and an AppImage's own library paths from every process it starts, so the engine's Python finds its own standard library. On Linux it also sets WEBKIT_, because WebKitGTK's DMA-BUF renderer draws a blank window on many NVIDIA systems, the GB10 included.
desktop/ installer/ setup screens (HTML, CSS, JS) scripts/stage.mjs copies the engine and uv before a build src-tauri/ src/main.rs detect, install, start and stop the studio tauri.conf.json bundle settings and the version engine/ staged: basal/, ui/, installer/, requirements binaries/ staged: bud-uv-<target>Work on the app#
To work on the app against a checkout, point it at the checkout's code, Python and data with three variables, so nothing is reinstalled. The setup screens can be previewed in any browser by opening desktop/: ?hw=gb10, ?hw=mac, ?hw=intel or ?hw=cpu simulates a computer, and ?installed=1 shows the launch screen.
| Variable | What it does |
|---|---|
BUD_STUDIO_ENGINE |
Run the studio's code from this folder instead of the bundled copy |
BUD_STUDIO_PYTHON |
Use this Python instead of the one in engine-env/ |
BUD_STUDIO_DATA |
Keep the studio's data here instead of the app-data folder |
BUD_STUDIO_DEVICE |
Run setup without questions: cuda, mps, xpu, rocm, cpu or recommended. For managed rollouts and tests |
cd desktopnpm installBUD_STUDIO_ENGINE=$PWD/.. \BUD_STUDIO_PYTHON=$PWD/../.venv/bin/python \BUD_STUDIO_DATA=$PWD/../data \npx tauri devBuild the installers#
npx tauri build builds for the computer you run it on. It needs Rust, Node 18 or newer, and on Linux the WebKitGTK 4.1 development packages.
| Platform | Built on | Files |
|---|---|---|
| macOS, Apple Silicon | macOS | .app, .dmg |
| Windows x64 | Windows | .msi, -setup.exe |
| Linux x64 and ARM64 | Linux | .deb, .rpm, .AppImage |
On Linux, tauri build downloads AppImage tools from GitHub and can time out on a slow connection. Download them once into ~/.cache/tauri/ (AppRun-<arch>, linuxdeploy- and linuxdeploy-), make them executable, and build again.
macOS and Windows builds are not code-signed yet. They work, but the system warns the first time they are opened; the one-line installers avoid the warning.
sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev \ libayatana-appindicator3-dev librsvg2-dev patchelf filecd desktopnpm installnpx tauri buildls src-tauri/target/release/bundle/cd desktopnpm installnpx tauri buildMake a release#
A release is a version bump, a tag, and GitHub Actions. The version appears in five files, plus the two lock files that follow them:
| File | Field |
|---|---|
basal/__init__.py |
__version__, shown by the server and recorded with every decision |
desktop/ |
version, the app's version |
desktop/ |
version |
desktop/package.json |
version |
site/docs-src/nav.py |
VERSION, shown in these docs |
desktop/, desktop/ |
Updated with the two above |
- Test. Run the studio tests, conformance and the end-to-end check (Testing), and update
docs/testing.md. - Bump the version in the files above and commit.
- Tag and push. Pushing a
v*tag startsdesktop.yml, which builds macOS (Apple Silicon), Windows x64, Linux x64 and Linux ARM64 (NVIDIA GB10, DGX Spark) in parallel and attaches every installer to one draft release. - Publish. When all four builds succeed, the workflow publishes the draft and marks it the latest release. The one-line installers,
get.shandget.ps1, always install the latest release. The workflow then writessite/release.jsonand commits it tomain, so the website shows the new release without any edit: its pages read the latest release from GitHub in the browser, from the API and from that file. - Write the notes. Replace the generated text with notes for people: what changed, why it matters, and how to update.
The app does not update itself yet. People update by installing the new version over the old one, or by running the one-line command again; the engine, settings, models, templates and history are kept.
git commit -am "Bud Decision Studio 0.3.0"git tag -a v0.3.0 -m "Bud Decision Studio 0.3.0"git push origin main v0.3.0# after the four builds finishgh release view v0.3.0 --repo BudEcosystem/Bud-Decision-Enginegh release edit v0.3.0 --repo BudEcosystem/Bud-Decision-Engine \ --title "Bud Decision Studio 0.3.0" --notes-file notes.md