Skip to main content

macOS 签名(调试构建)

此应用通常通过 scripts/package-mac-app.sh 构建,该脚本现在:
  • 设置稳定的调试捆绑包标识符:ai.openclaw.mac.debug
  • 使用该捆绑包标识符写入 Info.plist(可通过 BUNDLE_ID=... 覆盖)
  • 调用 scripts/codesign-mac-app.sh 对主二进制文件和应用捆绑包进行签名,使 macOS 将每次重新构建视为同一个已签名的捆绑包,并保留 TCC 权限(通知、辅助功能、屏幕录制、麦克风、语音)。为获得稳定的权限,请使用真实的签名身份;临时签名需显式启用且较为脆弱(参见 macOS 权限)。
  • 默认使用 CODESIGN_TIMESTAMP=auto;它为 Developer ID 签名启用可信时间戳。将 CODESIGN_TIMESTAMP=off 设置为 true 可跳过时间戳记录(适用于离线调试构建)。
  • 将构建元数据注入 Info.plist:OpenClawBuildTimestamp(UTC)和 OpenClawGitCommit(短哈希),以便“关于”面板能够显示构建信息、Git 提交以及调试或发布通道。
  • 打包需要 Node 22+:该脚本会运行 TypeScript 构建以及 Control UI 构建。
  • 从环境变量中读取 SIGN_IDENTITY。将 export SIGN_IDENTITY="Apple Development: Your Name (TEAMID)"(或您的 Developer ID 应用证书)添加到 shell 配置文件中,以始终使用您的证书进行签名。临时签名需要通过 ALLOW_ADHOC_SIGNING=1SIGN_IDENTITY="-" 显式启用(不建议用于权限测试)。
  • 在签名后执行团队 ID 审计,如果应用捆绑包内的任何 Mach-O 文件由不同的团队 ID 签名,则构建会失败。将 SKIP_TEAM_ID_CHECK=1 设置为 true 可绕过此检查。

使用方法

# from repo root
scripts/package-mac-app.sh               # auto-selects identity; errors if none found
SIGN_IDENTITY="Developer ID Application: Your Name" scripts/package-mac-app.sh   # real cert
ALLOW_ADHOC_SIGNING=1 scripts/package-mac-app.sh    # ad-hoc (permissions will not stick)
SIGN_IDENTITY="-" scripts/package-mac-app.sh        # explicit ad-hoc (same caveat)
DISABLE_LIBRARY_VALIDATION=1 scripts/package-mac-app.sh   # dev-only Sparkle Team ID mismatch workaround

临时签名说明

当使用 SIGN_IDENTITY="-"(临时签名)进行签名时,脚本会自动禁用 强化运行时 (--options runtime)。这是必要的,可防止应用在尝试加载未共享相同团队 ID 的嵌入式框架(如 Sparkle)时发生崩溃。临时签名还会导致 TCC 权限无法持久化;有关恢复步骤,请参阅 macOS 权限

用于“关于”面板的构建元数据

package-mac-app.sh 会在捆绑包中打上以下标记:
  • OpenClawBuildTimestamp:打包时的 ISO8601 UTC 时间
  • OpenClawGitCommit:短 Git 哈希(若不可用则使用 unknown)
“关于”选项卡会读取这些键值,以显示版本、构建日期、Git 提交以及是否为调试构建(通过 #if DEBUG 判断)。在代码更改后,运行打包脚本即可更新这些值。

原因

TCC 权限同时绑定到捆绑包标识符和代码签名。未签名的调试构建由于 UUID 不断变化,会导致 macOS 在每次重新构建后忘记已授予的权限。通过对二进制文件进行签名(默认采用临时签名)并保持固定的捆绑包标识符/路径(dist/OpenClaw.app),可在不同构建之间保留这些权限,这与 VibeTunnel 的做法一致。