2.2 KiB
2.2 KiB
Bundled Bun runtime (mac app only)
Date: 2025-12-07 · Owner: steipete · Scope: packaged mac app runtime
What we ship
- The mac menu-bar app embeds an arm64 Bun runtime under
Contents/Resources/Relay/only for the packaged app. Dev/CI keep using pnpm+node. - Payload:
bunbinary (defaults to/opt/homebrew/bin/bun, override withBUN_PATH=/path/to/bun),dist/output, productionnode_modules/, and the rootpackage.json/pnpm-lock.yamlfor provenance. - We prune dev/build tooling (vite, rolldown, biome, vitest, tsc/tsx, @types, etc.) and drop all non-macOS sharp vendors so only
sharp-darwin-arm64+sharp-libvips-darwin-arm64remain.
Build/packaging flow
- Run
scripts/package-mac-app.sh(orBUN_PATH=/custom/bun scripts/package-mac-app.sh).- Ensures deps via
pnpm install, thenpnpm exec tsc. - Builds the Swift app and stages
dist/, Bun, and productionnode_modulesintoContents/Resources/Relay/using a temp deploy (hoisted layout, no dev deps). - Prunes optional tooling + extra sharp vendors, then codesigns binaries and native addons.
- Ensures deps via
- Architecture: arm64 only. Ship a separate bundle if you need Rosetta/x64.
Runtime behavior
CommandResolverprefers the bundledbun dist/index.js <subcommand>when present; falls back to systemclawdis/pnpm/node otherwise.RelayProcessManagerruns in the bundled cwd/PATH so native deps (sharp, undici) resolve without installing anything on the host.
Testing the bundle
- After packaging:
cd dist/Clawdis.app/Contents/Resources/Relay && ./bun dist/index.js --helpshould print the CLI help without missing-module errors. - If sharp fails to load, confirm the remaining
@img/sharp-darwin-arm64+@img/sharp-libvips-darwin-arm64directories exist and are codesigned.
Notes / limits
- Bundle is mac-app-only; keep using pnpm+node for dev/test.
- Packaging stops early if Bun or
pnpm buildprerequisites are missing.
FAQ
- What does
--legacydo? When used withpnpm deploy,--legacybuilds a classic flattenednode_moduleslayout instead of pnpm's symlinked structure. We no longer need it in the current packaging flow because we create a self-contained hoisted install directly in the temp deploy dir.