# 2026-10-04 macOS 版开发与发布规划（Easy Image 试点）

> 配套正本：策略 docs/业务规划/2026-10-01-苹果生态上架策略.md、需求票 docs/需求/2026-09-29-桌面产品跨平台支持(macOS+Linux).md（已 accepted）、账号教程 2026-10-04-Apple开发者账号申请教程.md
> 本文档回答三个问题：**代码怎么组织、开发循环怎么转（无 mac 开发机）、打包发布怎么走。**

## 一 · 总格局（三句话）

1. **前端同一套代码**：五产品全是 Tauri 2 + React，UI 是网页技术，天然平台无关——95% 的界面代码 mac 零改动。
2. **平台差异收口在两处**：`ui_kit` 顶栏组件一个平台分支（导航差异）+ Rust `cfg(target_os)` 少量分支（EI 实测仅 1 处）。改一处，五产品复用，禁止散落 if 苹果判断。
3. **构建在 CI 的 mac 机器，真机验收在 boss 的 Mac**：Windows 上写码 → GitHub Actions macos-latest 编译+测试+出包 → dmg 交 boss Mac 实装。

## 二 · 代码怎么开发（boss 担心的「导航不一样」在这里）

### 2.1 顶栏导航（真实存在的差异，收口一处）

- Windows 现状：无边框窗口 + `ui_kit` WinHeader 自绘三键（最小化/最大化/关闭）。
- macOS 方案：tauri.conf 配 `titleBarStyle: "overlay"`——**系统红绿灯（traffic lights）由 mac 自带**，WinHeader 组件加一个平台分支：mac 下隐藏三键、左侧留出红绿灯位（约 70px padding），其余不变。
- 效果：Windows 零改动；mac 用户看到的是 mac 原生习惯的红绿灯。**一个组件分支，五产品同享**，这就是为什么导航差异不构成逐产品工作量。

### 2.2 菜单栏（mac 特有件）

- mac 应用顶部菜单栏（App 名/Edit/Window）是系统级 UI，Cmd+C/V/Q 等快捷键靠它生效。Tauri 2 默认生成基础菜单兜底；EI 验收时实测快捷键，不够再补自定义菜单项。
- 第一例跑通后，菜单+顶栏分支回流 pdgen tauri-app 模板（出生即合规，规则同全局 pdgen 节）。

### 2.3 Rust 侧（量极小）

- EI 扫描实测 `cfg(windows)` 仅 1 处，且无 Windows-only 依赖（image 处理 crate 全跨平台）。mac 分支按需 `#[cfg(target_os = "macos")]`。
- 不需要 App Sandbox entitlements（那是 MAS 上架才要的，独立分发默认即可）。

### 2.4 平台件对照（全是配置，不是开发）

| 能力 | mac 方案 | 工作量 |
|---|---|---|
| 深链登录回跳（imagefactory://） | tauri-plugin-deep-link 官方全平台，Info.plist 自动注册 | 配置 |
| 托盘/自启动/单实例 | 官方插件跨平台（mac 本身单实例语义） | 配置 |
| 日志路径 | 标准扩展 mac=`~/Library/Logs/<id>/`（LOGGING-STANDARD 补对照表） | 配置+规范一行 |
| WebView2Loader.dll | 条件资源，仅 Windows 打包 | tauri.conf 一行 |
| updater | mac 更新包 .app.tar.gz 必须签名+公证（无签名装不上） | CI 配置 |

## 三 · 开发循环（没有 mac 开发机怎么转）

```
Windows 写码/自测（前端 dev server 照常预览）
   ↓ push
GitHub Actions macos-latest：cargo check + clippy + test + tauri build
   ↓ 失败当场暴露（mac 专属编译错在 CI 抓，不等真机）
dmg artifact
   ↓
boss Mac 下载实装验收（安装→启动→登录深链→更新）
```

- **CI 额度账**：私有仓 macOS runner 按 10x 计费，免费额度折合约 200 分钟/月；一次 mac 构建+公证约 15-25 分钟 → 试点期约 8-10 次/月，够用。量大再评估租云 mac / mac mini。
- **真机验收找 boss 的 Mac**：这是现成的验收机，开发不依赖它，只在里程碑验收用（首版无签名也可装：右键打开绕 Gatekeeper）。

## 四 · 打包

- `tauri.conf.json` bundle targets：Windows 保持 `nsis`，mac 加 `app` + `dmg`。
- 双架构：`--target universal-apple-darwin`（Apple Silicon + Intel 一个包全覆盖），CI 装 x86_64/aarch64 两个 rust target。
- 签名公证在 CI 内一条龙：Developer ID Application 签名 → notarytool 公证（App Store Connect API Key）→ staple。Apple 账号四件套配进 GitHub Secrets。
- Tauri updater 专用 minisign 密钥（`TAURI_SIGNING_PRIVATE_KEY`）与 Apple 证书无关，agent 生成，存 `~/.pinnadash/keys/` 惯例位。

## 五 · 发布链路（第一波主体，app_admin + official_website）

1. **release.mjs 多平台化**：APPS 表加平台产物模式（exe / dmg+app.tar.gz）；`--os` 参数——Windows 本机构建 exe（现状不变），mac 消费 CI artifact；R2 上传路径加 `darwin-aarch64/x86_64` 段。
2. **latest.json 分平台 key**：`windows-x86_64` / `darwin-aarch64` / `darwin-x86_64` 三条目，Tauri updater 按平台自动命中。
3. **官网下载嗅探**：下载按钮按 UA 落 dmg / exe，products.json chip 文案补 mac。
4. **Windows 零回归闸**：release.mjs 改造后 Windows 发版 dry-run 必过，才允许合入。

## 六 · 波次与节奏（照需求票，accepted 生效）

| 波 | 内容 | 量级 |
|---|---|---|
| 一 | 分发链路（release.mjs 多平台 + CI workflow + 官网嗅探） | 先行，不依赖 Apple 证书 |
| 二 | EI mac 适配（顶栏分支/深链/日志/资源条件化） | 1-2 天 |
| 三 | EF → ED → ES → EC 按难度递增 | 每产品 1-2 天，ES/EC 另有平台分支开发 |
| 四 | Linux（AppImage 单格式） | 随试点带出 |

## 七 · 验收（对齐需求票，结票口径）

- [ ] EI macOS 版（双架构 dmg）CI 构建，boss Mac 真机：可安装/启动/登录（深链回跳）/更新（feed 分平台 key 实测命中）
- [ ] release.mjs 单产品单命令三平台产物上 R2，latest.json 三平台条目齐，签名公证通过
- [ ] 官网 mac 浏览器下载落 dmg、Windows 落 exe
- [ ] Windows 链路零回归（dry-run 过）
- [ ] UI-STANDARD-DESKTOP / LOGGING-STANDARD / INSTALLER-STANDARD 三规范补平台条款

## 八 · 2026-10-04 第一波开发落地实况（Windows 侧全部完成，等 boss Mac 实机）

本轮四仓改动全部已验证（Windows 零回归），mac 真机构建只欠 boss 侧跑一次脚本：

| 仓 | 改动 | 验证 |
|---|---|---|
| image_factory | `tauri.macos.conf.json` 平台覆盖（红绿灯 Overlay 窗）/bundle targets 加 app+dmg/lib.rs single-instance 按 OS 门控（mac 系统语义单实例）/CSP 补放行账户中心（清 10-04 悬账）/`build-mac.sh` 一键构建脚本/`.github/workflows/release-mac.yml` CI 存档 | cargo check + tauri build 全量重打（exe+sig 新鲜）+37 前端测试绿 |
| ui_kit | v0.9.10：`WinHeader` mac 分支（`isMacOS()` 隐藏自绘三键+`data-macos` 红绿灯位钩子）+ui-kit.css 78px 红绿灯位 | 156 测试绿（新 3 测先红后绿，含 iPad 冒充 Mac 负向）；六消费仓 kit.py bump 同步 |
| app_admin | feed.js `buildTauriFeed` 多平台 platforms 形（旧形兼容）；release.mjs `uploadAndFeed` 按证据发现平台产物（exe→windows 键 / .app.tar.gz→darwin 键 / dmg 仅官网分发），universal 包 darwin 两键同 url；transformProducts 支持官网 `download_mac` 版本回填 | 62 测试绿+假产物烟测（签名闸精确拦截） |
| official_website | 下载按钮组抽 `_macros.html` 宏（首页五横幅+apps 卡片），`download_mac`/`url_mac` 配了才渲染；js/main.js UA 嗅探隐藏非当前平台钮；i18n 五语按钮文案；build.py url_mac 透传 | 两态渲染实测：无 mac 数据=零 mac 按钮零死链；注入假数据=双按钮齐 |

顺手清账：10-04 CSP 最小化批「IF conf 路径待查」悬账闭环——conf 在 `apps/desktop/src-tauri/tauri.conf.json`，`connect-src` 已补 `https://account.pinnadash.com`。

### boss Mac 验收（下一步唯一动作）

```bash
git clone http://192.168.31.192:13000/xlkj/easy_image.git && cd easy_image
./build-mac.sh          # 首次约 10-20 分钟(含 Rust 冷构建);依赖自检缺什么报什么
# 产物 dmg 双击装;未签名右键 App→打开 绕 Gatekeeper;脚本自带深链 Info.plist 断言
```

### 剩余缺口（不阻塞本地验收）

- **签名公证**：等 Apple 账号激活→四件套入 `~/.pinnadash/keys/apple/`→配 CI Secrets（workflows 文件已就位）
- **CI 跑起来**：产品仓目前仅 NAS Forgejo remote，接 GitHub remote 后 tag 触发 release-mac.yml
- **updater mac 密钥**：复用现有 easy-image.key（TAURI_SIGNING_PRIVATE_KEY），mac 构建时注入即可，无新增密钥
- **官网 mac 链接点亮**：EI mac 首发发版时 products.json 加一行 `download_mac`（回填/嗅探机制本轮已就位）
- **发版链路 mac 段真跑**：release.mjs 多平台逻辑已单测+烟测，等首个真实 dmg 产物走一次 `rel ship`
- 二三四波（EF/ED/ES/EC 适配、Linux）按本票既定波次推进

### 2026-10-12 收口：六项缺口三闭二开一项另议

| 缺口（10-04 立项时） | 现状 | 实证 |
|---|---|---|
| 签名公证（等 Apple 账号四件套） | **已闭** | Developer ID + notarytool Accepted + stapler worked + `spctl=source=Notarized Developer ID`，三产品包均绿 |
| updater mac 密钥（复用现有 `<app>.key`） | **已闭** | mac 更新件 tar.gz 在 Windows 侧 `tauri signer sign`（私钥不上 mac），feed `darwin-aarch64` 签名 436B 非空 |
| 官网 mac 链接点亮 + 发版链路 mac 段真跑 | **已闭** | EF 0.9.7 / EI 0.4.7 / ES 0.12.1 / EC 0.5.12 四波 `rel ship` 真跑并 `rel verify` ok=true；`download_mac` 由 transformProducts 自动回填；UA 嗅探隐藏入口的自伤缺陷当日已修（`main.js` 现无隐藏逻辑，双钮齐显） |
| CI 跑起来（release-mac.yml tag 触发） | **仍开** | 三产品的 mac 包均来自构建机直连构建（`ssh mac` + `tools/mac_ef_build.sh`），workflows 文件是存档状态 |
| 二三四波：ED / EC 适配与对外 | **EC 已闭 / ED 仍开**（10-12 更新） | EC：boss「Easy Clipboard发布」→ v0.5.12 双平台同版对外（feed 双键、dmg 签名+公证 Accepted、verify.json ok=true，详见跨平台票进展十一）；ED：feed 实测 0.9.9 仍只有 `windows-x86_64` 一键，扫描核需 NTFS 语义重写未开工 |
| Intel（`darwin-x86_64`/universal）与 Linux | **待 boss 拍 / 无排期** | 三家 darwin 键均只有 aarch64；Linux 在跨平台票内未开工 |

流程口径补充：mac 出包的两条硬口径（`macos-private-api` Cargo 根段与 target 段互斥、`cc` 直编 ObjC 禁用 `@available`）已写入 `image_factory/docs/MACOS-BUILD.md` 正本，ED/EC 跟随时不再重新踩。
