#!/usr/bin/env bash set -euo pipefail # Build and bundle Clawdis into a minimal .app we can open. # Outputs to dist/Clawdis.app ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" APP_ROOT="$ROOT_DIR/dist/Clawdis.app" BUILD_PATH="$ROOT_DIR/apps/macos/.build" PRODUCT="Clawdis" BUNDLE_ID="${BUNDLE_ID:-com.steipete.clawdis.debug}" PKG_VERSION="$(cd "$ROOT_DIR" && node -p "require('./package.json').version" 2>/dev/null || echo "0.0.0")" BUILD_TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ") GIT_COMMIT=$(cd "$ROOT_DIR" && git rev-parse --short HEAD 2>/dev/null || echo "unknown") APP_VERSION="${APP_VERSION:-$PKG_VERSION}" APP_BUILD="${APP_BUILD:-$PKG_VERSION}" echo "๐Ÿ“ฆ Ensuring deps (pnpm install)" (cd "$ROOT_DIR" && pnpm install --no-frozen-lockfile --config.node-linker=hoisted) echo "๐Ÿ“ฆ Building JS (pnpm exec tsc)" (cd "$ROOT_DIR" && pnpm exec tsc -p tsconfig.json) cd "$ROOT_DIR/apps/macos" echo "๐Ÿ”จ Building $PRODUCT (debug)" swift build -c debug --product "$PRODUCT" --product "${PRODUCT}CLI" --build-path "$BUILD_PATH" BIN="$BUILD_PATH/debug/$PRODUCT" CLI_BIN="$BUILD_PATH/debug/ClawdisCLI" echo "๐Ÿงน Cleaning old app bundle" rm -rf "$APP_ROOT" mkdir -p "$APP_ROOT/Contents/MacOS" mkdir -p "$APP_ROOT/Contents/Resources" mkdir -p "$APP_ROOT/Contents/Resources/Relay" echo "๐Ÿ“„ Writing Info.plist" cat > "$APP_ROOT/Contents/Info.plist" < CFBundleIdentifier ${BUNDLE_ID} CFBundleShortVersionString ${APP_VERSION} CFBundleVersion ${APP_BUILD} CFBundleName Clawdis CFBundleExecutable Clawdis CFBundleIconFile Clawdis CFBundlePackageType APPL LSMinimumSystemVersion 15.0 LSUIElement ClawdisBuildTimestamp ${BUILD_TS} ClawdisGitCommit ${GIT_COMMIT} NSUserNotificationUsageDescription Clawdis needs notification permission to show alerts for agent actions. NSScreenCaptureDescription Clawdis captures the screen when the agent needs screenshots for context. NSMicrophoneUsageDescription Clawdis needs the mic for Voice Wake tests and agent audio capture. NSSpeechRecognitionUsageDescription Clawdis uses speech recognition to detect your Voice Wake trigger phrase. NSAppleEventsUsageDescription Clawdis needs Automation (AppleScript) permission to drive Terminal and other apps for agent actions. PLIST echo "๐Ÿšš Copying binary" cp "$BIN" "$APP_ROOT/Contents/MacOS/Clawdis" chmod +x "$APP_ROOT/Contents/MacOS/Clawdis" echo "๐Ÿ–ผ Copying app icon" cp "$ROOT_DIR/apps/macos/Sources/Clawdis/Resources/Clawdis.icns" "$APP_ROOT/Contents/Resources/Clawdis.icns" echo "๐Ÿ“ฆ Copying WebChat resources" rsync -a "$ROOT_DIR/apps/macos/Sources/Clawdis/Resources/WebChat" "$APP_ROOT/Contents/Resources/" RELAY_DIR="$APP_ROOT/Contents/Resources/Relay" BUN_SRC="${BUN_PATH:-$(command -v bun || true)}" if [ -z "$BUN_SRC" ] || [ ! -x "$BUN_SRC" ]; then echo "bun binary not found (set BUN_PATH to override)" >&2 exit 1 fi echo "๐Ÿงฐ Staging relay runtime (bun + dist + node_modules)" cp "$BUN_SRC" "$RELAY_DIR/bun" chmod +x "$RELAY_DIR/bun" rsync -a --delete --exclude "Clawdis.app" "$ROOT_DIR/dist/" "$RELAY_DIR/dist/" cp "$ROOT_DIR/package.json" "$RELAY_DIR/" cp "$ROOT_DIR/pnpm-lock.yaml" "$RELAY_DIR/" if [ -f "$ROOT_DIR/.npmrc" ]; then cp "$ROOT_DIR/.npmrc" "$RELAY_DIR/" fi echo "๐Ÿ“ฆ Installing prod node_modules into bundle via temp project" TMP_DEPLOY=$(mktemp -d /tmp/clawdis-deps.XXXXXX) cp "$ROOT_DIR/package.json" "$TMP_DEPLOY/" cp "$ROOT_DIR/pnpm-lock.yaml" "$TMP_DEPLOY/" [ -f "$ROOT_DIR/.npmrc" ] && cp "$ROOT_DIR/.npmrc" "$TMP_DEPLOY/" PNPM_STORE_DIR="$TMP_DEPLOY/.pnpm-store" \ PNPM_HOME="$HOME/Library/pnpm" \ pnpm install \ --prod \ --force \ --no-frozen-lockfile \ --ignore-scripts=false \ --config.enable-pre-post-scripts=true \ --config.ignore-workspace-root-check=true \ --config.shared-workspace-lockfile=false \ --lockfile-dir "$ROOT_DIR" \ --dir "$TMP_DEPLOY" rsync -aL "$TMP_DEPLOY/node_modules" "$RELAY_DIR/" rm -rf "$TMP_DEPLOY" if [ -f "$CLI_BIN" ]; then echo "๐Ÿ”ง Copying CLI helper" cp "$CLI_BIN" "$APP_ROOT/Contents/MacOS/ClawdisCLI" chmod +x "$APP_ROOT/Contents/MacOS/ClawdisCLI" fi echo "โน Stopping any running Clawdis" killall -q Clawdis 2>/dev/null || true echo "๐Ÿ” Signing bundle (auto-selects signing identity if SIGN_IDENTITY is unset)" "$ROOT_DIR/scripts/codesign-mac-app.sh" "$APP_ROOT" echo "โœ… Bundle ready at $APP_ROOT"