Skip to content
Merged

Dev #10

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 37 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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') }}
Expand Down
4 changes: 3 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
Expand Down
9 changes: 7 additions & 2 deletions FinderSyncExtension/FinderSync.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 默认对动态字符串打 <private>)
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,
Expand Down
5 changes: 5 additions & 0 deletions PITFALLS_DEV.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 + 完整路径(之前只打布尔,排障信息为零)。
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@
- 单击 Dock 图标最小化窗口(可在设置中开启)
- Dock图标悬停可预览窗口
- 访达中支持右键菜单自定义
- 灵动岛

## TODO list
- [ ] 灵动岛中显示cpu,内存等使用情况
- [ ] 灵动岛中显示音乐
- [ ] 灵动岛显示宠物?如果太耗内存就不做
- [ ] 通过`添加右键菜单`按钮统一实现多个功能,现有右键菜单移除,全部通过上述按钮实现

## 下载安装

Expand Down
Loading