#!/usr/bin/env bash set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" DEST="${1:?Usage: stage-macos-runtime.sh ResourcesDirectory [arm64|amd64|universal]}" ARCH="${2:-$(uname -m)}" [[ "$ARCH" != amd64 ]] || ARCH=x86_64 cd "$ROOT" for file in platform-tools/adb scrcpy/scrcpy-server-v5.0.1 scrcpy/LICENSE.txt ffmpeg/ffmpeg runtime-manifest.json mcp-filesystem/node mcp-filesystem/NODE-LICENSE.txt mcp-filesystem/runtime.json mcp-filesystem/node_modules/@modelcontextprotocol/server-filesystem/dist/index.js mcp-mobile/runtime.json mcp-mobile/node_modules/@mobilenext/mobile-mcp/lib/index.js; do [[ -f "third_party/$file" ]] || { echo "Missing bundled runtime: $file. Run scripts/sync-macos-runtime.sh on the build Mac." >&2; exit 1; } done grep -q '"platform":"darwin"' third_party/runtime-manifest.json || { echo 'Wrong platform runtime; prepare macOS dependencies.' >&2; exit 1; } echo '764eb6f79811d5211fe9df341120882ba9994c7a61b897d7bf3fb662e53bc536 third_party/scrcpy/scrcpy-server-v5.0.1' | shasum -a 256 -c - for tool in third_party/platform-tools/adb third_party/ffmpeg/ffmpeg third_party/ffmpeg/lib/*.dylib third_party/mcp-filesystem/node; do [[ -f "$tool" ]] || continue if [[ "$ARCH" == universal ]]; then lipo -verify_arch arm64 x86_64 "$tool" else lipo -verify_arch "$ARCH" "$tool" fi done mkdir -p "$DEST" DEST="$(cd "$DEST" && pwd)" for folder in platform-tools scrcpy ffmpeg mcp-filesystem mcp-mobile; do mkdir -p "$DEST/$folder" rsync -a --delete "third_party/$folder/" "$DEST/$folder/" done cp third_party/runtime-manifest.json third_party/RUNTIME-NOTICES.txt "$DEST/" # Verify with loader environment cleared, so the bundle cannot borrow Homebrew libraries. env -u DYLD_LIBRARY_PATH -u DYLD_FALLBACK_LIBRARY_PATH "$DEST/ffmpeg/ffmpeg" -version >/dev/null env -u NODE_OPTIONS -u NODE_PATH "$DEST/mcp-filesystem/node" --input-type=module -e 'import {pathToFileURL} from "node:url"; if (Number(process.versions.node.split(".")[0]) < 24) process.exit(1); await import(pathToFileURL(process.argv[2]).href)' check-only "$DEST/mcp-filesystem/node_modules/@modelcontextprotocol/server-filesystem/dist/index.js" # The private Node must resolve the pinned server with loader overrides cleared. env -u NODE_OPTIONS -u NODE_PATH "$DEST/mcp-filesystem/node" -e 'require(process.argv[1])' "$DEST/mcp-mobile/node_modules/@mobilenext/mobile-mcp/lib/server.js"