release: package FCP-BeautyGirl 1.3.2 with verified legacy identity migration
这个提交包含在:
1 父节点
767bba8ac1
当前提交
8a70d38b7c
32 个文件已更改
+810
-31
没有与搜索条件相匹配的文件
+2
@@ -42,3 +42,5 @@ reference-binaries/
|
|||||||
!releases/1.2.0/*.pkg
|
!releases/1.2.0/*.pkg
|
||||||
|
|
||||||
!releases/1.3.1/*.pkg
|
!releases/1.3.1/*.pkg
|
||||||
|
|
||||||
|
!releases/1.3.2/*.pkg
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
# 大鱼人像美化 · beatygril
|
# 大鱼人像美化 · FCP-BeautyGirl
|
||||||
|
|
||||||
基于本仓库的 FxPlug4 初始工程制作的人像美化滤镜,支持 Motion 和 Final Cut Pro。源码使用 Objective-C、Vision、Core Image 与 Metal。
|
基于本仓库的 FxPlug4 初始工程制作的人像美化滤镜,支持 Motion 和 Final Cut Pro。源码使用 Objective-C、Vision、Core Image 与 Metal。
|
||||||
|
|
||||||
@@ -6,15 +6,17 @@
|
|||||||
|
|
||||||
功能包括磨皮、肤色、细节、牙齿美白、眼睛提亮、九类脸型调整、自动人脸跟随和多人处理。原版 MSE18V2 的静态分析依据、近似实现与尚未对齐的部分见 [分析说明](docs/analysis/REA-分析与复刻说明.md)。本版尚未完成原版逐像素与复杂运动跟踪对照。
|
功能包括磨皮、肤色、细节、牙齿美白、眼睛提亮、九类脸型调整、自动人脸跟随和多人处理。原版 MSE18V2 的静态分析依据、近似实现与尚未对齐的部分见 [分析说明](docs/analysis/REA-分析与复刻说明.md)。本版尚未完成原版逐像素与复杂运动跟踪对照。
|
||||||
|
|
||||||
|
1.3.2(17)已统一工程、APP、插件类名和应用ID,正式安装为 `FCP-BeautyGirl.app` / `com.dayu.fcpbeautygirl`,嵌套插件ID为 `com.dayu.fcpbeautygirl.fxplug`。旧APP已迁移清理,滤镜UUID、参数编号和归档格式保持兼容。1901项自动回归及身份迁移检查通过;APP和含配套模板的PKG均已签名、公证、粘附票据和验证。更名后的旧工程重开仍由用户实测。
|
||||||
|
|
||||||
## 使用
|
## 使用
|
||||||
|
|
||||||
正式安装路径为 `/Library/Plug-Ins/FxPlug/beatygril.app`。Motion 滤镜分类为「大鱼」,滤镜名「大鱼人像美化」。Final Cut Pro 在「效果 → 大鱼磨皮瘦脸 → 大鱼人像美化」中使用配套 Motion 效果,模板目录必须同时保留 `.moef` 与 `Drop Zone.tiff`。美化会随当前帧的人脸自动更新,不需要点击分析。界面以磨皮、美白、瘦脸三张卡片呈现,默认跟随主要人脸;多人模式对多脸变形。单项眼睛可暂时停用并保留数值,右侧箭头恢复默认;磨皮半径、饱和度、锐化和整体混合等收在「更多设置」。旧手动分析与调试参数仅保留隐藏兼容,实际输出统一使用实时自动跟随。
|
正式安装路径为 `/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app`。Motion 滤镜分类为「大鱼」,滤镜名「大鱼人像美化」。Final Cut Pro 在「效果 → 大鱼磨皮瘦脸 → 大鱼人像美化」中使用配套 Motion 效果,模板目录必须同时保留 `.moef` 与 `Drop Zone.tiff`。美化会随当前帧的人脸自动更新,不需要点击分析。界面以磨皮、美白、瘦脸三张卡片呈现,默认跟随主要人脸;多人模式对多脸变形。单项眼睛可暂时停用并保留数值,右侧箭头恢复默认;磨皮半径、饱和度、锐化和整体混合等收在「更多设置」。旧手动分析与调试参数仅保留隐藏兼容,实际输出统一使用实时自动跟随。
|
||||||
|
|
||||||
1.3.0 的磨皮卡片依次提供「磨皮程度、微细锐化、五官保护、非肤色区保护」。两种保护默认 100%;降低五官保护让五官区域参与更多磨皮,降低非肤色区保护则扩大磨皮范围,均不扩大肤色提亮范围。微细锐化在局部支持区域恢复纹理;旧全局磨皮和全局锐化仍保留在更多设置,旧工程的参数与归档继续兼容。迁移证据、实现边界与验证见[新版磨皮参数迁移](docs/analysis/新版磨皮参数迁移.md)。1.3.0 的新增参数已随 1.3.1 一并提供。
|
1.3.0 的磨皮卡片依次提供「磨皮程度、微细锐化、五官保护、非肤色区保护」。两种保护默认 100%;降低五官保护让五官区域参与更多磨皮,降低非肤色区保护则扩大磨皮范围,均不扩大肤色提亮范围。微细锐化在局部支持区域恢复纹理;旧全局磨皮和全局锐化仍保留在更多设置,旧工程的参数与归档继续兼容。迁移证据、实现边界与验证见[新版磨皮参数迁移](docs/analysis/新版磨皮参数迁移.md)。1.3.0 的新增参数已随 1.3.1 一并提供。
|
||||||
|
|
||||||
1.3.1(16)修复 V 脸影响眼区的问题,改为四组下颌轮廓到外唇的局部采样,并对齐新目标的 0.065 强度映射。1901 项自动检查通过,APP 与本机 PKG 工坊制作的安装包均已签名、公证和验证。正式 APP 已安装;新效果的原生宿主视觉仍由用户实测。原理与边界见 [V 脸下颌区域修复](docs/analysis/V脸下颌区域修复.md)。
|
1.3.1(16)修复 V 脸影响眼区的问题,改为四组下颌轮廓到外唇的局部采样,并对齐新目标的 0.065 强度映射。1901 项自动检查通过,APP 与本机 PKG 工坊制作的安装包均已签名、公证和验证。正式 APP 已安装;新效果的原生宿主视觉仍由用户实测。原理与边界见 [V 脸下颌区域修复](docs/analysis/V脸下颌区域修复.md)。
|
||||||
|
|
||||||
当前 [1.3.1 正式下载](https://github.com/dayumeida/FCP-BeautyGirl/releases/tag/v1.3.1) 与 [大鱼文章](https://dayu.media/15593/) 已更新,安装包包含「大鱼磨皮瘦脸」分类的配套效果及资源,源码快照也已同步。
|
当前 [1.3.2 正式下载](https://github.com/dayumeida/FCP-BeautyGirl/releases/tag/v1.3.2) 与 [大鱼文章](https://dayu.media/15593/) 是本版发布入口,安装包包含「大鱼磨皮瘦脸」分类的配套效果及资源,源码快照也已同步。
|
||||||
|
|
||||||
## 开发和恢复
|
## 开发和恢复
|
||||||
|
|
||||||
@@ -22,9 +24,9 @@
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
./scripts/test.sh
|
./scripts/test.sh
|
||||||
PAINTFCP_HOST_ASAN=1 ./scripts/test-host.sh
|
FCP_BEAUTYGIRL_HOST_ASAN=1 ./scripts/test-host.sh
|
||||||
PAINTFCP_OSC_ASAN=1 ./scripts/test-osc.sh
|
FCP_BEAUTYGIRL_OSC_ASAN=1 ./scripts/test-osc.sh
|
||||||
xcodebuild -project beatygril/beatygril.xcodeproj -scheme 'Wrapper Application' -configuration Release -derivedDataPath /tmp/paintfcp-build -destination 'generic/platform=macOS' build
|
xcodebuild -project FCP-BeautyGirl/FCP-BeautyGirl.xcodeproj -scheme 'FCP-BeautyGirl' -configuration Release -derivedDataPath /tmp/fcp-beautygirl-build -destination 'generic/platform=macOS' build
|
||||||
```
|
```
|
||||||
|
|
||||||
工程从 `/Library/Developer/SDKs/FxPlug.sdk` 读取头文件与链接信息,从 `/Library/Developer/Frameworks` 嵌入可运行的 Apple 框架。构建默认使用团队 B3W25FX5H5 的 Developer ID Application 身份;正式交付使用 `python3 scripts/deliver.py` 完成公证、粘附和安装;安装前先关闭 Motion 与 FCP,脚本在检测到宿主仍运行时保留原安装版并停止。原生验收完成后继续脚本的清理阶段,清除临时注册与 APP 副本。
|
工程从 `/Library/Developer/SDKs/FxPlug.sdk` 读取头文件与链接信息,从 `/Library/Developer/Frameworks` 嵌入可运行的 Apple 框架。构建默认使用团队 B3W25FX5H5 的 Developer ID Application 身份;正式交付使用 `python3 scripts/deliver.py` 完成公证、粘附和安装;安装前先关闭 Motion 与 FCP,脚本在检测到宿主仍运行时保留原安装版并停止。原生验收完成后继续脚本的清理阶段,清除临时注册与 APP 副本。
|
||||||
|
|||||||
+10
@@ -1,5 +1,8 @@
|
|||||||
# 恢复说明
|
# 恢复说明
|
||||||
|
|
||||||
|
当前产品身份自1.3.2(17)统一为FCP-BeautyGirl:工程 `FCP-BeautyGirl/FCP-BeautyGirl.xcodeproj`、scheme `FCP-BeautyGirl`、APP `/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app`、主ID `com.dayu.fcpbeautygirl`、插件ID `com.dayu.fcpbeautygirl.fxplug`。签名源码 `767bba8ac11e9bf9268a1e02d1a06d3c120c46aa`,APP公证Accepted `559eedf0-048f-4d0e-b013-6a187695f2da`,已安装并迁移清理旧APP;程序与滤镜参数、UUID保持兼容。中央身份定义见product.json,旧名称只用于经过ID、签名团队和滤镜UUID验证的迁移。下文历史版本保留各自当时的名称与路径。
|
||||||
|
|
||||||
|
|
||||||
- 大鱼备份远程(origin):`https://dayu.media/git/dayu/paintfcp-fxplug.git`
|
- 大鱼备份远程(origin):`https://dayu.media/git/dayu/paintfcp-fxplug.git`
|
||||||
- GitHub 公开远程(github):`https://github.com/dayumeida/FCP-BeautyGirl.git`
|
- GitHub 公开远程(github):`https://github.com/dayumeida/FCP-BeautyGirl.git`
|
||||||
- 本地项目根:`/Users/dayu/Documents/PaintFCP`
|
- 本地项目根:`/Users/dayu/Documents/PaintFCP`
|
||||||
@@ -130,3 +133,10 @@ GitHub于2026-10-22更正仓库名为 `FCP-BeautyGirl`,远端为 `https://gith
|
|||||||
|
|
||||||
|
|
||||||
GitHub用户名现为 `dayumeida`,账号ID117798680保持一致。当前公开远端 `https://github.com/dayumeida/FCP-BeautyGirl.git` 的恢复检查点 `2faf7de77929cf7707645ebb38095b03d5729647` 已通过匿名独立克隆、241文件字节/执行位和strict/full fsck核验,产品源码与账号更名前一致。两个仓库的全部分支/标签及Release附件均保留;当前文章、本地github远端和仓库目录表已同步。回执见 `docs/verification/github/username-recovery-20261022.json`。
|
GitHub用户名现为 `dayumeida`,账号ID117798680保持一致。当前公开远端 `https://github.com/dayumeida/FCP-BeautyGirl.git` 的恢复检查点 `2faf7de77929cf7707645ebb38095b03d5729647` 已通过匿名独立克隆、241文件字节/执行位和strict/full fsck核验,产品源码与账号更名前一致。两个仓库的全部分支/标签及Release附件均保留;当前文章、本地github远端和仓库目录表已同步。回执见 `docs/verification/github/username-recovery-20261022.json`。
|
||||||
|
|
||||||
|
|
||||||
|
## 1.3.2 统一产品身份
|
||||||
|
|
||||||
|
发行入口为 `v1.3.2`;正式 APP 源码为 `767bba8ac11e9bf9268a1e02d1a06d3c120c46aa`。新机器按 `product.json` 的工程、scheme 与路径恢复,运行 `python3 scripts/deliver.py --wait-for-hosts --user-tests`;旧产品先验证 Bundle ID、签名团队和滤镜 UUID,再迁移并支持失败回滚。最终包为 `releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg`,SHA-256 `20a88dacf68cc8812f5af86cfe94c1c0614414a68a019eaeac7ca9d078165ae1`,签名、公证 Accepted `4a831775-2317-4372-a4cc-102415657ea3`、票据和 Gatekeeper 均通过。正式 APP 已安装并清理旧身份。1901 项自动回归、8 项 APP 迁移、8 项最终 PKG 身份脚本迁移与模板隔离测试通过;未运行真实 installer,原生旧工程重开仍待用户检查。
|
||||||
|
|
||||||
|
源码包须从发行标签导出,排除 PKG 二进制并加入 SOURCE-SNAPSHOT.json。发布与独立克隆恢复回执位于 `docs/verification/v1.3.2/`,不包含用户人脸素材、签名私钥或公证凭据。历史标签和旧版本安装包保留,不覆盖。
|
||||||
+7
-2
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
公开源码:https://github.com/dayumeida/FCP-BeautyGirl
|
公开源码:https://github.com/dayumeida/FCP-BeautyGirl
|
||||||
|
|
||||||
正式安装包:https://github.com/dayumeida/FCP-BeautyGirl/releases/tag/v1.3.1
|
正式安装包:https://github.com/dayumeida/FCP-BeautyGirl/releases/tag/v1.3.2
|
||||||
|
|
||||||
本地 `github` 远端指向上述 GitHub 仓库,`origin` 继续指向大鱼仓库,`main` 仍跟随 `origin/main`。当前项目的完整提交历史、main 和全部现有版本标签已推送,两端引用与本地一致;未改写历史或覆盖标签。后续更新需要分别推送到 origin 和 github,不会自动定时同步。
|
本地 `github` 远端指向上述 GitHub 仓库,`origin` 继续指向大鱼仓库,`main` 仍跟随 `origin/main`。当前项目的完整提交历史、main 和全部现有版本标签已推送,两端引用与本地一致;未改写历史或覆盖标签。后续更新需要分别推送到 origin 和 github,不会自动定时同步。
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ git switch --detach 356683b41af702d6c0143ad7fa5f540d752d6e14
|
|||||||
源代码编写署名:代码由 OpenAI + Codex 全程编写,站长仅参与调试和测试。
|
源代码编写署名:代码由 OpenAI + Codex 全程编写,站长仅参与调试和测试。
|
||||||
|
|
||||||
|
|
||||||
## 1.3.1 当前发行与恢复
|
## 1.3.1 发行与恢复
|
||||||
|
|
||||||
main已快进纳入1.3.0磨皮参数和1.3.1的V脸下颌修复;origin和github的main及v1.3.1引用已回读核验。v1.3.1固定完整SHA为 `b35b4a5d1ca252d2f83c798613560a768274de3c`,签名APP源码为 `7fa3298e022946e77dfd8cfba1bb5ff2c2a6361f`。独立匿名GitHub克隆232文件字节与执行位一致、strict/full fsck和恢复PKG签名/票据通过。无LFS或子模块。后续main仅补充发布记录,不改写标签。
|
main已快进纳入1.3.0磨皮参数和1.3.1的V脸下颌修复;origin和github的main及v1.3.1引用已回读核验。v1.3.1固定完整SHA为 `b35b4a5d1ca252d2f83c798613560a768274de3c`,签名APP源码为 `7fa3298e022946e77dfd8cfba1bb5ff2c2a6361f`。独立匿名GitHub克隆232文件字节与执行位一致、strict/full fsck和恢复PKG签名/票据通过。无LFS或子模块。后续main仅补充发布记录,不改写标签。
|
||||||
|
|
||||||
@@ -40,3 +40,8 @@ GitHub仓库从 `FAMEDaYu/FCP-BeatyGril` 更名为 `FAMEDaYu/FCP-BeautyGirl`,
|
|||||||
## 2026-10-22 用户名更改
|
## 2026-10-22 用户名更改
|
||||||
|
|
||||||
用户将GitHub登录名从 `FAMEDaYu` 改为 `dayumeida`,账号ID117798680保持不变。两个公开仓库迁移到dayumeida名下:FCP-BeautyGirl(ID1428817365)和FCPX-(ID904215594)。更名前后全部分支/标签SHA及Release/附件ID、名称、大小一致。当前项目github远端为 `https://github.com/dayumeida/FCP-BeautyGirl.git`,origin及main上游保持原大鱼仓库;文章15593、活动文档和Release说明更新为新地址。正式版本标签、公证APP/PKG和源码快照保留原始字节,不为账号更名重新构建。个人主页新地址为 `https://github.com/dayumeida`,旧个人主页不提供重定向;仓库旧地址由GitHub重定向。历史验证回执保留当时用户名。账号更名核验见verification/github/username-20261022.json。
|
用户将GitHub登录名从 `FAMEDaYu` 改为 `dayumeida`,账号ID117798680保持不变。两个公开仓库迁移到dayumeida名下:FCP-BeautyGirl(ID1428817365)和FCPX-(ID904215594)。更名前后全部分支/标签SHA及Release/附件ID、名称、大小一致。当前项目github远端为 `https://github.com/dayumeida/FCP-BeautyGirl.git`,origin及main上游保持原大鱼仓库;文章15593、活动文档和Release说明更新为新地址。正式版本标签、公证APP/PKG和源码快照保留原始字节,不为账号更名重新构建。个人主页新地址为 `https://github.com/dayumeida`,旧个人主页不提供重定向;仓库旧地址由GitHub重定向。历史验证回执保留当时用户名。账号更名核验见verification/github/username-20261022.json。
|
||||||
|
|
||||||
|
|
||||||
|
## 1.3.2 产品身份统一
|
||||||
|
|
||||||
|
发行标签 `v1.3.2`,正式 APP 签名源码 `767bba8ac11e9bf9268a1e02d1a06d3c120c46aa`。新工程和 APP 名为 FCP-BeautyGirl,应用标识及安装路径见 product.json;旧身份仅保留经过验证的迁移入口。GitHub、大鱼 Release 和文章 15593 使用新名称安装包及源码快照,历史发行资料不改写。当前交付与发布核验保存在 verification/v1.3.2。
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Beauty renderer: 57 checks, 0 failures (Metal).
|
||||||
|
2026-10-22 18:30:09.786 face-tests[35177:8446323] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||||
|
Face processing: 116 checks passed
|
||||||
|
2026-10-22 18:30:23.734 slim-tests[35267:8446747] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||||
|
PASS: 1033 slim alignment checks; maximum UV oracle error 1.09828022e-05
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"status": "installed_user_qa_pending",
|
||||||
|
"bundleIdentifier": "com.dayu.fcpbeautygirl",
|
||||||
|
"installationPath": "/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app",
|
||||||
|
"options": {
|
||||||
|
"waitForHosts": true,
|
||||||
|
"userTests": true
|
||||||
|
},
|
||||||
|
"nativeEffectQA": {
|
||||||
|
"status": "pending_user",
|
||||||
|
"performedByScript": false
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"commit": "767bba8ac11e9bf9268a1e02d1a06d3c120c46aa",
|
||||||
|
"trackedWorktreeChanges": []
|
||||||
|
},
|
||||||
|
"updatedAt": "2026-10-22T10:38:29.383549+00:00",
|
||||||
|
"version": "1.3.2",
|
||||||
|
"build": "17",
|
||||||
|
"stagingSignature": "Executable=/private/tmp/fcp-beautygirl-release/Build/Products/Release/FCP-BeautyGirl.app/Contents/MacOS/FCP-BeautyGirl\nIdentifier=com.dayu.fcpbeautygirl\nFormat=app bundle with Mach-O universal (x86_64 arm64)\nCodeDirectory v=20500 size=482 flags=0x10000(runtime) hashes=4+7 location=embedded\nHash type=sha256 size=32\nCandidateCDHash sha256=28f0e84981124d854690d9be80e8ecb7a855ed02\nCandidateCDHashFull sha256=28f0e84981124d854690d9be80e8ecb7a855ed02e3de84009119fc616e22aecd\nHash choices=sha256\nCMSDigest=28f0e84981124d854690d9be80e8ecb7a855ed02e3de84009119fc616e22aecd\nCMSDigestType=2\nCDHash=28f0e84981124d854690d9be80e8ecb7a855ed02\nSignature size=8968\nAuthority=Developer ID Application: zhong luo (B3W25FX5H5)\nAuthority=Developer ID Certification Authority\nAuthority=Apple Root CA\nTimestamp=Oct 22, 2026 at 18:38:05\nInfo.plist entries=23\nTeamIdentifier=B3W25FX5H5\nRuntime Version=27.0.0\nSealed Resources version=2 rules=13 files=5\nInternal requirements count=1 size=184\nTotal signatures=1\nChosen signature=1\n",
|
||||||
|
"notarization": {
|
||||||
|
"id": "559eedf0-048f-4d0e-b013-6a187695f2da",
|
||||||
|
"message": "Processing complete",
|
||||||
|
"status": "Accepted"
|
||||||
|
},
|
||||||
|
"signingVerified": true,
|
||||||
|
"stapleValidated": true,
|
||||||
|
"stagingPluginUnregistered": true,
|
||||||
|
"runningHosts": [],
|
||||||
|
"installedSignature": "Executable=/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app/Contents/MacOS/FCP-BeautyGirl\nIdentifier=com.dayu.fcpbeautygirl\nFormat=app bundle with Mach-O universal (x86_64 arm64)\nCodeDirectory v=20500 size=482 flags=0x10000(runtime) hashes=4+7 location=embedded\nHash type=sha256 size=32\nCandidateCDHash sha256=28f0e84981124d854690d9be80e8ecb7a855ed02\nCandidateCDHashFull sha256=28f0e84981124d854690d9be80e8ecb7a855ed02e3de84009119fc616e22aecd\nHash choices=sha256\nCMSDigest=28f0e84981124d854690d9be80e8ecb7a855ed02e3de84009119fc616e22aecd\nCMSDigestType=2\nCDHash=28f0e84981124d854690d9be80e8ecb7a855ed02\nSignature size=8968\nAuthority=Developer ID Application: zhong luo (B3W25FX5H5)\nAuthority=Developer ID Certification Authority\nAuthority=Apple Root CA\nTimestamp=Oct 22, 2026 at 18:38:05\nNotarization Ticket=stapled\nInfo.plist entries=23\nTeamIdentifier=B3W25FX5H5\nRuntime Version=27.0.0\nSealed Resources version=2 rules=13 files=5\nInternal requirements count=1 size=184\nTotal signatures=1\nChosen signature=1\n",
|
||||||
|
"installedSignatureVerified": true,
|
||||||
|
"installedStapleValidated": true,
|
||||||
|
"gatekeeperAccepted": true,
|
||||||
|
"identityMigration": {
|
||||||
|
"legacyInstallationsRemoved": [
|
||||||
|
"/Library/Plug-Ins/FxPlug/beatygril.app"
|
||||||
|
],
|
||||||
|
"filterUUIDPreserved": "FB14B0E6-59B2-4836-916F-CD0C559E9241"
|
||||||
|
},
|
||||||
|
"pluginDiscovery": {
|
||||||
|
"bundleIdentifier": "com.dayu.fcpbeautygirl.fxplug",
|
||||||
|
"formalPath": "/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app/Contents/PlugIns/FCP-BeautyGirl XPC Service.pluginkit",
|
||||||
|
"output": " com.dayu.fcpbeautygirl.fxplug(1.1)\t6C990AD2-B58E-4C2F-91A4-927849E7AA10\t2026-10-22 10:38:29 +0000\t/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app/Contents/PlugIns/FCP-BeautyGirl XPC Service.pluginkit\n (1 plug-in)\n"
|
||||||
|
},
|
||||||
|
"removedGeneratedPaths": [
|
||||||
|
"/Users/dayu/Documents/PaintFCP/build/delivery/legacy-beatygril.app",
|
||||||
|
"/tmp/fcp-beautygirl-release",
|
||||||
|
"/Users/dayu/Documents/PaintFCP/build/delivery/notarization.zip"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
2026-10-22 18:30:11.816 host-tests[35227:8446515] FBBA: creating VNFaceBBoxAligner from VNFaceDetectorRevision2: VNFaceDetectorRevision2
|
||||||
|
Default IOSurface maximum byte difference: 0
|
||||||
|
Alternate destination tag maximum byte difference: 0
|
||||||
|
Anatomy default 0/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||||
|
Anatomy default 0/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||||
|
Anatomy default 1/0 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||||
|
Anatomy default 1/1 max=0 mean=0.0000000 eye=0/0 chin=0 inverted=0
|
||||||
|
Anatomy big-eye 0/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||||
|
Anatomy big-eye 0/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||||
|
Anatomy big-eye 1/0 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||||
|
Anatomy big-eye 1/1 max=2 mean=0.0008917 eye=33510/33880 chin=0 inverted=0
|
||||||
|
Anatomy chin-positive 0/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||||
|
Anatomy chin-positive 0/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||||
|
Anatomy chin-positive 1/0 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||||
|
Anatomy chin-positive 1/1 max=1 mean=0.0001459 eye=0/0 chin=116812 inverted=0
|
||||||
|
Anatomy chin-negative 0/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||||
|
Anatomy chin-negative 0/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||||
|
Anatomy chin-negative 1/0 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||||
|
Anatomy chin-negative 1/1 max=1 mean=0.0000849 eye=0/0 chin=60426 inverted=0
|
||||||
|
Anatomy short-positive 0/0 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||||
|
Anatomy short-positive 0/1 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||||
|
Anatomy short-positive 1/0 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||||
|
Anatomy short-positive 1/1 max=2 mean=0.0011072 eye=0/0 chin=285953 inverted=0
|
||||||
|
Anatomy short-negative 0/0 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||||
|
Anatomy short-negative 0/1 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||||
|
Anatomy short-negative 1/0 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||||
|
Anatomy short-negative 1/1 max=2 mean=0.0008583 eye=0/0 chin=225648 inverted=0
|
||||||
|
Anatomy jaw 0/0 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||||
|
Anatomy jaw 0/1 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||||
|
Anatomy jaw 1/0 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||||
|
Anatomy jaw 1/1 max=1 mean=0.0001974 eye=0/0 chin=12951 inverted=0
|
||||||
|
Anatomy v-face 0/0 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||||
|
Anatomy v-face 0/1 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||||
|
Anatomy v-face 1/0 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||||
|
Anatomy v-face 1/1 max=1 mean=0.0001240 eye=0/0 chin=39246 inverted=0
|
||||||
|
Legacy fallback upright comparison: max=2 mean=0.0010357
|
||||||
|
Host adapter: 370 checks, 0 failures
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Inspector: 227 checks, 0 failures
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"status": "verified",
|
||||||
|
"installedProduct": {
|
||||||
|
"path": "/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app",
|
||||||
|
"bundleId": "com.dayu.fcpbeautygirl",
|
||||||
|
"version": "1.3.2"
|
||||||
|
},
|
||||||
|
"signatureAllArchitecturesVerified": true,
|
||||||
|
"scopedInventory": {
|
||||||
|
"roots": [
|
||||||
|
"/Applications",
|
||||||
|
"/Library/Plug-Ins/FxPlug",
|
||||||
|
"/Users/dayu/Library/Plug-Ins/FxPlug",
|
||||||
|
"/Users/dayu/Documents/PaintFCP",
|
||||||
|
"/Users/dayu/Desktop",
|
||||||
|
"/Users/dayu/Downloads",
|
||||||
|
"/Users/dayu/Library/Developer/Xcode/DerivedData",
|
||||||
|
"/tmp/fcp-beautygirl-release",
|
||||||
|
"/tmp/paintfcp-build-20261021"
|
||||||
|
],
|
||||||
|
"products": [
|
||||||
|
{
|
||||||
|
"path": "/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app",
|
||||||
|
"bundleId": "com.dayu.fcpbeautygirl",
|
||||||
|
"version": "1.3.2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"errors": [],
|
||||||
|
"scope": "Listed roots only; not all mounted volumes"
|
||||||
|
},
|
||||||
|
"legacyPluginOriginalPathAbsent": true,
|
||||||
|
"filterUUIDPreserved": "FB14B0E6-59B2-4836-916F-CD0C559E9241",
|
||||||
|
"templateBytesUnchanged": true,
|
||||||
|
"nativeOldProjectReopen": "pending_user"
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
........
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Ran 8 tests in 2.805s
|
||||||
|
|
||||||
|
OK
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
........
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Ran 8 tests in 0.029s
|
||||||
|
|
||||||
|
OK
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
2026-10-22 18:30:08.818 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:08.826 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,180) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.311 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.8,0.3) setter=(1152,-432) readback=(0.8,0.3) mode=centered-pixels verified=1
|
||||||
|
2026-10-22 18:30:09.311 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.7,0.4) objectBounds=(-1920,-1080,3840,2160) canvas=(152,78) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.359 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.8,0.3) setter=(0.8,0.3) readback=(0.12345,0.87654) mode=normalized verified=0
|
||||||
|
2026-10-22 18:30:09.359 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.75,0.25) setter=(0.75,0.25) readback=(0.75,0.25) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:09.360 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.75,0.25) objectBounds=(-100,-50,200,100) canvas=(160,60) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.409 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.625,0.375) setter=(0.625,0.375) readback=(0.625,0.375) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:09.409 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.625,0.375) objectBounds=(-100,-50,200,100) canvas=(240,60) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.457 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.25,0.75) setter=(0.25,0.75) readback=(0.25,0.75) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:09.457 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(144,180) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.506 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:09.506 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0,1) objectBounds=(-100,-50,200,100) canvas=(100,140) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.574 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(nan,nan) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.628 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:09.629 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(inf,nan) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.689 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:09.690 osc-tests[35208:8446417] PGFaceOSC coordinates selection=(0.25,0.75) objectBounds=(-100,-50,200,100) canvas=(80,nan) surface=320x240 origin=0
|
||||||
|
2026-10-22 18:30:09.742 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||||
|
2026-10-22 18:30:09.742 osc-tests[35208:8446417] PGFaceOSC point-write desired=(0.5,0.5) setter=(0.5,0.5) readback=(0.5,0.5) mode=normalized verified=1
|
||||||
|
OSC adapter: 98 checks, 0 failures
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"status": "verified",
|
||||||
|
"version": "1.3.2",
|
||||||
|
"build": "17",
|
||||||
|
"package": "releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg",
|
||||||
|
"bytes": 4889706,
|
||||||
|
"sha256": "20a88dacf68cc8812f5af86cfe94c1c0614414a68a019eaeac7ca9d078165ae1",
|
||||||
|
"sourceApp": "/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app",
|
||||||
|
"sourceCommit": "767bba8ac11e9bf9268a1e02d1a06d3c120c46aa",
|
||||||
|
"motionSource": "/Users/dayu/Movies/Motion Templates.localized/Effects.localized/大鱼磨皮瘦脸",
|
||||||
|
"motionFiles": [
|
||||||
|
{
|
||||||
|
"file": "大鱼人像美化/Drop Zone.tiff",
|
||||||
|
"sha256": "a7f8e3a2a431dbb3ce9e777040bb55e701cfe9ab9632e8cbb10359732bc8692e",
|
||||||
|
"locked": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "大鱼人像美化/large.png",
|
||||||
|
"sha256": "a02ddb255b1ae255c749bb837a759e2dee1c3b8ffb9bdc1167957761bd5a1b97",
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "大鱼人像美化/small.png",
|
||||||
|
"sha256": "1552b838dd88f60dee0795e20aaca652f9c558ecefc93500e895fbff77c2a4d5",
|
||||||
|
"locked": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "大鱼人像美化/大鱼人像美化.moef",
|
||||||
|
"sha256": "e9fa97dc14323d0daa7d3d61b06a78ba4000a70ab9f5e67ebffd750d49df1e15",
|
||||||
|
"locked": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packager": "/Applications/PKG工坊.app/Contents/MacOS/PKG工坊",
|
||||||
|
"productMigration": "PKG Forge base plus identity-checked backup/rollback block; final package freshly signed, notarized and stapled",
|
||||||
|
"notarization": {
|
||||||
|
"message": "Processing complete",
|
||||||
|
"id": "4a831775-2317-4372-a4cc-102415657ea3",
|
||||||
|
"status": "Accepted"
|
||||||
|
},
|
||||||
|
"realInstallerExecuted": false
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
/Users/dayu/Documents/PaintFCP/releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg: accepted
|
||||||
|
source=Notarized Developer ID
|
||||||
|
origin=Developer ID Installer: zhong luo (B3W25FX5H5)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"message": "Processing complete",
|
||||||
|
"id": "4a831775-2317-4372-a4cc-102415657ea3",
|
||||||
|
"status": "Accepted"
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
Package "FCP-BeautyGirl-1.3.2.pkg":
|
||||||
|
Status: signed by a developer certificate issued by Apple for distribution
|
||||||
|
Notarization: trusted by the Apple notary service
|
||||||
|
Signed with a trusted timestamp on: 2026-10-22 10:40:28 +0000
|
||||||
|
Certificate Chain:
|
||||||
|
1. Developer ID Installer: zhong luo (B3W25FX5H5)
|
||||||
|
Expires: 2027-02-01 22:12:15 +0000
|
||||||
|
SHA256 Fingerprint:
|
||||||
|
4D AC CD 04 A5 4C 7E F8 13 13 A2 ED D1 C2 C0 D0 29 EF FA BF 7B 53
|
||||||
|
5A 43 C8 72 4D C4 0A A3 94 34
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
2. Developer ID Certification Authority
|
||||||
|
Expires: 2027-02-01 22:12:15 +0000
|
||||||
|
SHA256 Fingerprint:
|
||||||
|
7A FC 9D 01 A6 2F 03 A2 DE 96 37 93 6D 4A FE 68 09 0D 2D E1 8D 03
|
||||||
|
F2 9C 88 CF B0 B1 BA 63 58 7F
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
3. Apple Root CA
|
||||||
|
Expires: 2035-02-09 21:40:36 +0000
|
||||||
|
SHA256 Fingerprint:
|
||||||
|
B0 B1 73 0E CB C7 FF 45 05 14 2C 49 F1 29 5E 6E DA 6B CA ED 7E 2C
|
||||||
|
68 C5 BE 91 B5 A1 10 01 F0 24
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
productsign: using timestamp authority for signature
|
||||||
|
productsign: signing product with identity "Developer ID Installer: zhong luo (B3W25FX5H5)" from keychain /Users/dayu/Library/Keychains/login.keychain-db
|
||||||
|
productsign: adding certificate "Developer ID Certification Authority"
|
||||||
|
productsign: adding certificate "Apple Root CA"
|
||||||
|
productsign: Wrote signed product archive to /Users/dayu/Documents/PaintFCP/releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Processing: /Users/dayu/Documents/PaintFCP/releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg
|
||||||
|
Processing: /Users/dayu/Documents/PaintFCP/releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg
|
||||||
|
The staple and validate action worked!
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"package": "releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg",
|
||||||
|
"bytes": 4889706,
|
||||||
|
"sha256": "20a88dacf68cc8812f5af86cfe94c1c0614414a68a019eaeac7ca9d078165ae1",
|
||||||
|
"version": "1.3.2",
|
||||||
|
"build": "17",
|
||||||
|
"app_files_compared": 34,
|
||||||
|
"app_byte_and_symlink_equality": true,
|
||||||
|
"template_files": {
|
||||||
|
"大鱼人像美化.moef": "e9fa97dc14323d0daa7d3d61b06a78ba4000a70ab9f5e67ebffd750d49df1e15",
|
||||||
|
"Drop Zone.tiff": "a7f8e3a2a431dbb3ce9e777040bb55e701cfe9ab9632e8cbb10359732bc8692e",
|
||||||
|
"large.png": "a02ddb255b1ae255c749bb837a759e2dee1c3b8ffb9bdc1167957761bd5a1b97",
|
||||||
|
"small.png": "1552b838dd88f60dee0795e20aaca652f9c558ecefc93500e895fbff77c2a4d5"
|
||||||
|
},
|
||||||
|
"locked_relative_paths": [
|
||||||
|
"大鱼人像美化/large.png",
|
||||||
|
"大鱼人像美化/small.png"
|
||||||
|
],
|
||||||
|
"script_sha256": {
|
||||||
|
"preinstall": "b0562f7705c84a2f34e31df67a4f0d429e60083bab122dad99f56a4b266c0174",
|
||||||
|
"postinstall": "d147ccab1c428659fd2b0ed60e77399d1eb5910d1049dcdcbdbfc88fd3824300"
|
||||||
|
},
|
||||||
|
"isolated_script_tests": [
|
||||||
|
"fresh install",
|
||||||
|
"replace old locked thumbnail",
|
||||||
|
"partial copy failure restores old bytes and locks"
|
||||||
|
],
|
||||||
|
"isolation_changes": [
|
||||||
|
"Console identity/home redirected to task fixture",
|
||||||
|
"chown replaced with true",
|
||||||
|
"FxPlug verification skipped; formal app signature and discovery verified separately"
|
||||||
|
],
|
||||||
|
"real_installer_execution": false,
|
||||||
|
"app_and_template_installed": "APP installed through signed delivery workflow; formal template files matched the specified installed category, not changed by running this PKG",
|
||||||
|
"fonts": "No editable third-party font dependency; promotional lettering baked into PNG. No optional font ZIP needed."
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"package": "releases/1.3.2/FCP-BeautyGirl-1.3.2.pkg",
|
||||||
|
"bytes": 4889706,
|
||||||
|
"sha256": "20a88dacf68cc8812f5af86cfe94c1c0614414a68a019eaeac7ca9d078165ae1",
|
||||||
|
"version": "1.3.2",
|
||||||
|
"build": "17",
|
||||||
|
"app_files_compared": 34,
|
||||||
|
"app_byte_and_symlink_equality": true,
|
||||||
|
"template_files": {
|
||||||
|
"大鱼人像美化.moef": "e9fa97dc14323d0daa7d3d61b06a78ba4000a70ab9f5e67ebffd750d49df1e15",
|
||||||
|
"Drop Zone.tiff": "a7f8e3a2a431dbb3ce9e777040bb55e701cfe9ab9632e8cbb10359732bc8692e",
|
||||||
|
"large.png": "a02ddb255b1ae255c749bb837a759e2dee1c3b8ffb9bdc1167957761bd5a1b97",
|
||||||
|
"small.png": "1552b838dd88f60dee0795e20aaca652f9c558ecefc93500e895fbff77c2a4d5"
|
||||||
|
},
|
||||||
|
"locked_relative_paths": [
|
||||||
|
"大鱼人像美化/large.png",
|
||||||
|
"大鱼人像美化/small.png"
|
||||||
|
],
|
||||||
|
"script_sha256": {
|
||||||
|
"preinstall": "b0562f7705c84a2f34e31df67a4f0d429e60083bab122dad99f56a4b266c0174",
|
||||||
|
"postinstall": "d147ccab1c428659fd2b0ed60e77399d1eb5910d1049dcdcbdbfc88fd3824300"
|
||||||
|
},
|
||||||
|
"isolated_script_tests": [
|
||||||
|
"fresh install",
|
||||||
|
"replace old locked thumbnail",
|
||||||
|
"partial copy failure restores old bytes and locks"
|
||||||
|
],
|
||||||
|
"isolation_changes": [
|
||||||
|
"Console identity/home redirected to task fixture",
|
||||||
|
"chown replaced with true",
|
||||||
|
"FxPlug verification skipped; formal app signature and discovery verified separately"
|
||||||
|
],
|
||||||
|
"real_installer_execution": false,
|
||||||
|
"app_and_template_installed": "APP installed through signed delivery workflow; formal template files matched the specified installed category, not changed by running this PKG",
|
||||||
|
"fonts": "No editable third-party font dependency; promotional lettering baked into PNG. No optional font ZIP needed."
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
识别到 2 个安装内容:
|
||||||
|
- FCP-BeautyGirl.app
|
||||||
|
类型:FxPlug 插件
|
||||||
|
目录:/Library/Plug-Ins/FxPlug
|
||||||
|
状态:已签名并公证,保留隔离属性,自动验证并修复注册;失败时打开 APP 所在目录
|
||||||
|
- 大鱼磨皮瘦脸
|
||||||
|
类型:FCP 效果
|
||||||
|
目录:~/Movies/Motion Templates.localized/Effects.localized
|
||||||
|
状态:非 APP,保留隔离属性
|
||||||
|
|
||||||
|
识别完成,未生成安装包。
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
识别到 2 个安装内容:
|
||||||
|
- FCP-BeautyGirl.app
|
||||||
|
类型:FxPlug 插件
|
||||||
|
目录:/Library/Plug-Ins/FxPlug
|
||||||
|
状态:已签名并公证,保留隔离属性,自动验证并修复注册;失败时打开 APP 所在目录
|
||||||
|
- 大鱼磨皮瘦脸
|
||||||
|
类型:FCP 效果
|
||||||
|
目录:~/Movies/Motion Templates.localized/Effects.localized
|
||||||
|
状态:非 APP,保留隔离属性
|
||||||
|
|
||||||
|
完成:/Users/dayu/Documents/PaintFCP/build/package-1.3.2/base/FCP-BeautyGirl-1.3.2.pkg
|
||||||
|
|
||||||
|
本次唯一标识:com.dayu.fcppackage.b20261022104001942.tt2yn7vc
|
||||||
|
安装包版本:1.3.2(继承 FCP-BeautyGirl.app)
|
||||||
|
[正在准备内容]
|
||||||
|
正在整理 2 个内容项
|
||||||
|
[正在生成安装包]
|
||||||
|
正在构建组件包
|
||||||
|
[正在签名]
|
||||||
|
正在使用 Developer ID Installer 签名
|
||||||
|
[正在等待 Apple 公证]
|
||||||
|
已提交 Apple,公证通常需要几分钟
|
||||||
|
[正在粘附公证票据]
|
||||||
|
公证已通过,正在粘附票据
|
||||||
|
[正在验证结果]
|
||||||
|
正在检查签名和安装包结构
|
||||||
|
签名、包结构与公证票据验证通过
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"baseline": "d1137edd836cc360c53d21c104a06f2435382441",
|
||||||
|
"signedSource": "767bba8ac11e9bf9268a1e02d1a06d3c120c46aa",
|
||||||
|
"renderAndStateFilesCompared": [
|
||||||
|
"PGFaceSelectOSC.m",
|
||||||
|
"PGParameterIDs.h",
|
||||||
|
"PGInspectorState.m",
|
||||||
|
"PGBeautyTypes.h",
|
||||||
|
"PGBeautyRenderer.m",
|
||||||
|
"PGFaceProcessor.h",
|
||||||
|
"FCPBeautyGirlPlugIn.h",
|
||||||
|
"PGInspectorView.m",
|
||||||
|
"main.m",
|
||||||
|
"PGFaceProcessor.m",
|
||||||
|
"PGBeautyRenderer.h",
|
||||||
|
"PGInspectorState.h",
|
||||||
|
"FCPBeautyGirlPlugIn.m",
|
||||||
|
"PGInspectorView.h"
|
||||||
|
],
|
||||||
|
"normalization": "Only entry class/header names, log subsystem and NSError domain differ; pixel and archived-state logic bytes unchanged.",
|
||||||
|
"regressionChecks": 1901,
|
||||||
|
"migrationUnitScenarios": 8,
|
||||||
|
"installerMigrationScenarios": "7 runtime scenarios passed; final package-block check runs after build."
|
||||||
|
}
|
||||||
+16
-16
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
更新时间:2026-10-22,Asia/Shanghai。项目根目录:`/Users/dayu/Documents/PaintFCP`。
|
更新时间:2026-10-22,Asia/Shanghai。项目根目录:`/Users/dayu/Documents/PaintFCP`。
|
||||||
|
|
||||||
当前正式 APP 为 **1.3.1(16)**,通用 Release、正式签名、Apple公证、票据、Gatekeeper和正式路径注册均已核验,临时APP副本已清理。1901项自动回归及1561项重叠真实帧几何ASan通过,V脸和新磨皮参数的最终宿主视觉仍由用户实测。签名源码 `7fa3298e022946e77dfd8cfba1bb5ff2c2a6361f`;本次PKG由本机PKG工坊CLI打包,包含用户指定已安装的「大鱼磨皮瘦脸」分类及4项模板资源。文章15593、GitHub和大鱼Release均已更新1.3.1,main与标签已同步;线上下载和恢复的具体核验边界见本版本回执。
|
当前正式 APP 为 **1.3.2(17)**,工程、APP、插件服务及应用标识统一为 FCP-BeautyGirl。通用 Release、正式签名、Apple 公证、票据、Gatekeeper 和正式路径注册均已核验,旧 APP 与临时副本已清理。签名源码 `767bba8ac11e9bf9268a1e02d1a06d3c120c46aa`,发行标签 `v1.3.2`。1901 项自动回归、8 项 APP 身份迁移、8 项最终安装脚本身份迁移及模板隔离测试通过。滤镜 UUID、参数编号和归档保持原格式;新身份下的旧工程重开与最终原生视觉仍由用户实测。安装包基础由本机 PKG 工坊 CLI 生成,加入身份迁移后重新签名公证,包含指定已安装的「大鱼磨皮瘦脸」分类四项资源。文章 15593、GitHub 与大鱼 Release 沿用原入口,发布同步结果见本版回执。
|
||||||
|
|
||||||
代码由 **OpenAI + Codex 全程编写,站长仅参与调试和测试**。文章和仓库须保留这个表述,不使用“站长原创代码”等说法。免费版本无需账号、激活码或付费授权;“自动注册”指系统插件注册。
|
代码由 **OpenAI + Codex 全程编写,站长仅参与调试和测试**。文章和仓库须保留这个表述,不使用“站长原创代码”等说法。免费版本无需账号、激活码或付费授权;“自动注册”指系统插件注册。
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
| 入口 | 用途 |
|
| 入口 | 用途 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| [1.3.1 交付回执](verification/v1.3.1/delivery-receipt.json) | 当前安装版、签名源码、公证、清理及原生视觉待测范围 |
|
| [1.3.2 交付回执](verification/v1.3.2/delivery-receipt.json) | 当前安装版、签名源码、公证、清理及原生视觉待测范围 |
|
||||||
| [README](../README.md) | 产品介绍、使用与版本变化 |
|
| [README](../README.md) | 产品介绍、使用与版本变化 |
|
||||||
| [恢复说明](../RECOVERY.md) | 精确源码节点、依赖、远端恢复记录 |
|
| [恢复说明](../RECOVERY.md) | 精确源码节点、依赖、远端恢复记录 |
|
||||||
| [GitHub 同步说明](GitHub同步说明.md) | 两个远端、公开克隆及 Release 验证 |
|
| [GitHub 同步说明](GitHub同步说明.md) | 两个远端、公开克隆及 Release 验证 |
|
||||||
@@ -30,12 +30,12 @@
|
|||||||
| 项目 | 当前值 |
|
| 项目 | 当前值 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 显示名称 | 大鱼人像美化 |
|
| 显示名称 | 大鱼人像美化 |
|
||||||
| Xcode 产品名 | `beatygril`,保留现有拼写 |
|
| Xcode 产品名 | `FCP-BeautyGirl` |
|
||||||
| APP 版本 | `1.3.1` / `16`,arm64 与 x86_64 通用版本 |
|
| APP 版本 | `1.3.2` / `17`,arm64 与 x86_64 通用版本 |
|
||||||
| 唯一正式 APP | `/Library/Plug-Ins/FxPlug/beatygril.app` |
|
| 唯一正式 APP | `/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app` |
|
||||||
| 主 Bundle ID | `com.dayu.beatygril` |
|
| 主 Bundle ID | `com.dayu.fcpbeautygirl` |
|
||||||
| 嵌套插件 | `Contents/PlugIns/beatygril XPC Service.pluginkit` |
|
| 嵌套插件 | `Contents/PlugIns/FCP-BeautyGirl XPC Service.pluginkit` |
|
||||||
| 插件 Bundle ID | `com.dayu.beatygril.fxplug` |
|
| 插件 Bundle ID | `com.dayu.fcpbeautygirl.fxplug` |
|
||||||
| 滤镜 UUID | `FB14B0E6-59B2-4836-916F-CD0C559E9241` |
|
| 滤镜 UUID | `FB14B0E6-59B2-4836-916F-CD0C559E9241` |
|
||||||
| 自定义面板参数 ID | `210` |
|
| 自定义面板参数 ID | `210` |
|
||||||
| FCP 效果分类 | 大鱼磨皮瘦脸 → 大鱼人像美化 |
|
| FCP 效果分类 | 大鱼磨皮瘦脸 → 大鱼人像美化 |
|
||||||
@@ -54,13 +54,13 @@
|
|||||||
|
|
||||||
## 源码结构
|
## 源码结构
|
||||||
|
|
||||||
Xcode 工程:`beatygril/beatygril.xcodeproj`。外层 scheme 为 `Wrapper Application`,插件 target 为 `XPC Service`。
|
Xcode 工程:`FCP-BeautyGirl/FCP-BeautyGirl.xcodeproj`。外层 scheme 为 `FCP-BeautyGirl`,插件 target 为 `FCP-BeautyGirl XPC Service`。
|
||||||
|
|
||||||
下表插件文件均位于 `beatygril/beatygril/Plugin/`。
|
下表插件文件均位于 `FCP-BeautyGirl/FCP-BeautyGirl/Plugin/`。
|
||||||
|
|
||||||
| 文件或目录 | 职责与修改入口 |
|
| 文件或目录 | 职责与修改入口 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `beatygrilPlugIn.m` | FxPlug 参数、宿主 action、图像适配、渲染状态与整体混合 |
|
| `FCPBeautyGirlPlugIn.m` | FxPlug 参数、宿主 action、图像适配、渲染状态与整体混合 |
|
||||||
| `PGFaceProcessor.m` | Vision 检测、76 点、自动跟随、几何稳定、局部变形和几何蒙版 |
|
| `PGFaceProcessor.m` | Vision 检测、76 点、自动跟随、几何稳定、局部变形和几何蒙版 |
|
||||||
| `PGBeautyRenderer.m` | 磨皮、肤色、细节、牙齿和眼睛等外观处理 |
|
| `PGBeautyRenderer.m` | 磨皮、肤色、细节、牙齿和眼睛等外观处理 |
|
||||||
| `PGInspectorView.m` | AppKit 卡片、滑杆、数值框、开关、重置和连续提交 |
|
| `PGInspectorView.m` | AppKit 卡片、滑杆、数值框、开关、重置和连续提交 |
|
||||||
@@ -120,9 +120,9 @@ Xcode 工程:`beatygril/beatygril.xcodeproj`。外层 scheme 为 `Wrapper Appl
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
./scripts/test.sh
|
./scripts/test.sh
|
||||||
PAINTFCP_HOST_ASAN=1 ./scripts/test-host.sh
|
FCP_BEAUTYGIRL_HOST_ASAN=1 ./scripts/test-host.sh
|
||||||
PAINTFCP_OSC_ASAN=1 ./scripts/test-osc.sh
|
FCP_BEAUTYGIRL_OSC_ASAN=1 ./scripts/test-osc.sh
|
||||||
PAINTFCP_INSPECTOR_ASAN=1 ./scripts/test-inspector.sh
|
FCP_BEAUTYGIRL_INSPECTOR_ASAN=1 ./scripts/test-inspector.sh
|
||||||
python3 scripts/inspector-template.py audit 'Templates/大鱼人像美化/大鱼人像美化.moef'
|
python3 scripts/inspector-template.py audit 'Templates/大鱼人像美化/大鱼人像美化.moef'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ python3 scripts/inspector-template.py audit 'Templates/大鱼人像美化/大鱼
|
|||||||
| 资源 | 文件 |
|
| 资源 | 文件 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 项目封面 | `Assets/Artwork/portrait-cover.png` |
|
| 项目封面 | `Assets/Artwork/portrait-cover.png` |
|
||||||
| APP 说明图 | `beatygril/beatygril/Wrapper Application/Resources/LauncherInfo.png` |
|
| APP 说明图 | `FCP-BeautyGirl/FCP-BeautyGirl/Wrapper Application/Resources/LauncherInfo.png` |
|
||||||
| 大缩略图 | `Templates/大鱼人像美化/large.png`,640×360 |
|
| 大缩略图 | `Templates/大鱼人像美化/large.png`,640×360 |
|
||||||
| 小缩略图 | `Templates/大鱼人像美化/small.png`,192×108 |
|
| 小缩略图 | `Templates/大鱼人像美化/small.png`,192×108 |
|
||||||
| 生成记录 | `docs/design/artwork-manifest.json`、`artwork-prompt.json` |
|
| 生成记录 | `docs/design/artwork-manifest.json`、`artwork-prompt.json` |
|
||||||
@@ -183,7 +183,7 @@ ls -lO "$HOME/Movies/Motion Templates.localized/Effects.localized/大鱼磨皮
|
|||||||
python3 scripts/deliver.py
|
python3 scripts/deliver.py
|
||||||
```
|
```
|
||||||
|
|
||||||
脚本获取 `/Users/dayu/.codex/app-delivery-locks/com.dayu.beatygril.lock`,使用固定暂存 `/tmp/paintfcp-build-20261021`,记录到 `build/delivery/`。它构建通用 Release,由内到外签名 Framework、嵌套插件、外层 APP,验证严格签名,提交公证并要求 `Accepted`,粘附并验证票据,等待宿主退出后替换唯一正式路径,检查 Gatekeeper 与 PluginKit。默认停在 `HOST_VALIDATION_PENDING`,完成实际宿主验收及副本盘点后才回车进入清理。
|
脚本同时获取新ID与product.json所列旧ID的共享交付锁,主锁为 `/Users/dayu/.codex/app-delivery-locks/com.dayu.fcpbeautygirl.lock`,使用固定暂存 `/tmp/fcp-beautygirl-release`,记录到 `build/delivery/`。它构建通用 Release,由内到外签名 Framework、嵌套插件、外层 APP,验证严格签名,提交公证并要求 `Accepted`,粘附并验证票据,等待宿主退出后替换唯一正式路径,检查 Gatekeeper 与 PluginKit。默认停在 `HOST_VALIDATION_PENDING`,完成实际宿主验收及副本盘点后才回车进入清理。
|
||||||
|
|
||||||
| 选项 | 用途 |
|
| 选项 | 用途 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
|||||||
二进制文件未显示。
@@ -0,0 +1,19 @@
|
|||||||
|
# FCP-BeautyGirl · 大鱼人像美化 1.3.2(17)
|
||||||
|
|
||||||
|
统一工程、APP、插件服务、源码类名和应用标识的拼写。主 Bundle ID 为 `com.dayu.fcpbeautygirl`,插件 ID 为 `com.dayu.fcpbeautygirl.fxplug`,唯一正式安装路径为 `/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app`。
|
||||||
|
|
||||||
|
安装器核对旧版的 Bundle ID、签名团队和滤镜 UUID 后迁移旧 APP;失败时恢复旧版,避免新旧服务并存。滤镜 UUID、参数编号和面板归档保留,渲染逻辑沿用 1.3.1。1901 项自动回归、8 项 APP 迁移测试、8 项安装器身份迁移测试,以及模板初装、更新与失败回滚隔离检查通过。更名后的旧工程重开与原生画面仍需用户实测。
|
||||||
|
|
||||||
|
- 文章:https://dayu.media/15593/
|
||||||
|
- GitHub:https://github.com/dayumeida/FCP-BeautyGirl
|
||||||
|
- 大鱼备份:https://dayu.media/git/dayu/paintfcp-fxplug
|
||||||
|
- 发布标签:v1.3.2
|
||||||
|
- 正式 APP 签名源码:767bba8ac11e9bf9268a1e02d1a06d3c120c46aa
|
||||||
|
- APP 公证:Accepted 559eedf0-048f-4d0e-b013-6a187695f2da
|
||||||
|
- PKG 公证:Accepted 4a831775-2317-4372-a4cc-102415657ea3
|
||||||
|
- PKG:FCP-BeautyGirl-1.3.2.pkg,4,889,706 bytes
|
||||||
|
- SHA-256:20a88dacf68cc8812f5af86cfe94c1c0614414a68a019eaeac7ca9d078165ae1
|
||||||
|
|
||||||
|
本机 PKG 工坊 CLI 生成基础包,加入本产品的旧身份迁移与回滚段后,对最终包重新签名、公证和粘附票据。包含用户指定的「大鱼磨皮瘦脸」分类:大鱼人像美化.moef、Drop Zone.tiff、large.png 和 small.png。有效载荷与正式 APP、四个模板文件一致;恢复两张缩略图的锁定。签名、公证票据、Gatekeeper 和隔离安装脚本核验通过,未实际运行本 PKG 安装器;本机 APP 已通过正式交付流程安装。
|
||||||
|
|
||||||
|
安装前保存并退出 Final Cut Pro 和 Motion。Final Cut Pro 在「效果 → 大鱼磨皮瘦脸 → 大鱼人像美化」中使用。免费开源,无需激活码。代码由 OpenAI + Codex 全程编写,站长仅参与调试和测试。Apple SDK 及相关资源遵循各自许可。
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"title": "大鱼人像美化 1.3.2:FCP / Motion 免费开源自动美颜插件",
|
||||||
|
"status": "publish",
|
||||||
|
"content": "<!-- wp:paragraph -->\n<p>大鱼人像美化是一款适用于 Final Cut Pro 与 Motion 的免费开源人像插件,把磨皮、美白和脸型调整放进同一块原生卡片面板。插件会识别当前画面中的人脸并自动跟随,无需先点击分析;你可以按素材需要调整强度,拖动滑杆时持续查看效果。</p>\n<!-- /wp:paragraph -->\n<!-- wp:paragraph -->\n<p><strong>代码由 OpenAI + Codex 全程编写,站长仅参与调试和测试。</strong></p>\n<!-- /wp:paragraph -->\n\n<!-- wp:image {\"sizeSlug\":\"full\"} -->\n<figure class=\"wp-block-image size-full\"><img src=\"https://dayu.media/wp-content/uploads/2026/10/1792604750-357ca780597c39f.png\" alt=\"大鱼人像美化古风宣传封面,展示自动瘦脸、自动跟随与自动美颜\" /><figcaption class=\"wp-element-caption\">古风宣传插画;面部线条用于示意瘦脸与跟随功能。</figcaption></figure>\n<!-- /wp:image -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">可以做什么</h2>\n<!-- /wp:heading -->\n\n<!-- wp:list {\"className\":\"wp-block-list\"} -->\n<ul class=\"wp-block-list\"><!-- wp:list-item -->\n<li>磨皮:磨皮程度、微细锐化、五官保护和非肤色区保护分别调节;全局磨皮与锐化保留在更多设置。</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>美白:肤色预设、肤色亮度、皮肤色相和牙齿美白。</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>脸型:瘦脸、大眼、短脸、窄脸、下巴、V 脸、下颌骨、颧骨与小头调整。</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>自动跟随:默认跟随主要人脸,也提供多人模式、防跳脸范围与检测框预览。</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li>实时预览:滑杆、数值、单项开关和重置集中在同一面板,便于反复对比。</li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:paragraph -->\n<p>自动识别负责定位处理区域,效果强度由你控制。建议先从较小的数值开始;多人交叉、严重遮挡和极端侧脸的结果需要结合具体素材检查。</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">版本与下载</h2>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph -->\n<p>当前版本 <strong>1.3.2(17)</strong>,支持 macOS 13 或更高版本,包含 Apple Silicon 与 Intel 两种架构。下载包包含 FxPlug4 程序和一个配套 FCP 效果模板。APP 与 PKG 均已完成 Developer ID 正式签名、Apple 公证和票据粘附;安装包为所有用户免费资源。</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>1.3.2 将工程、APP 与应用标识统一为 FCP-BeautyGirl;安装器会核对身份并迁移旧版程序,保留原滤镜 UUID 和参数存储格式。此版本沿用 1.3.1 的 V 脸下颌修复、微细锐化、连续五官保护和非肤色区保护。1901 项自动回归及安装迁移检查通过;本次更名后的旧工程重开与原生画面仍需结合实际素材检查。</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">安装</h2>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph -->\n<p>安装前先保存工作并退出 Final Cut Pro 和 Motion,安装期间保持关闭。运行本页提供的 PKG,按安装器提示完成安装;它会把程序安装到 <code>/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app</code>,把配套效果安装到当前登录用户的 Motion Templates 目录,并自动验证和修复系统插件注册。</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>本插件免费开源,<strong>无需激活码、付费注册或账号授权</strong>。主 APP 打开时显示说明图,窗口显示三秒后自动退出;宿主中的滤镜由独立服务运行。安装器还会重新锁定两张缩略图,避免被宿主自动替换。</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:image {\"sizeSlug\":\"full\"} -->\n<figure class=\"wp-block-image size-full\"><img src=\"https://dayu.media/wp-content/uploads/2026/10/1792604743-1c99c2ba53c7614.png\" alt=\"主程序说明页:免费开源,自动注册,无需激活码,启动三秒后自动退出\" /></figure>\n<!-- /wp:image -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">使用</h2>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Final Cut Pro:打开<strong>效果</strong>浏览器,找到<strong>大鱼磨皮瘦脸</strong>分类,将<strong>大鱼人像美化</strong>添加到人像片段。Motion:在原生滤镜资源库的<strong>大鱼</strong>分类中选择<strong>大鱼人像美化</strong>。</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:paragraph -->\n<p>在检查器中按需调节磨皮、美白和脸型。每项左侧的眼睛可暂时停用该项,数值会保留;右侧回转箭头用于重置。人脸会随画面自动更新,开启检测框预览可以检查跟随位置。多人模式建议先用短片段观Line truncated
|
||||||
|
"excerpt": "1.3.2 将工程、APP 与应用 ID 统一为 FCP-BeautyGirl,安装自动迁移旧版。保留 V 脸下颌修复和磨皮参数,提供免费开源源码及签名公证安装包。",
|
||||||
|
"seo": {
|
||||||
|
"title": {
|
||||||
|
"enabled": true,
|
||||||
|
"value": "大鱼人像美化 1.3.2|FCP / Motion 免费开源自动美颜插件"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"enabled": true,
|
||||||
|
"value": "大鱼人像美化是适用于 Final Cut Pro 和 Motion 的免费开源 FxPlug4 插件。1.3.2 将工程、APP 和应用 ID 统一为 FCP-BeautyGirl,自动迁移旧版;保留 V 脸下颌修复及磨皮保护参数。提供 Apple 签名公证安装包和源码,无需激活码,附安装使用说明。"
|
||||||
|
},
|
||||||
|
"keywords": {
|
||||||
|
"enabled": true,
|
||||||
|
"value": "大鱼人像美化,FCP美颜插件,Motion磨皮,自动瘦脸,自动跟随,FxPlug4,免费开源"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"resource": {
|
||||||
|
"cao_info": [
|
||||||
|
{
|
||||||
|
"title": "版本",
|
||||||
|
"desc": "1.3.2(17)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "宿主",
|
||||||
|
"desc": "Final Cut Pro / Motion"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "系统",
|
||||||
|
"desc": "macOS 13 或更高版本"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "架构",
|
||||||
|
"desc": "Apple Silicon / Intel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "授权",
|
||||||
|
"desc": "免费开源,无需激活码"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>大鱼人像美化是一款适用于 Final Cut Pro 与 Motion 的免费开源人像插件,把磨皮、美白和脸型调整放进同一块原生卡片面板。插件会识别当前画面中的人脸并自动跟随,无需先点击分析;你可以按素材需要调整强度,拖动滑杆时持续查看效果。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p><strong>代码由 OpenAI + Codex 全程编写,站长仅参与调试和测试。</strong></p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:image {"sizeSlug":"full"} -->
|
||||||
|
<figure class="wp-block-image size-full"><img src="https://dayu.media/wp-content/uploads/2026/10/1792604750-357ca780597c39f.png" alt="大鱼人像美化古风宣传封面,展示自动瘦脸、自动跟随与自动美颜" /><figcaption class="wp-element-caption">古风宣传插画;面部线条用于示意瘦脸与跟随功能。</figcaption></figure>
|
||||||
|
<!-- /wp:image -->
|
||||||
|
|
||||||
|
<!-- wp:heading -->
|
||||||
|
<h2 class="wp-block-heading">可以做什么</h2>
|
||||||
|
<!-- /wp:heading -->
|
||||||
|
|
||||||
|
<!-- wp:list {"className":"wp-block-list"} -->
|
||||||
|
<ul class="wp-block-list"><!-- wp:list-item -->
|
||||||
|
<li>磨皮:磨皮程度、微细锐化、五官保护和非肤色区保护分别调节;全局磨皮与锐化保留在更多设置。</li>
|
||||||
|
<!-- /wp:list-item -->
|
||||||
|
|
||||||
|
<!-- wp:list-item -->
|
||||||
|
<li>美白:肤色预设、肤色亮度、皮肤色相和牙齿美白。</li>
|
||||||
|
<!-- /wp:list-item -->
|
||||||
|
|
||||||
|
<!-- wp:list-item -->
|
||||||
|
<li>脸型:瘦脸、大眼、短脸、窄脸、下巴、V 脸、下颌骨、颧骨与小头调整。</li>
|
||||||
|
<!-- /wp:list-item -->
|
||||||
|
|
||||||
|
<!-- wp:list-item -->
|
||||||
|
<li>自动跟随:默认跟随主要人脸,也提供多人模式、防跳脸范围与检测框预览。</li>
|
||||||
|
<!-- /wp:list-item -->
|
||||||
|
|
||||||
|
<!-- wp:list-item -->
|
||||||
|
<li>实时预览:滑杆、数值、单项开关和重置集中在同一面板,便于反复对比。</li>
|
||||||
|
<!-- /wp:list-item --></ul>
|
||||||
|
<!-- /wp:list -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>自动识别负责定位处理区域,效果强度由你控制。建议先从较小的数值开始;多人交叉、严重遮挡和极端侧脸的结果需要结合具体素材检查。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:heading -->
|
||||||
|
<h2 class="wp-block-heading">版本与下载</h2>
|
||||||
|
<!-- /wp:heading -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>当前版本 <strong>1.3.2(17)</strong>,支持 macOS 13 或更高版本,包含 Apple Silicon 与 Intel 两种架构。下载包包含 FxPlug4 程序和一个配套 FCP 效果模板。APP 与 PKG 均已完成 Developer ID 正式签名、Apple 公证和票据粘附;安装包为所有用户免费资源。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>1.3.2 将工程、APP 与应用标识统一为 FCP-BeautyGirl;安装器会核对身份并迁移旧版程序,保留原滤镜 UUID 和参数存储格式。此版本沿用 1.3.1 的 V 脸下颌修复、微细锐化、连续五官保护和非肤色区保护。1901 项自动回归及安装迁移检查通过;本次更名后的旧工程重开与原生画面仍需结合实际素材检查。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:heading -->
|
||||||
|
<h2 class="wp-block-heading">安装</h2>
|
||||||
|
<!-- /wp:heading -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>安装前先保存工作并退出 Final Cut Pro 和 Motion,安装期间保持关闭。运行本页提供的 PKG,按安装器提示完成安装;它会把程序安装到 <code>/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app</code>,把配套效果安装到当前登录用户的 Motion Templates 目录,并自动验证和修复系统插件注册。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>本插件免费开源,<strong>无需激活码、付费注册或账号授权</strong>。主 APP 打开时显示说明图,窗口显示三秒后自动退出;宿主中的滤镜由独立服务运行。安装器还会重新锁定两张缩略图,避免被宿主自动替换。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:image {"sizeSlug":"full"} -->
|
||||||
|
<figure class="wp-block-image size-full"><img src="https://dayu.media/wp-content/uploads/2026/10/1792604743-1c99c2ba53c7614.png" alt="主程序说明页:免费开源,自动注册,无需激活码,启动三秒后自动退出" /></figure>
|
||||||
|
<!-- /wp:image -->
|
||||||
|
|
||||||
|
<!-- wp:heading -->
|
||||||
|
<h2 class="wp-block-heading">使用</h2>
|
||||||
|
<!-- /wp:heading -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>Final Cut Pro:打开<strong>效果</strong>浏览器,找到<strong>大鱼磨皮瘦脸</strong>分类,将<strong>大鱼人像美化</strong>添加到人像片段。Motion:在原生滤镜资源库的<strong>大鱼</strong>分类中选择<strong>大鱼人像美化</strong>。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>在检查器中按需调节磨皮、美白和脸型。每项左侧的眼睛可暂时停用该项,数值会保留;右侧回转箭头用于重置。人脸会随画面自动更新,开启检测框预览可以检查跟随位置。多人模式建议先用短片段观察稳定性。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:heading -->
|
||||||
|
<h2 class="wp-block-heading">常见问题</h2>
|
||||||
|
<!-- /wp:heading -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>如果效果没有出现或显示红色警告,先退出 Final Cut Pro 和 Motion,再打开一次主 APP,等待其自动退出,然后重新启动宿主。可在“终端”执行下面这条命令:</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:code -->
|
||||||
|
<pre class="wp-block-code"><code>open '/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app'</code></pre>
|
||||||
|
<!-- /wp:code -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>该流程可重新触发系统注册,并不能解决所有报错。仍异常时请核对 macOS、宿主版本及安装包完整性;不要只复制单个 .moef 文件,配套程序与 Drop Zone.tiff 也需要保留。当前仅提供上述一个效果模板。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:heading -->
|
||||||
|
<h2 class="wp-block-heading">源码与开源许可</h2>
|
||||||
|
<!-- /wp:heading -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>公开源码仓库:<a href="https://github.com/dayumeida/FCP-BeautyGirl" target="_blank" rel="noreferrer noopener">GitHub · FCP-BeautyGirl</a>,可直接浏览源码、完整提交历史和版本标签。<a href="https://github.com/dayumeida/FCP-BeautyGirl/releases/tag/v1.3.2" target="_blank" rel="noreferrer noopener">1.3.2 Release</a> 提供正式签名公证安装包。大鱼站仓库作为备份保留:<a href="https://dayu.media/git/dayu/paintfcp-fxplug" target="_blank" rel="noreferrer noopener">paintfcp-fxplug</a>(该入口仍受站点登录与会员网关限制)。也可下载 <a href="{{source_url}}">1.3.2 源码快照 ZIP</a>,源码与安装包均免费提供。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:paragraph -->
|
||||||
|
<p>项目代码按仓库中的 MIT 许可文件提供,源码包含 Xcode 工程、Objective-C / Metal 实现、模板及构建与验证说明。Apple SDK、运行框架及样本按各自许可使用,详见源码中的 LICENSE 和 THIRD_PARTY_NOTICES.md。自行编译需要 Xcode 与 FxPlug SDK;证书和签名私钥不包含在源码中。</p>
|
||||||
|
<!-- /wp:paragraph -->
|
||||||
|
|
||||||
|
<!-- wp:image {"id":15597,"sizeSlug":"large","linkDestination":"none"} -->
|
||||||
|
<figure class="wp-block-image size-large"><img src="https://dayu.media/wp-content/uploads/2026/10/1792605142-78805a221a988e7-359x1024.png" alt="" class="wp-image-15597" /></figure>
|
||||||
|
<!-- /wp:image -->
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Package the installed product with local PKG Forge, then sign/notarize its migration update."""
|
||||||
|
import argparse, datetime, hashlib, json, os, pathlib, plistlib, shutil, subprocess, sys
|
||||||
|
from installer_identity import inject_migration
|
||||||
|
from product_identity import PRODUCT, ROOT, delivery_locks, validate_app
|
||||||
|
|
||||||
|
def run(args, log=None, env=None):
|
||||||
|
result = subprocess.run(args, cwd=ROOT, text=True, capture_output=True, env=env)
|
||||||
|
if log:
|
||||||
|
pathlib.Path(log).write_text(result.stdout + result.stderr)
|
||||||
|
result.check_returncode()
|
||||||
|
return result.stdout
|
||||||
|
|
||||||
|
version = PRODUCT['version']
|
||||||
|
work = ROOT / 'build' / ('package-' + version)
|
||||||
|
release = ROOT / 'releases' / version
|
||||||
|
proof = ROOT / 'docs/verification' / ('v' + version)
|
||||||
|
package_name = PRODUCT['name'] + '-' + version + '.pkg'
|
||||||
|
final = release / package_name
|
||||||
|
keychain = '/Users/dayu/Library/Keychains/login.keychain-db'
|
||||||
|
installer_identity = 'Developer ID Installer: zhong luo (B3W25FX5H5)'
|
||||||
|
cli = '/Applications/PKG工坊.app/Contents/MacOS/PKG工坊'
|
||||||
|
source_template = pathlib.Path('/Users/dayu/Movies/Motion Templates.localized/Effects.localized/大鱼磨皮瘦脸')
|
||||||
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
|
parser.add_argument('--verify-existing', action='store_true', help='Resume verification of the already Accepted, stapled final package without rebuilding or resubmitting it.')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
with delivery_locks():
|
||||||
|
if not args.verify_existing:
|
||||||
|
if work.exists() or final.exists():
|
||||||
|
raise SystemExit('Packaging work or final package already exists; inspect before retrying')
|
||||||
|
work.mkdir(parents=True)
|
||||||
|
release.mkdir(parents=True, exist_ok=True)
|
||||||
|
proof.mkdir(parents=True, exist_ok=True)
|
||||||
|
formal = pathlib.Path(PRODUCT['installationPath'])
|
||||||
|
info = validate_app(formal, PRODUCT['bundleIdentifier'])
|
||||||
|
assert info['CFBundleShortVersionString'] == version and info['CFBundleVersion'] == PRODUCT['build']
|
||||||
|
assert installer_identity in run(['security', 'find-identity', '-v', '-p', 'basic', keychain])
|
||||||
|
template = work / 'input/大鱼磨皮瘦脸'
|
||||||
|
manifest = []
|
||||||
|
for source in sorted(source_template.rglob('*')):
|
||||||
|
if source.is_file() and source.name != '.DS_Store':
|
||||||
|
target = template / source.relative_to(source_template)
|
||||||
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.copyfile(source, target)
|
||||||
|
if source.stat().st_flags & 2:
|
||||||
|
run(['chflags', 'uchg', str(target)])
|
||||||
|
manifest.append({'file': str(source.relative_to(source_template)), 'sha256': hashlib.sha256(source.read_bytes()).hexdigest(), 'locked': bool(source.stat().st_flags & 2)})
|
||||||
|
assert len(manifest) == 4 and len(list(template.rglob('*.moef'))) == 1
|
||||||
|
base = work / 'base' / package_name
|
||||||
|
base.parent.mkdir()
|
||||||
|
print('PKG Forge: generating signed/notarized base installer from the formal APP and installed Motion category.', flush=True)
|
||||||
|
run([cli, 'inspect', str(formal), str(template)], proof / 'pkgforge-inspect.txt')
|
||||||
|
run([cli, 'package', '--name', PRODUCT['name'], '--version', version, '--identifier-prefix', 'com.dayu.fcppackage', '--signing-identity', installer_identity, '--notary-profile', 'codex-dayu-notary-B3W25FX5H5', '--keychain', keychain, '--output', str(base), str(formal), str(template)], proof / 'pkgforge.txt')
|
||||||
|
run(['pkgutil', '--check-signature', str(base)])
|
||||||
|
run(['xcrun', 'stapler', 'validate', str(base)])
|
||||||
|
expanded = work / 'expanded'
|
||||||
|
run(['pkgutil', '--expand', str(base), str(expanded)])
|
||||||
|
script = expanded / 'Payload.pkg/Scripts/postinstall'
|
||||||
|
script.write_text(inject_migration(script.read_text()))
|
||||||
|
run(['/bin/zsh', '-n', str(script)])
|
||||||
|
# PKG Forge owns the payload/template/update scripts. Only the product's
|
||||||
|
# identity migration is added, then the complete result is signed afresh.
|
||||||
|
unsigned = work / 'migration-unsigned.pkg'
|
||||||
|
run(['pkgutil', '--flatten', str(expanded), str(unsigned)])
|
||||||
|
run(['productsign', '--sign', installer_identity, '--keychain', keychain, '--timestamp', str(unsigned), str(final)], proof / 'pkg-signing.txt')
|
||||||
|
print('Submitting the final migration installer to Apple notarization.', flush=True)
|
||||||
|
result = json.loads(run(['xcrun', 'notarytool', 'submit', str(final), '--keychain-profile', 'codex-dayu-notary-B3W25FX5H5', '--keychain', keychain, '--wait', '--output-format', 'json']))
|
||||||
|
(proof / 'pkg-notarization.json').write_text(json.dumps(result, indent=2) + '\n')
|
||||||
|
if result.get('status') != 'Accepted':
|
||||||
|
raise RuntimeError('Final migration package notarization was not Accepted')
|
||||||
|
run(['xcrun', 'stapler', 'staple', str(final)], proof / 'pkg-staple.txt')
|
||||||
|
run(['xcrun', 'stapler', 'validate', str(final)])
|
||||||
|
run(['pkgutil', '--check-signature', str(final)], proof / 'pkg-signature.txt')
|
||||||
|
run(['spctl', '-a', '-vv', '-t', 'install', str(final)], proof / 'pkg-gatekeeper.txt')
|
||||||
|
else:
|
||||||
|
if not work.exists() or not final.exists():
|
||||||
|
raise RuntimeError('No prepared package to verify')
|
||||||
|
formal = pathlib.Path(PRODUCT['installationPath'])
|
||||||
|
info = validate_app(formal, PRODUCT['bundleIdentifier'])
|
||||||
|
assert info['CFBundleShortVersionString'] == version and info['CFBundleVersion'] == PRODUCT['build']
|
||||||
|
result = json.loads((proof / 'pkg-notarization.json').read_text())
|
||||||
|
assert result['status'] == 'Accepted'
|
||||||
|
run(['xcrun', 'stapler', 'validate', str(final)])
|
||||||
|
run(['pkgutil', '--check-signature', str(final)])
|
||||||
|
run(['spctl', '-a', '-vv', '-t', 'install', str(final)])
|
||||||
|
template = work / 'input/大鱼磨皮瘦脸'
|
||||||
|
manifest = [{'file': str(p.relative_to(template)), 'sha256': hashlib.sha256(p.read_bytes()).hexdigest(), 'locked': bool(p.stat().st_flags & 2)} for p in sorted(template.rglob('*')) if p.is_file()]
|
||||||
|
assert len(manifest) == 4
|
||||||
|
full = work / 'full'
|
||||||
|
try:
|
||||||
|
run(['pkgutil', '--expand-full', str(final), str(full)])
|
||||||
|
run([sys.executable, 'scripts/verify-release-package.py', '--version', version, '--build', PRODUCT['build'], '--expanded', str(full), '--fixture', 'build/pkg-isolation-' + version], proof / 'pkg-verification-output.txt')
|
||||||
|
env = dict(os.environ, FCP_BEAUTYGIRL_POSTINSTALL=str(full / 'Payload.pkg/Scripts/postinstall'))
|
||||||
|
run([sys.executable, 'tests/installer_identity_tests.py'], proof / 'installer-tests.txt', env=env)
|
||||||
|
finally:
|
||||||
|
if full.exists():
|
||||||
|
run(['chflags', '-R', 'nouchg', str(full)])
|
||||||
|
shutil.rmtree(full)
|
||||||
|
receipt = {'status': 'verified', 'version': version, 'build': PRODUCT['build'], 'package': str(final.relative_to(ROOT)), 'bytes': final.stat().st_size, 'sha256': hashlib.sha256(final.read_bytes()).hexdigest(), 'sourceApp': str(formal), 'sourceCommit': json.loads((ROOT / 'build/delivery/delivery-receipt.json').read_text())['source']['commit'], 'motionSource': str(source_template), 'motionFiles': manifest, 'packager': cli, 'productMigration': 'PKG Forge base plus identity-checked backup/rollback block; final package freshly signed, notarized and stapled', 'notarization': result, 'realInstallerExecuted': False}
|
||||||
|
(proof / 'pkg-delivery.json').write_text(json.dumps(receipt, ensure_ascii=False, indent=2) + '\n')
|
||||||
|
run(['chflags', '-R', 'nouchg', str(work)])
|
||||||
|
shutil.rmtree(work)
|
||||||
|
print(json.dumps(receipt, ensure_ascii=False), flush=True)
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
Only --publish performs writes. Credentials stay in memory and go only to Dayu.
|
Only --publish performs writes. Credentials stay in memory and go only to Dayu.
|
||||||
"""
|
"""
|
||||||
import argparse, base64, hashlib, html, json, pathlib, ssl, subprocess, urllib.parse, urllib.request, uuid, zipfile
|
import argparse, base64, hashlib, html, json, pathlib, ssl, subprocess, urllib.parse, urllib.request, uuid, zipfile
|
||||||
|
from product_identity import PRODUCT
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument('--version', required=True)
|
parser.add_argument('--version', required=True)
|
||||||
@@ -49,8 +50,8 @@ if not args.publish:
|
|||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
baseline = json.loads((work / 'article-before.json').read_text())['article']
|
baseline = json.loads((work / 'article-before.json').read_text())['article']
|
||||||
payload = json.loads((release / 'article-payload.json').read_text())
|
payload = json.loads((release / 'article-payload.json').read_text())
|
||||||
package = release / ('大鱼人像美化-' + args.version + '.pkg')
|
package = release / (PRODUCT['name'] + '-' + args.version + '.pkg')
|
||||||
source = root / 'build' / ('Dayu-Portrait-' + args.version + '-source.zip')
|
source = root / 'build' / (PRODUCT['name'] + '-' + args.version + '-source.zip')
|
||||||
with zipfile.ZipFile(source) as z:
|
with zipfile.ZipFile(source) as z:
|
||||||
assert z.testzip() is None and any(n.endswith('/Wrapper Application/AppDelegate.m') for n in z.namelist())
|
assert z.testzip() is None and any(n.endswith('/Wrapper Application/AppDelegate.m') for n in z.namelist())
|
||||||
assert not any(n.endswith(('.app', '.pkg', '.p12', '.key', '.env')) for n in z.namelist())
|
assert not any(n.endswith(('.app', '.pkg', '.p12', '.key', '.env')) for n in z.namelist())
|
||||||
@@ -77,7 +78,7 @@ assert '{{' not in payload['content']
|
|||||||
if not state.get('response'):
|
if not state.get('response'):
|
||||||
boundary = 'DayuRelease' + state['idempotencyKey'].replace('-', '')
|
boundary = 'DayuRelease' + state['idempotencyKey'].replace('-', '')
|
||||||
parts = []
|
parts = []
|
||||||
for name, data, filename, mime in [('payload', json.dumps(payload, ensure_ascii=False).encode(), None, 'application/json'), ('package', package.read_bytes(), 'Dayu-Portrait-' + args.version + '.pkg', 'application/octet-stream')]:
|
for name, data, filename, mime in [('payload', json.dumps(payload, ensure_ascii=False).encode(), None, 'application/json'), ('package', package.read_bytes(), package.name, 'application/octet-stream')]:
|
||||||
head = '--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"'
|
head = '--' + boundary + '\r\nContent-Disposition: form-data; name="' + name + '"'
|
||||||
if filename:
|
if filename:
|
||||||
head += '; filename="' + filename + '"'
|
head += '; filename="' + filename + '"'
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
"""Verify an expanded release payload and run template-only update/rollback in isolation."""
|
"""Verify an expanded release payload and run template-only update/rollback in isolation."""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import argparse,hashlib,json,os,plistlib,shutil,subprocess,sys
|
import argparse,hashlib,json,os,plistlib,shutil,subprocess,sys
|
||||||
|
from product_identity import PRODUCT
|
||||||
root=Path(__file__).resolve().parent.parent
|
root=Path(__file__).resolve().parent.parent
|
||||||
parser=argparse.ArgumentParser(description=__doc__)
|
parser=argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument('--version',default='1.2.0')
|
parser.add_argument('--version',default=PRODUCT['version'])
|
||||||
parser.add_argument('--build',default='14')
|
parser.add_argument('--build',default=PRODUCT['build'])
|
||||||
parser.add_argument('--expanded',default='build/pkg-expanded')
|
parser.add_argument('--expanded',default='build/pkg-expanded')
|
||||||
parser.add_argument('--fixture',default='build/pkg-isolation')
|
parser.add_argument('--fixture',default='build/pkg-isolation')
|
||||||
args=parser.parse_args()
|
args=parser.parse_args()
|
||||||
@@ -33,7 +34,10 @@ base=root/args.fixture;base.mkdir(exist_ok=False)
|
|||||||
volume=base/'volume';home=base/'user';home.mkdir()
|
volume=base/'volume';home=base/'user';home.mkdir()
|
||||||
start=post.index('CURRENT_ACTIVE=0')
|
start=post.index('CURRENT_ACTIVE=0')
|
||||||
isolated='#!/bin/zsh\nset -eu\nTARGET_VOLUME="'+str(volume)+'"\nCONSOLE_USER="'+os.getlogin()+'"\nCONSOLE_UID="'+str(os.getuid())+'"\nCONSOLE_GROUP="staff"\nUSER_HOME="'+str(home)+'"\n'+post[start:]
|
isolated='#!/bin/zsh\nset -eu\nTARGET_VOLUME="'+str(volume)+'"\nCONSOLE_USER="'+os.getlogin()+'"\nCONSOLE_UID="'+str(os.getuid())+'"\nCONSOLE_GROUP="staff"\nUSER_HOME="'+str(home)+'"\n'+post[start:]
|
||||||
isolated=isolated[:isolated.index('fx_verify_app "${TARGET_VOLUME%/}/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app"')]+'exit 0\n'
|
stop = isolated.find('# FCP-BeautyGirl identity migration.')
|
||||||
|
if stop < 0:
|
||||||
|
stop = isolated.index('fx_verify_app "${TARGET_VOLUME%/}/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app"')
|
||||||
|
isolated=isolated[:stop]+'exit 0\n'
|
||||||
isolated=isolated.replace('/usr/sbin/chown -R','/usr/bin/true')
|
isolated=isolated.replace('/usr/sbin/chown -R','/usr/bin/true')
|
||||||
new_copy=next(l for l in isolated.splitlines() if l.startswith('/usr/bin/ditto "${TARGET_VOLUME%/}'))
|
new_copy=next(l for l in isolated.splitlines() if l.startswith('/usr/bin/ditto "${TARGET_VOLUME%/}'))
|
||||||
def refill():
|
def refill():
|
||||||
@@ -66,7 +70,7 @@ assert files(final)==original
|
|||||||
assert all((final/n).stat().st_flags & 2 for n in ['large.png','small.png'])
|
assert all((final/n).stat().st_flags & 2 for n in ['large.png','small.png'])
|
||||||
backups=list((home/'Library/Application Support/PKGForge/Template Backups').rglob('.locked-paths'))
|
backups=list((home/'Library/Application Support/PKGForge/Template Backups').rglob('.locked-paths'))
|
||||||
assert backups and all('/Movies/' not in str(x) for x in backups)
|
assert backups and all('/Movies/' not in str(x) for x in backups)
|
||||||
package=root/('releases/'+args.version+'/大鱼人像美化-'+args.version+'.pkg')
|
package=root/('releases/'+args.version+'/'+PRODUCT['name']+'-'+args.version+'.pkg')
|
||||||
info=plistlib.loads((packed/'Contents/Info.plist').read_bytes())
|
info=plistlib.loads((packed/'Contents/Info.plist').read_bytes())
|
||||||
assert info['CFBundleShortVersionString']==args.version and info['CFBundleVersion']==args.build
|
assert info['CFBundleShortVersionString']==args.version and info['CFBundleVersion']==args.build
|
||||||
report={'package':str(package.relative_to(root)),'bytes':package.stat().st_size,'sha256':sha(package),'version':args.version,'build':args.build,'app_files_compared':len(files(formal)),'app_byte_and_symlink_equality':True,'template_files':{n:sha(template/n) for n in runtime},'locked_relative_paths':['大鱼人像美化/large.png','大鱼人像美化/small.png'],'script_sha256':{'preinstall':sha(expanded/'Scripts/preinstall'),'postinstall':sha(expanded/'Scripts/postinstall')},'isolated_script_tests':['fresh install','replace old locked thumbnail','partial copy failure restores old bytes and locks'],'isolation_changes':['Console identity/home redirected to task fixture','chown replaced with true','FxPlug verification skipped; formal app signature and discovery verified separately'],'real_installer_execution':False,'app_and_template_installed':'APP installed through signed delivery workflow; formal template files matched the specified installed category, not changed by running this PKG','fonts':'No editable third-party font dependency; promotional lettering baked into PNG. No optional font ZIP needed.'}
|
report={'package':str(package.relative_to(root)),'bytes':package.stat().st_size,'sha256':sha(package),'version':args.version,'build':args.build,'app_files_compared':len(files(formal)),'app_byte_and_symlink_equality':True,'template_files':{n:sha(template/n) for n in runtime},'locked_relative_paths':['大鱼人像美化/large.png','大鱼人像美化/small.png'],'script_sha256':{'preinstall':sha(expanded/'Scripts/preinstall'),'postinstall':sha(expanded/'Scripts/postinstall')},'isolated_script_tests':['fresh install','replace old locked thumbnail','partial copy failure restores old bytes and locks'],'isolation_changes':['Console identity/home redirected to task fixture','chown replaced with true','FxPlug verification skipped; formal app signature and discovery verified separately'],'real_installer_execution':False,'app_and_template_installed':'APP installed through signed delivery workflow; formal template files matched the specified installed category, not changed by running this PKG','fonts':'No editable third-party font dependency; promotional lettering baked into PNG. No optional font ZIP needed.'}
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
"""Run the generated installer migration in isolated volumes, never live paths."""
|
||||||
|
import os, pathlib, plistlib, shlex, subprocess, sys, tempfile, unittest
|
||||||
|
ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||||
|
sys.path.insert(0, str(ROOT / 'scripts'))
|
||||||
|
from installer_identity import inject_migration, PRODUCT
|
||||||
|
|
||||||
|
class InstallerIdentityTests(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.tmp = tempfile.TemporaryDirectory(prefix='beautygirl-installer-test.')
|
||||||
|
self.root = pathlib.Path(self.tmp.name)
|
||||||
|
self.old = self.root / pathlib.Path(PRODUCT['legacyProducts'][0]['installationPath']).relative_to('/')
|
||||||
|
self.new = self.root / pathlib.Path(PRODUCT['installationPath']).relative_to('/')
|
||||||
|
for app, info in [(self.old, PRODUCT['legacyProducts'][0]), (self.new, PRODUCT)]:
|
||||||
|
(app / 'Contents/PlugIns' / info['pluginName'] / 'Contents').mkdir(parents=True)
|
||||||
|
(app / 'Contents/Info.plist').write_bytes(plistlib.dumps({'CFBundleIdentifier': info['bundleIdentifier']}))
|
||||||
|
(app / 'Contents/PlugIns' / info['pluginName'] / 'Contents/Info.plist').write_bytes(plistlib.dumps({'ProPlugPlugInList': [{'uuid': PRODUCT['filterUUID']}]}))
|
||||||
|
(app / 'payload-byte').write_bytes(b'original signed payload stand-in')
|
||||||
|
self.signer = self.root / 'codesign-fixture'
|
||||||
|
self.signer.write_text('#!/bin/zsh\napp="${argv[-1]}"\nif [[ -f "$app/.invalid" ]]; then exit 1; fi\n/bin/echo TeamIdentifier=B3W25FX5H5 >&2\n')
|
||||||
|
self.signer.chmod(0o755)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.tmp.cleanup()
|
||||||
|
|
||||||
|
def run_installer(self, fail_registration=False):
|
||||||
|
base = '''#!/bin/zsh
|
||||||
|
set -eu
|
||||||
|
TARGET_VOLUME=@@VOLUME@@
|
||||||
|
CONSOLE_UID=501
|
||||||
|
CONSOLE_USER=fixture
|
||||||
|
FX_FAILURE=0
|
||||||
|
fx_verify_app() {
|
||||||
|
/bin/echo "$1" >> @@LOG@@
|
||||||
|
if [[ "$1" == "$BG_NEW_APP" && @@FAIL@@ == 1 ]]; then return 1; fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
trap - EXIT
|
||||||
|
fx_verify_app "${TARGET_VOLUME}/Library/Plug-Ins/FxPlug/FCP-BeautyGirl.app" || FX_FAILURE=1
|
||||||
|
if (( FX_FAILURE )); then exit 1; fi
|
||||||
|
exit 0
|
||||||
|
'''
|
||||||
|
base = base.replace('@@VOLUME@@', shlex.quote(str(self.root))).replace('@@LOG@@', shlex.quote(str(self.root / 'registration-calls'))).replace('@@FAIL@@', '1' if fail_registration else '0')
|
||||||
|
code = inject_migration(base)
|
||||||
|
# Only signature and user-session registration are isolated. Identity
|
||||||
|
# parsing, file moves, deletes, traps and rollback run unchanged.
|
||||||
|
code = code.replace('/usr/bin/codesign', shlex.quote(str(self.signer)))
|
||||||
|
code = code.replace('/bin/launchctl asuser', '/usr/bin/true asuser')
|
||||||
|
script = self.root / 'postinstall'
|
||||||
|
script.write_text(code)
|
||||||
|
subprocess.run(['/bin/zsh', '-n', str(script)], check=True, capture_output=True)
|
||||||
|
return subprocess.run(['/bin/zsh', str(script)], text=True, capture_output=True)
|
||||||
|
|
||||||
|
def test_upgrade_keeps_new_and_removes_old_and_recovery_copy(self):
|
||||||
|
self.assertEqual(self.run_installer().returncode, 0)
|
||||||
|
self.assertTrue(self.new.exists())
|
||||||
|
self.assertFalse(self.old.exists())
|
||||||
|
self.assertFalse(list((self.root / 'Library/Application Support').rglob('*.app')))
|
||||||
|
|
||||||
|
def test_registration_failure_restores_old_and_removes_new(self):
|
||||||
|
original = (self.old / 'payload-byte').read_bytes()
|
||||||
|
result = self.run_installer(True)
|
||||||
|
self.assertNotEqual(result.returncode, 0)
|
||||||
|
self.assertFalse(self.new.exists())
|
||||||
|
self.assertEqual((self.old / 'payload-byte').read_bytes(), original)
|
||||||
|
self.assertIn(str(self.old), (self.root / 'registration-calls').read_text())
|
||||||
|
|
||||||
|
def test_invalid_new_signature_does_not_touch_old(self):
|
||||||
|
(self.new / '.invalid').touch()
|
||||||
|
self.assertNotEqual(self.run_installer().returncode, 0)
|
||||||
|
self.assertTrue(self.old.exists())
|
||||||
|
|
||||||
|
def test_foreign_old_bundle_id_is_preserved(self):
|
||||||
|
(self.old / 'Contents/Info.plist').write_bytes(plistlib.dumps({'CFBundleIdentifier': 'com.unrelated.product'}))
|
||||||
|
self.assertNotEqual(self.run_installer().returncode, 0)
|
||||||
|
self.assertTrue(self.old.exists())
|
||||||
|
|
||||||
|
def test_invalid_old_signature_is_preserved(self):
|
||||||
|
(self.old / '.invalid').touch()
|
||||||
|
self.assertNotEqual(self.run_installer().returncode, 0)
|
||||||
|
self.assertTrue(self.old.exists())
|
||||||
|
|
||||||
|
def test_fresh_install_and_repeat_are_idempotent(self):
|
||||||
|
import shutil
|
||||||
|
shutil.rmtree(self.old)
|
||||||
|
self.assertEqual(self.run_installer().returncode, 0)
|
||||||
|
self.assertEqual(self.run_installer().returncode, 0)
|
||||||
|
self.assertTrue(self.new.exists())
|
||||||
|
|
||||||
|
def test_unrelated_neighbor_is_preserved(self):
|
||||||
|
unrelated = self.old.parent / 'OtherProduct.app'
|
||||||
|
unrelated.mkdir()
|
||||||
|
self.assertEqual(self.run_installer().returncode, 0)
|
||||||
|
self.assertTrue(unrelated.exists())
|
||||||
|
|
||||||
|
@unittest.skipUnless(os.environ.get('FCP_BEAUTYGIRL_POSTINSTALL'), 'Final PKG is not built yet')
|
||||||
|
def test_final_package_contains_the_tested_migration_block(self):
|
||||||
|
actual = pathlib.Path(os.environ['FCP_BEAUTYGIRL_POSTINSTALL']).read_text()
|
||||||
|
generated = inject_migration('\ntrap - EXIT\nfx_verify_app candidate\nexit 0\n')
|
||||||
|
start = generated.index('# FCP-BeautyGirl identity migration.')
|
||||||
|
end = generated.rindex('\nfx_verify_app ')
|
||||||
|
self.assertIn(generated[start:end], actual)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
在新工单中引用
屏蔽一个用户