diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b4d59ca..0c5e216 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,9 +30,35 @@ jobs: - name: Checkout uses: actions/checkout@v5 - # Ad-hoc signing (no Apple certificate available on CI): - # keeps the sandbox + App Group entitlements of the FinderSync extension - # and makes the binaries runnable on Apple Silicon. + # FinderSync 扩展沙盒进程需要 Team 签名才有 App Group 容器的写权限: + # ad-hoc 签名时扩展能读组容器但写入 EPERM(POSIX Code=1),「访达右键打开终端」 + # 等依赖扩展→主app IPC 的功能会静默失败。CI 从 secrets 导入 Apple Development + # 证书签名;未配置证书时回退 ad-hoc(fork PR 拿不到 secrets,仅编译检查用)。 + - name: Import signing certificate + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }} + P12_PASSWORD: ${{ secrets.P12_PASSWORD }} + run: | + set -euo pipefail + if [ -z "${BUILD_CERTIFICATE_BASE64:-}" ]; then + echo "::warning::未配置 BUILD_CERTIFICATE_BASE64,回退 ad-hoc 签名(FinderSync 扩展将无 App Group 写权限)" + echo "CS_IDENTITY=-" >> "$GITHUB_ENV" + echo "CS_TEAM=" >> "$GITHUB_ENV" + exit 0 + fi + CERT_PATH="$RUNNER_TEMP/build_certificate.p12" + KC_PATH="$RUNNER_TEMP/build.keychain-db" + KC_PASS="$(openssl rand -hex 16)" + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o "$CERT_PATH" + security create-keychain -p "$KC_PASS" "$KC_PATH" + security set-keychain-settings -lut 21600 "$KC_PATH" + security unlock-keychain -p "$KC_PASS" "$KC_PATH" + security import "$CERT_PATH" -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k "$KC_PATH" + security set-key-partition-list -S apple-tool:,apple: -k "$KC_PASS" "$KC_PATH" + security list-keychain -d user -s "$KC_PATH" login.keychain + echo "CS_IDENTITY=Apple Development" >> "$GITHUB_ENV" + echo "CS_TEAM=8NHN73Q43T" >> "$GITHUB_ENV" + - name: Build run: | set -euo pipefail @@ -41,9 +67,9 @@ jobs: -scheme Zeroflow \ -configuration Release \ -derivedDataPath build \ - CODE_SIGN_IDENTITY=- \ + CODE_SIGN_IDENTITY="$CS_IDENTITY" \ CODE_SIGN_STYLE=Manual \ - DEVELOPMENT_TEAM= \ + DEVELOPMENT_TEAM="$CS_TEAM" \ build # The product path is not always deterministic (may land in @@ -67,6 +93,12 @@ jobs: set -euo pipefail codesign --verify --deep --strict "$APP_PATH" codesign -dv "$APP_PATH/Contents/PlugIns/FinderSyncExtension.appex" + # 发 Release 的包必须带 Team 签名,否则扩展沙盒无 App Group 写权限 + if [ -n "${CS_TEAM:-}" ]; then + codesign -dv "$APP_PATH/Contents/PlugIns/FinderSyncExtension.appex" 2>&1 \ + | grep -q "TeamIdentifier=$CS_TEAM" \ + || { echo "::error::appex 未按 Team 签名,沙盒下 App Group 写入会被拒(打开终端功能会失效)"; exit 1; } + fi - name: Package app zip if: ${{ !startsWith(github.ref, 'refs/tags/v') }} diff --git a/AGENTS.md b/AGENTS.md index 3021208..347364c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,7 +13,9 @@ macOS 截图菜单栏工具(截图 + 画线/矩形/圆框/文字气泡/马赛克 xcodebuild -project Zeroflow.xcodeproj -scheme Zeroflow -configuration Debug -derivedDataPath build -allowProvisioningUpdates build open build/Build/Products/Debug/Zeroflow.app -# CI 等价命令(ad-hoc 签名,无需团队证书/provisioning) +# CI 等价命令(ad-hoc;仅限编译检查——ad-hoc 包的 FinderSync 扩展无 App Group 写权限, +# 「访达右键打开终端」会静默失败,见 PITFALLS_DEV.md DEV-018;正式分发用 Team 签名, +# CI 已从 secrets 导入 Apple Development 证书,本地用上面的 Debug 命令) xcodebuild -project Zeroflow.xcodeproj -scheme Zeroflow -configuration Release -derivedDataPath build \ CODE_SIGN_IDENTITY=- CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM= build ``` diff --git a/FinderSyncExtension/FinderSync.swift b/FinderSyncExtension/FinderSync.swift index e624c22..f98fcd8 100644 --- a/FinderSyncExtension/FinderSync.swift +++ b/FinderSyncExtension/FinderSync.swift @@ -247,8 +247,13 @@ enum CustomCommandRunner { "directory": directory?.path ?? "", "createdAt": Double(stamp), ] - guard (payload as NSDictionary).write(to: fileURL, atomically: true) else { - os_log("submit: failed to write %@", log: finderSyncLog, type: .error, fileURL.path) + do { + let data = try PropertyListSerialization.data(fromPropertyList: payload, format: .xml, options: 0) + try data.write(to: fileURL, options: .atomic) + } catch { + // 诊断:写出真实 NSError 与完整路径(os_log 默认对动态字符串打 ) + os_log("submit: failed to write %{public}@ error=%{public}@", log: finderSyncLog, type: .error, + fileURL.path, String(describing: error)) return } os_log("submit: cmd=%{public}@ file=%{public}@", log: finderSyncLog, type: .info, diff --git a/PITFALLS_DEV.md b/PITFALLS_DEV.md index d81b227..ff395cf 100644 --- a/PITFALLS_DEV.md +++ b/PITFALLS_DEV.md @@ -86,3 +86,8 @@ - **Pitfall:** `CGWindowListCreateImage` 在 macOS 15 已 obsoleted(SDK 15+ 直接编译错误),系统磨砂(NSVisualEffectView)公开 API 不暴露模糊半径;`NSGlassEffectView` 的 `alphaValue` 会连 contentView 内容一起变透明,不能当「背景不透明度」用。 - **Cause:** 液态玻璃透明度只能经 `tintColor` 的 alpha(染色深浅)控制;内容必须嵌 `contentView` 才保证在玻璃内(任意兄弟子视图 z 序无保证)。 - **Prevention:** macOS 26+ 面板背景用 `NSGlassEffectView`(cornerRadius 对齐屏幕圆角,macOS 上无公开 API 查屏幕圆角,取 16);旧系统回退 `NSVisualEffectView(.hudWindow)`。若真需要面板背后区域的模糊快照,须 SCScreenshotManager + `SCContentFilter(display:excludingWindows: [自身 SCWindow])` 整屏捕获后裁剪再 `CIGaussianBlur`(输入先 `clampedToExtent()` 防边缘晕边);SCShareableContent 枚举耗时数百毫秒,需缓存。 + +## DEV-018: ad-hoc 签名的扩展对 App Group 容器只读,写请求文件 EPERM,「打开终端」静默失效 +- **Pitfall:** 「访达右键 → 打开终端」点击毫无反应,而「新建空文件」(纯扩展内动作)正常,极具迷惑性。扩展 os_log 仅报 `submit: failed to write`,底层为 `NSCocoaErrorDomain Code=513 / NSPOSIXErrorDomain Code=1 (EPERM)`;group container 里从未出现 `finder-command-*.plist`,主 app 日志零条 `finderCommand`。GitHub CI 的 ad-hoc 包必现,Team 签名构建正常。 +- **Cause:** ad-hoc 签名(`TeamIdentifier=not set`)的沙盒扩展,系统不认可其 `com.apple.security.application-groups` entitlement,沙盒只放行 group container 的**读**、**写**被拒(EPERM)。扩展读设置正常所以菜单/文案都正常,只有「写请求文件」这一步死;非沙盒主 app 不受沙盒中介、读写都正常——这种读写不对称掩盖了问题。Team 签名(真证书)即可放行写,实测无需嵌入 provisioning profile。 +- **Prevention:** 涉及 FinderSync 扩展的产物必须 Team 签名(`CODE_SIGN_IDENTITY="Apple Development" DEVELOPMENT_TEAM=8NHN73Q43T`)。CI 已加 `Import signing certificate` 步骤从 secrets 导入证书,发 tag 时断言 appex `TeamIdentifier=8NHN73Q43T`;无 secrets 回退 ad-hoc 仅限编译检查(那种包右键命令功能无效)。排障用 `log show --info --predicate 'subsystem == "com.zeroflow.app.finderSync"'`(必须 `--info`,否则只剩 error 级);`CustomCommandRunner.submit` 的失败日志已改为输出真实 NSError + 完整路径(之前只打布尔,排障信息为零)。 diff --git a/README.md b/README.md index 203f643..69174c0 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,13 @@ - 单击 Dock 图标最小化窗口(可在设置中开启) - Dock图标悬停可预览窗口 - 访达中支持右键菜单自定义 +- 灵动岛 + +## TODO list +- [ ] 灵动岛中显示cpu,内存等使用情况 +- [ ] 灵动岛中显示音乐 +- [ ] 灵动岛显示宠物?如果太耗内存就不做 +- [ ] 通过`添加右键菜单`按钮统一实现多个功能,现有右键菜单移除,全部通过上述按钮实现 ## 下载安装