The handshake ran synchronously in Bridge::connect: on a build-id mismatch it
sent Cmd::Shutdown and awaited a reply that never flushes (the daemon exits
first), so request() hit its 5s timeout and the reconnect-retry respawned the
daemon and re-sent Shutdown — a loop that produced repeated 'spaceshd
listening' lines and a multi-second launch delay. The id stamps also differed
between the separately-built daemon and GUI, so it fired on normal launches.
- Remove the handshake auto-restart; `make install`/`reinstall` already kill
and replace the daemon reliably. health.build stays for display in Settings.
- Shutdown now goes through a fire-and-forget send (no reply wait, no retry),
fixing the same loop for the Settings Restart button.
- Makefile: `make app-bundle` builds just the .app via `tauri build --bundles
app` (no .dmg, no hdiutil) and `reinstall` uses it — faster self-update that
can't hang on a mounted DMG volume.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The stale bin/spaceshd-universal-apple-darwin sidecar (left over from an
earlier approach) poisoned the universal bundle — tauri shipped that old
daemon instead of the freshly built one, so the packaged daemon lacked the
TERM fix. dmg/dmg-native now wipe the sidecar dir first. install copies the
native bundle (was preferring the universal one, which could be stale) and
kills the running daemon; reinstall = native rebuild + install for fast
self-updates. Universal stays for distribution via dmg / install-universal.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuilding the .app never replaced the RUNNING daemon (it outlives the GUI),
so a stale spaceshd kept serving old code (e.g. the pre-TERM-fix daemon).
`make install` now stops the daemon, copies the fresh bundle to /Applications,
and clears quarantine; `make reinstall` does dmg+install in one shot.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tauri's universal target builds each arch separately and resolves externalBin
with that arch's triple (spaceshd-aarch64-apple-darwin / -x86_64-apple-darwin),
lipo'ing them itself. The previous single -universal-apple-darwin sidecar made
the per-arch sub-build fail with 'resource path ... doesn't exist'.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tauri build bundled only the GUI binary, so the packaged app had no daemon:
find_daemon() looks for a sibling `spaceshd` next to the GUI
(Contents/MacOS/spaceshd) and ensure_daemon failed to spawn it → "offline".
(Dev worked only because find_daemon falls back to the repo-root target path.)
- tauri.bundle.conf.json: a build-only overlay adding bundle.externalBin
["bin/spaceshd"], kept out of tauri.conf.json so `tauri dev` doesn't require
a sidecar file.
- Makefile: `make dmg` now builds spaceshd for both arches, lipo's a universal
sidecar into src-tauri/bin/spaceshd-universal-apple-darwin, and passes
--config so it lands in Contents/MacOS/spaceshd. `make dmg-native` does the
host-arch equivalent.
- .gitignore: ignore the generated app/src-tauri/bin/.
After install, the unsigned helper runs once quarantine is cleared recursively:
xattr -dr com.apple.quarantine /Applications/spacesh.app
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
No macOS CI runner available, so the universal .dmg is built locally:
`make dmg` (adds the rust targets + tauri build --target universal-apple-darwin).
Also: deps, dmg-native, dev, daemon, test, landing-image/run/push, clean.
`make` / `make help` lists targets.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>