Ariver
2026-05-29 f6c42d1a709e55de9895c564401165ca6c2e3f8e
build.sh
@@ -5,12 +5,24 @@
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
BUILD_DIR="$PROJECT_DIR/build"
APP_BUNDLE="$BUILD_DIR/$APP_NAME.app"
APP_INFO_PLIST="$APP_BUNDLE/Contents/Info.plist"
MACOS_DIR="$APP_BUNDLE/Contents/MacOS"
RESOURCES_DIR="$APP_BUNDLE/Contents/Resources"
SWIFT_DIR="$PROJECT_DIR/Apptag"
INFO_PLIST="$SWIFT_DIR/Info.plist"
SDK_PATH=$(xcrun --sdk macosx --show-sdk-path)
TARGET="arm64-apple-macosx15.0"
APP_VERSION=$(/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "$INFO_PLIST")
APP_BUILD="${APP_BUILD:-$(date '+%Y%m%d.%H%M')}"
SOURCE_INFO_PLIST_HASH_BEFORE=$(shasum -a 256 "$INFO_PLIST" | awk '{print $1}')
if [ -z "$APP_VERSION" ] || ! [[ "$APP_BUILD" =~ ^[0-9]{8}\.[0-9]{4}$ ]]; then
    echo "❌ Invalid version metadata in $INFO_PLIST: version='$APP_VERSION' build='$APP_BUILD'"
    exit 1
fi
echo "==> Packaging $APP_NAME $APP_VERSION ($APP_BUILD)"
# --- Optional: App Store / Sandbox signing ---
# Set CODESIGN_IDENTITY to your "Apple Distribution" or "Mac Developer" cert name.
@@ -24,6 +36,10 @@
    if [ -z "$CODESIGN_IDENTITY" ]; then
        echo "⚠️  APP_STORE=1 but CODESIGN_IDENTITY not set. Will ad-hoc sign with entitlements."
    fi
    if [ ! -f "$ENTITLEMENTS" ]; then
        echo "❌ APP_STORE=1 requires entitlements at: $ENTITLEMENTS"
        exit 1
    fi
fi
echo "==> Cleaning..."
@@ -34,18 +50,25 @@
mkdir -p "$RESOURCES_DIR"
echo "==> Compiling Swift files..."
SWIFT_FILES=()
while IFS= read -r file; do
    SWIFT_FILES+=("$file")
done < <(find "$SWIFT_DIR" -name '*.swift' -print | sort)
swiftc \
    -o "$MACOS_DIR/$APP_NAME" \
    -framework AppKit \
    -framework SwiftUI \
    -framework Carbon \
    -framework CoreServices \
    -lcompression \
    -sdk "$SDK_PATH" \
    -target "$TARGET" \
    -Osize \
    "$SWIFT_DIR"/*.swift
    "${SWIFT_FILES[@]}"
echo "==> Copying Info.plist..."
cp "$SWIFT_DIR/Info.plist" "$APP_BUNDLE/Contents/Info.plist"
cp "$INFO_PLIST" "$APP_INFO_PLIST"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $APP_BUILD" "$APP_INFO_PLIST"
echo "==> Copying AppIcon.icns..."
if [ -f "$PROJECT_DIR/icon-icns.icns" ]; then
@@ -54,8 +77,80 @@
    iconutil -c icns "$SWIFT_DIR/AppIcon.iconset" -o "$RESOURCES_DIR/AppIcon.icns" 2>/dev/null
fi
echo "==> Copying menu bar icon..."
if [ -f "$PROJECT_DIR/Research/logo/TagLauncherMenuBarIcon_v2_light.svg" ]; then
    cp "$PROJECT_DIR/Research/logo/TagLauncherMenuBarIcon_v2_light.svg" "$RESOURCES_DIR/TagLauncherMenuBarIcon.svg"
fi
echo "==> Copying Localization files..."
cp -r "$SWIFT_DIR/Localization" "$RESOURCES_DIR/Localization"
echo "==> Copying Smart Start catalog..."
SMARTSTART_SOURCE_DIR="$PROJECT_DIR/Research/SmartStart/UltimateDefaultCatalog"
for required in \
    "SmartStart_UltimateDefaultCatalog.base.json" \
    "SmartStart_UltimateDefaultCatalog.manifest.json" \
    "SmartStart_UltimateDefaultCatalog.notes.en.json" \
    "SmartStart_UltimateDefaultCatalog.notes.zh-Hans.json"; do
    if [ ! -f "$SMARTSTART_SOURCE_DIR/$required" ]; then
        echo "❌ Missing Smart Start split resource: $required"
        echo "   Run: node Research/SmartStart/Scripts/build-ultimate-default-catalog.mjs"
        exit 1
    fi
done
python3 - "$SMARTSTART_SOURCE_DIR/SmartStart_UltimateDefaultCatalog.base.json" "$RESOURCES_DIR/SmartStartUltimateDefaultCatalog.base.json" <<'PY'
import json
import sys
source, destination = sys.argv[1], sys.argv[2]
with open(source, "r", encoding="utf-8") as f:
    data = json.load(f)
with open(destination, "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, separators=(",", ":"))
PY
python3 - "$SMARTSTART_SOURCE_DIR/SmartStart_UltimateDefaultCatalog.manifest.json" "$RESOURCES_DIR/SmartStartUltimateDefaultCatalog.manifest.json" <<'PY'
import json
import sys
source, destination = sys.argv[1], sys.argv[2]
with open(source, "r", encoding="utf-8") as f:
    data = json.load(f)
with open(destination, "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, separators=(",", ":"))
PY
for notes_file in "$SMARTSTART_SOURCE_DIR"/SmartStart_UltimateDefaultCatalog.notes.*.json; do
    [ -e "$notes_file" ] || continue
    output_name="$(basename "$notes_file" | sed 's/SmartStart_UltimateDefaultCatalog/SmartStartUltimateDefaultCatalog/').deflate"
    python3 - "$notes_file" "$RESOURCES_DIR/$output_name" <<'PY'
import json
import sys
import zlib
source, destination = sys.argv[1], sys.argv[2]
with open(source, "r", encoding="utf-8") as f:
    data = json.load(f)
payload = json.dumps(data, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
compressor = zlib.compressobj(level=9, wbits=-15)
compressed = compressor.compress(payload) + compressor.flush()
with open(destination, "wb") as f:
    f.write(compressed)
PY
done
if find "$RESOURCES_DIR" -maxdepth 1 -type f \( \
    -name '*TranslationCache*' -o \
    -name '*invalid*' -o \
    -name 'SmartStartUltimateDefaultCatalog.json' -o \
    -name 'SmartStartUltimateDefaultCatalog.csv' -o \
    -name 'SmartStartUltimateDefaultCatalog.notes.*.json' \
    \) | grep -q .; then
    echo "❌ Forbidden Smart Start artifact copied into app bundle"
    find "$RESOURCES_DIR" -maxdepth 1 -type f \( \
        -name '*TranslationCache*' -o \
        -name '*invalid*' -o \
        -name 'SmartStartUltimateDefaultCatalog.json' -o \
        -name 'SmartStartUltimateDefaultCatalog.csv' -o \
        -name 'SmartStartUltimateDefaultCatalog.notes.*.json' \
        \) -print
    exit 1
fi
echo "==> Embedding PkgInfo..."
echo -n "APPL????" > "$APP_BUNDLE/Contents/PkgInfo"
@@ -65,6 +160,9 @@
echo "==> Stripping debug symbols..."
strip -x "$MACOS_DIR/$APP_NAME"
echo "==> Clearing extended attributes..."
xattr -cr "$APP_BUNDLE" 2>/dev/null || true
# --- Signing ---
if [ "$APP_STORE_MODE" = true ] || [ -n "$CODESIGN_IDENTITY" ]; then
@@ -88,6 +186,13 @@
    codesign --force --deep --sign - "$APP_BUNDLE"
fi
echo "==> Verifying source Info.plist was not modified..."
SOURCE_INFO_PLIST_HASH_AFTER=$(shasum -a 256 "$INFO_PLIST" | awk '{print $1}')
if [ "$SOURCE_INFO_PLIST_HASH_BEFORE" != "$SOURCE_INFO_PLIST_HASH_AFTER" ]; then
    echo "❌ Build mutated tracked source file: $INFO_PLIST"
    exit 1
fi
echo ""
echo "✅ App built at: $APP_BUNDLE"
echo "   Run: open $APP_BUNDLE"