Updates
How Daintree updates itself: the update flow and its toasts, the stable and nightly channels, manual checks, when auto-update is off, what happens when an install fails, and agent CLI updates.
App Updates
Daintree uses electron-updater to fetch and stage its own updates. Two release channels serve the same flow; only the feed differs.
Update Flow
- Check. Daintree checks shortly after launch, then every 4 hours. The launch check is jittered across a 60-second window so a fleet of machines restarting together doesn't stampede the feed.
- Download. A found update downloads in the background automatically.
- Notify. An in-app toast reports the download and then the ready-to-install state.
- Install. The staged update installs when you quit, or immediately if you use Restart to Install Update.
Transient network failures retry on a bounded backoff (roughly 30 seconds, 2 minutes, then 8 minutes, each with jitter) rather than waiting out the 4-hour tick. Permanent failures (certificate problems, a feed that answers with an error) surface right away instead of retrying.
The Toasts and the 24-Hour Cooldown
The Update available toast appears when a new version is found and starts downloading. Close it explicitly and Daintree won't raise that version's available-toast again for 24 hours, across restarts.
The cooldown is narrower than it sounds, which is deliberate:
- It arms only when you close the toast yourself. A toast evicted because too many notifications stacked up, or dismissed programmatically, doesn't arm it.
- A newer version bypasses it, so a follow-up release is never silently swallowed.
- A manual check always bypasses it.
- Dismissing the Update ready toast never arms it: that stage is about an install you have already paid for, and suppressing it would strand a staged build.
Once the download finishes, the toast becomes Update ready with two actions: Restart to update, the one load-bearing decision, and a secondary View release notes link that opens that version's release page on GitHub. If a newer download starts while a ready-toast is still on screen, both actions are cleared so you can't restart into a build that's already been superseded.
For how these toasts sit alongside everything else Daintree notifies you about, see Notifications and Sound.
Update Channels
Two channels, both served from updates.daintree.org. Stable is the default.
| Channel | Feed URL | QA |
|---|---|---|
| Stable | https://updates.daintree.org/releases/ | Full QA |
| Nightly | https://updates.daintree.org/nightly/ | Pre-release; skips manual QA |
Nightly versions encode the build timestamp and the commit, for example 0.33.0-nightly.20260814021530.abc1234f. Nightly artifacts are pruned from the feed after 3 days. That only affects what's downloadable: a client already running a nightly keeps its build and simply sees no newer one until the next publish.
Switching Channels
Open Settings → General → Overview → Update channel, and pick Stable or Nightly. The change takes effect immediately; no restart, and your settings and data are untouched. The next check, automatic or manual, pulls from the new feed.
Below the buttons, a Last checked line shows how long ago a check ran and refreshes about once a minute.
If Daintree can't read your current channel it shows a "Couldn't load the update channel" banner with a Retry button rather than defaulting the selector to Stable. Quietly falling back would show a nightly user "stable" as though it were authoritative, which is worse than an honest error.
Checking for Updates Manually
The menu item appears in packaged builds only. It won't be there when you run from source.
Open the Daintree menu at the top-left of the screen and click Check for Updates…
Open the Help menu and click Check for Updates…
Open the Help menu and click Check for Updates…
The item relabels itself to match the state of the updater:
| Label | State |
|---|---|
| Check for Updates… | Idle. Click to check. |
| Checking… | A check is in flight. The item is disabled. It only appears if the check runs longer than 400 ms, so a fast round-trip never flickers the label. |
| Restart to Install Update | A build is downloaded and staged. Click to install and relaunch. |
If you're already current, a toast reads No updates available and names your version, for example "Daintree 0.32.0 is the latest version." A failed manual check raises an Update failed toast with a Retry action.
What Happens at Install Time
Installing an update is a shutdown, so it runs through Daintree's graceful-shutdown coordinator rather than terminating the process directly. Session journaling, database checkpoints, and audit-log flushes all complete before the installer takes over. If the coordinator declines the shutdown (because something is genuinely mid-flight), the install rolls back cleanly and the app keeps running.
After the handoff, a 5-second watchdog checks whether the process actually exited. If it hasn't, the install failed to end it and nothing else will, so Daintree force-exits. This is armed on every platform: on macOS the Squirrel installer can fail to acquire its staging lock, and on Windows and Linux a failed install simply returns without quitting. By that point the database is closed and the terminals are torn down, so a process that stays alive is a zombie, not a working app.
When Auto-Update Is Disabled
Daintree turns its updater off entirely in these cases:
- Development and unpackaged builds.
- Windows Store builds (
.appx). The Store owns installs on that channel. Regular NSIS installer builds are unaffected. - Flatpak and Snap on Linux. Both sandboxes manage their own package updates.
- Linux without an AppImage or package marker. Auto-update needs either the
APPIMAGEenvironment variable (set automatically for AppImage builds) or a non-emptypackage-typemarker file in the resources directory (present in.debpackages). - Local
--dirpackages, which ship without theapp-update.ymlthat electron-updater needs. Wiring the updater anyway would only produce an unhandled rejection on the first check.
On a Windows Store build, Settings replaces the channel selector with an Updates section reading "Updates are managed by the Microsoft Store on Windows," plus a single toggle for whether to be notified when a new version is available. With it on, Daintree polls the release manifest every 8 hours and, when it finds a newer version, raises a notification that deep-links straight to Daintree's Store page (falling back to the Store's downloads-and-updates page if the product ID isn't available).
When an Update Fails to Install
An update that downloads but never lands used to be invisible: you would restart, still be on the old version, and have nothing to tell you why. Daintree now records the version it expected to install, along with how far the install attempt got, and compares that against the running version on the next boot.
On a mismatch, a toast appears:
Update didn't install: Daintree 0.33.0 was downloaded but couldn't be installed, so you're still on 0.32.0. Reinstalling from a fresh download will get you onto the latest version.
The action is Download manually, which opens the download page. The advice is deliberate rather than lazy: on macOS, Squirrel validates a staged bundle against a code requirement derived from the running app, so an installation that has been replaced by an unsigned or ad-hoc local build can never accept a signed update no matter how many times it retries. A fresh download is the only way out.
The prompt only fires when an install was actually attempted. A version marker left behind by an app that was killed before it could install anything is ambiguous (the staged installer is probably fine), so that case is recorded for telemetry and nothing is shown. Windows Store builds are excluded, because a daintree.org download is the wrong recovery there.
Canopy Legacy Builds
Early releases shipped a Canopy-branded variant that pulled updates from updates.canopyide.com. That variant was retired at v0.9.0. Everything now runs as Daintree and updates from updates.daintree.org.
Agent CLI Updates
Agent CLIs are ordinary command-line tools you installed yourself, and they update through their own package managers. Daintree doesn't bundle or version them; it detects what's on your PATH and reads the version.
Every built-in agent carries its own update command. Daintree picks one by walking a fixed priority ladder over whatever the agent declares: npm, brew, curl, powershell, pip, pipx, pypi, cargo, go. Most agents declare one or two.
| Agent | Update command |
|---|---|
| Claude Code | npm install -g @anthropic-ai/claude-code@latest |
| OpenCode | npm install -g opencode-ai@latest, or brew upgrade opencode |
| Aider | python -m pip install --upgrade aider-chat, or brew upgrade aider |
| Codex CLI | npm install -g @openai/codex@latest |
| Cursor | curl https://cursor.com/install -fsS | bash |
| GitHub Copilot CLI | npm install -g @github/copilot@latest |
| Goose | brew upgrade block-goose-cli |
| Amp | npm install -g @ampcode/cli@latest, or the ampcode.com install script |
| Crush | brew upgrade crush, or go install github.com/charmbracelet/crush@latest |
| Qwen Code | npm install -g @qwen-code/qwen-code@latest |
| Kimi CLI | uv tool install kimi-cli --upgrade |
| Open Interpreter | pipx upgrade open-interpreter, or pip install --upgrade open-interpreter |
| Mistral Vibe | uv tool upgrade mistral-vibe, or the mistral.ai install script |
| Kiro | curl -fsSL https://cli.kiro.dev/install | bash |
| Gemini CLI | npm install -g @google/gemini-cli@latest (deprecated, see below) |
| Grok | Self-updating: run grok update. Daintree doesn't drive it. |
| Antigravity | No update command is declared; reinstall with its own installer. |
Version Checking
Daintree reads the installed version of each detected CLI and shows it in that agent's settings tab, so you can tell at a glance whether what's on your PATH is what you think it is.