#!/bin/bash # DoTouchAI 一键安装脚本(macOS) # # 用法(收件方只需这一行): # curl -fsSL https://raw.githubusercontent.com/USERNAME/REPO/main/install.sh | bash # # 无需 Apple 签名公证也能在新版 macOS(含 26)上正常安装打开: # 下载 DMG → 校验 sha256 → 挂载 → ditto 拷贝到 /Applications # → xattr -cr 清除 com.apple.quarantine 与 com.apple.provenance → 启动 # # 发布新版时只需改下面 BASE_URL / VERSION / SHA256 三项即可。 set -euo pipefail # ── 配置 ──────────────────────────────────────────────────────────────── # DMG 托管在 Git releases(dist/ 被 gitignore 且超 100M 不入 git 树)。 # 默认指向你的自建 Gitea(需先把仓库设为「公开」,否则外人 curl 会 404): # Gitea raw: http://47.112.106.152:10880/Evan/EvanAgent/raw/branch/master/dsh-desktop/install.sh # Gitea rel: http://47.112.106.152:10880/Evan/EvanAgent/releases/download/v0.4.1/DoTouchAI-0.4.1-arm64.dmg # 若改用 GitHub 公开仓库分发(HTTPS、更受信任),只需把下面 BASE_URL 改成: # https://github.com///releases/download BASE_URL="${DOTOUCHAI_BASE_URL:-http://47.112.106.152:10880/Evan/EvanAgent/releases/download}" VERSION="${DOTOUCHAI_VERSION:-0.4.1}" # 0.4.1 arm64 DMG 的 sha256(发布新版后用 shasum -a 256 更新): SHA256_ARM="${DOTOUCHAI_SHA256:-05941c6b1f95780e85d0dad8176c80e355756344bcf4641589da9c632a4eca48}" # ── 架构检测 ───────────────────────────────────────────────────────────── ARCH="$(uname -m)" case "$ARCH" in arm64) DMG="DoTouchAI-${VERSION}-arm64.dmg" EXPECTED_SHA="$SHA256_ARM" ;; x86_64) echo "✗ 暂未提供 Intel (x86_64) Mac 版本,目前仅 arm64。" echo " 新版 Mac(M1/M2/M3/M4…)均为 arm64;如确为 Intel 机器,请反馈以补 x64 构建。" exit 1 ;; *) echo "✗ 不支持的架构:$ARCH" exit 1 ;; esac URL="${BASE_URL}/v${VERSION}/${DMG}" APP_NAME="DoTouchAI" APP_DST="/Applications/${APP_NAME}.app" # ── 临时资源 ───────────────────────────────────────────────────────────── TMP_DMG="$(mktemp -t dotouchai).dmg" MNT="$(mktemp -d -t dotouchai-mnt)" cleanup() { hdiutil detach "$MNT" -quiet >/dev/null 2>&1 || true rmdir "$MNT" 2>/dev/null || true rm -f "$TMP_DMG" } trap cleanup EXIT echo "→ 下载 ${DMG} …" echo " ${URL}" curl -fSL "$URL" -o "$TMP_DMG" echo "→ 校验完整性(sha256)…" ACTUAL_SHA="$(shasum -a 256 "$TMP_DMG" | cut -d' ' -f1)" if [ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]; then echo "✗ 校验和不匹配" echo " 期望:$EXPECTED_SHA" echo " 实际:$ACTUAL_SHA" echo " 下载可能不完整或被篡改,已中止。" exit 1 fi echo " ✓ 校验通过" echo "→ 挂载安装包 …" hdiutil attach "$TMP_DMG" -nobrowse -mountpoint "$MNT" -quiet APP_SRC="$MNT/${APP_NAME}.app" if [ ! -d "$APP_SRC" ]; then echo "✗ 安装包内未找到 ${APP_NAME}.app" exit 1 fi # 退出可能正在运行的旧实例(用 osascript 精确退出,避免误杀其他 Electron 应用) osascript -e "tell application \"${APP_NAME}\" to quit" 2>/dev/null || true sleep 1 # 替换旧版本 if [ -d "$APP_DST" ]; then echo "→ 移除旧版本 …" rm -rf "$APP_DST" fi echo "→ 拷贝到 /Applications …" # ditto 保留 bundle 结构与元数据,优于 cp if ! ditto "$APP_SRC" "$APP_DST"; then echo "✗ 拷贝失败。若提示权限不足,请用管理员重试:" echo " sudo curl -fsSL <脚本URL> | sudo bash" exit 1 fi echo "→ 清除 Gatekeeper 隔离标记(quarantine + provenance)…" xattr -cr "$APP_DST" echo "→ 卸载安装包 …" hdiutil detach "$MNT" -quiet echo "" echo "✓ 安装完成:${APP_DST}" echo " 双击即可启动,或终端执行:open -a ${APP_NAME}" echo "" # 直接启动(除非显式要求不启动) if [ -z "${DOTOUCHAI_NO_LAUNCH:-}" ]; then echo "→ 启动 ${APP_NAME} …" open -a "$APP_NAME" fi