134 lines
4.2 KiB
Markdown
134 lines
4.2 KiB
Markdown
---
|
||
summary: "Bundled bun gateway: packaging, launchd, signing, and bytecode"
|
||
read_when:
|
||
- Packaging Clawdis.app
|
||
- Debugging the bundled gateway binary
|
||
- Changing bun build flags or codesigning
|
||
---
|
||
|
||
# Bundled bun Gateway (macOS)
|
||
|
||
Goal: ship **Clawdis.app** with a self-contained relay binary that can run both the CLI and the Gateway daemon. No global `npm install -g clawdis`, no system Node requirement.
|
||
|
||
## What gets bundled
|
||
|
||
App bundle layout:
|
||
|
||
- `Clawdis.app/Contents/Resources/Relay/clawdis`
|
||
- bun `--compile` relay executable built from `dist/macos/relay.js`
|
||
- Supports:
|
||
- `clawdis …` (CLI)
|
||
- `clawdis gateway-daemon …` (LaunchAgent daemon)
|
||
- `Clawdis.app/Contents/Resources/Relay/package.json`
|
||
- tiny “p runtime compatibility” file (see below)
|
||
- `Clawdis.app/Contents/Resources/Relay/theme/`
|
||
- p TUI theme payload (optional, but strongly recommended)
|
||
|
||
Why the sidecar files matter:
|
||
- The embedded p runtime detects “bun binary mode” and then looks for `package.json` + `theme/` **next to `process.execPath`** (i.e. next to `clawdis`).
|
||
- So even if bun can embed assets, the runtime expects filesystem paths. Keep the sidecar files.
|
||
|
||
## Build pipeline
|
||
|
||
Packaging script:
|
||
- `scripts/package-mac-app.sh`
|
||
|
||
It builds:
|
||
- TS: `pnpm exec tsc`
|
||
- Swift app + helper: `swift build …`
|
||
- bun relay: `bun build dist/macos/relay.js --compile --bytecode …`
|
||
|
||
Important bundler flags:
|
||
- `--compile`: produces a standalone executable
|
||
- `--bytecode`: reduces startup time / parsing overhead (works here)
|
||
- externals:
|
||
- `-e electron`
|
||
- Reason: avoid bundling Electron stubs in the relay binary
|
||
|
||
Version injection:
|
||
- `--define "__CLAWDIS_VERSION__=\"<pkg version>\""`
|
||
- `src/version.ts` also supports `__CLAWDIS_VERSION__` (and `CLAWDIS_BUNDLED_VERSION`) so `--version` doesn’t depend on reading `package.json` at runtime.
|
||
|
||
## Launchd (Gateway as LaunchAgent)
|
||
|
||
Label:
|
||
- `com.steipete.clawdis.gateway`
|
||
|
||
Plist location (per-user):
|
||
- `~/Library/LaunchAgents/com.steipete.clawdis.gateway.plist`
|
||
|
||
Manager:
|
||
- `apps/macos/Sources/Clawdis/GatewayLaunchAgentManager.swift`
|
||
|
||
Behavior:
|
||
- “Clawdis Active” enables/disables the LaunchAgent.
|
||
- App quit does **not** stop the gateway (launchd keeps it alive).
|
||
|
||
Logging:
|
||
- launchd stdout/err: `/tmp/clawdis/clawdis-gateway.log`
|
||
|
||
Default LaunchAgent env:
|
||
- `CLAWDIS_IMAGE_BACKEND=sips` (avoid sharp native addon under bun)
|
||
|
||
## Codesigning (hardened runtime + bun)
|
||
|
||
Symptom (when mis-signed):
|
||
- `Ran out of executable memory …` on launch
|
||
|
||
Fix:
|
||
- The bun executable needs JIT-ish permissions under hardened runtime.
|
||
- `scripts/codesign-mac-app.sh` signs `Relay/clawdis` with:
|
||
- `com.apple.security.cs.allow-jit`
|
||
- `com.apple.security.cs.allow-unsigned-executable-memory`
|
||
|
||
## Image processing under bun
|
||
|
||
Problem:
|
||
- bun can’t load some native Node addons like `sharp` (and we don’t want to ship native addon trees for the gateway).
|
||
|
||
Solution:
|
||
- Central helper `src/media/image-ops.ts`
|
||
- Prefers `/usr/bin/sips` on macOS (esp. when running under bun)
|
||
- Falls back to `sharp` when available (Node/dev)
|
||
- Used by:
|
||
- `src/web/media.ts` (optimize inbound/outbound images)
|
||
- `src/browser/screenshot.ts`
|
||
- `src/agents/pi-tools.ts` (image sanitization)
|
||
|
||
## Browser control server
|
||
|
||
The Gateway starts the browser control server (loopback only) from `src/gateway/server.ts`.
|
||
It’s started from the relay daemon process, so the relay binary includes Playwright deps.
|
||
|
||
## Tests / smoke checks
|
||
|
||
From a packaged app (local build):
|
||
|
||
```bash
|
||
dist/Clawdis.app/Contents/Resources/Relay/clawdis --version
|
||
|
||
CLAWDIS_SKIP_PROVIDERS=1 \
|
||
CLAWDIS_SKIP_CANVAS_HOST=1 \
|
||
dist/Clawdis.app/Contents/Resources/Relay/clawdis gateway-daemon --port 18999 --bind loopback
|
||
```
|
||
|
||
Then, in another shell:
|
||
|
||
```bash
|
||
pnpm -s clawdis gateway call health --url ws://127.0.0.1:18999 --timeout 3000
|
||
```
|
||
|
||
## Repo hygiene
|
||
|
||
Bun may leave dotfiles like `*.bun-build` in the repo root or subfolders.
|
||
- These are ignored via `.gitignore` (`*.bun-build`).
|
||
|
||
## DMG styling (human installer)
|
||
|
||
`scripts/create-dmg.sh` styles the DMG via Finder AppleScript.
|
||
|
||
Rules of thumb:
|
||
- Use a **72dpi** background image that matches the Finder window size in points.
|
||
- Preferred asset: `assets/dmg-background-small.png` (**500×320**).
|
||
- Default icon positions: app `{125,160}`, Applications `{375,160}`.
|