feat: macOS support for v0.1.0 — platform split, opener, PATH fix, universal DMG - #3
Conversation
Platform adaptation only; no new agent features (docs/release.md §3/§7): - tauri config split per platform (auto-merged at build): common (window/CSP/icons incl. icon.icns), tauri.windows.conf.json (NSIS + WebView2Loader + install notes), tauri.macos.conf.json (app+dmg, minimumSystemVersion 12.0) - openInFileManager now uses plugin-opener openPath (cross-platform); hardcoded explorer spawn removed — verified at runtime on Windows (opener opens Explorer at the data dir) - macOS PATH fix (P0): fix_path_env::fix() at startup — Finder/Dock launches do not inherit shell PATH; acceptance is git/claude/codex usable from the in-app terminal after Finder launch - shell capabilities split by platform: shell-macos.json carries only git/claude/codex/npm/node; cmd/powershell/explorer are Windows-only (explorer dropped entirely) — first pass of the allowlist tightening tracked in Roadmap issue #2 - make-release.mjs is platform-aware: win32 collects the NSIS exe, darwin collects the newest DMG (universal preferred), README/verify steps adapt (Get-FileHash vs shasum, SmartScreen vs Gatekeeper) - main.tsx boot-failure text now built via textContent (renderer security red line), not innerHTML - docs: release.md gains macOS build env, universal DMG flow, two-phase signing policy, mac test matrix in the release gate; README states Windows + macOS targets; seed manual gains a macOS appendix Windows regression: 63 vitest green, tsc+vite build, NSIS rebuilds from split config, dev + release smoke verified (CSP intact, opener click opens Explorer at data dir), release/ regenerated.
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved release packaging, permission-scope, and documentation issues remain.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds macOS 12+ support with platform-specific Tauri configuration, PATH restoration, Finder integration, and universal DMG packaging while preserving Windows support.
Changes:
- Splits Tauri configuration and shell capabilities by platform.
- Replaces Explorer-specific opening with
plugin-opener. - Adds platform-aware release tooling, documentation, and safer startup error rendering.
Unresolved items include release artifact selection and cross-machine merging, overly broad opener permissions, and stale platform/path documentation.
File summaries
| File | Reviewed change |
|---|---|
src/storage/git.ts |
Uses the cross-platform opener. |
src/main.tsx |
Safely renders initialization errors. |
src-tauri/tauri.windows.conf.json |
Defines Windows packaging configuration. |
src-tauri/tauri.macos.conf.json |
Defines macOS app and DMG configuration. |
src-tauri/tauri.conf.json |
Provides shared Tauri configuration. |
src-tauri/src/lib.rs |
Registers the opener and restores PATH. |
src-tauri/Cargo.toml |
Adds Rust dependencies. |
src-tauri/Cargo.lock |
Locks Rust dependencies. |
src-tauri/capabilities/shell-windows.json |
Defines Windows shell permissions. |
src-tauri/capabilities/shell-macos.json |
Defines macOS shell permissions. |
src-tauri/capabilities/default.json |
Removes the superseded capability file. |
src-tauri/capabilities/common.json |
Defines shared permissions. |
scripts/make-release.mjs |
Generates platform-aware release artifacts and documentation. |
README.md |
Updates platform and release guidance. |
package.json |
Adds the opener dependency. |
package-lock.json |
Locks npm dependencies. |
docs/seed-manual.md |
Adds macOS installation guidance. |
docs/release.md |
Documents macOS builds and validation. |
AGENTS.md |
Updates platform and contributor guidance. |
Review details
Suppressed comments (6)
AGENTS.md:39
- 本行把 macOS 适配记入当前状态,但紧邻的下一步和 README 状态仍只写“Windows clean 环境 → Windows seed → 2a”,没有列出本 PR 明确要求的 native/universal macOS 验证与双平台汇总发布。请同步更新状态,避免后续工作跳过 macOS release gate。
- **macOS 适配(v0.1.0,PR feat/v0.1-macos-support)**:Tauri 配置拆三文件(`tauri.conf.json` 公共 / `tauri.windows.conf.json` NSIS+WebView2Loader / `tauri.macos.conf.json` app+dmg+minimumSystemVersion 12.0,构建时自动合并);文件管理器改 `plugin-opener`(`openPath`,替代硬编码 explorer);**Finder/Dock 启动 PATH 修复**(`fix-path-env` crate,lib.rs setup 里 `fix()`,mac 验收 = Finder 双击启动后终端 git/claude/codex 可用);shell capability 拆平台(`shell-windows.json` / `shell-macos.json`——mac 只留 git/claude/codex/npm/node,explorer/cmd/powershell 不进 mac 白名单);universal 构建命令与 mac 测试矩阵见 docs/release.md §0/§3/§4-6。**签名两阶段**:内测不签名(右键→打开过 Gatekeeper),面向陌生用户前必须 Developer ID + 公证
docs/release.md:24
- 这里要求两台机器分别生成
release/后再手工汇总,但脚本每次都会重写SHA256SUMS.txt和README.md,只包含当前机器的平台;同时本节又规定 release 只能由脚本生成、手工修改无效。按现流程最终双平台发布物要么缺另一平台的校验/说明,要么必须违反发布规范,请让脚本支持双平台合并,或定义不冲突的合并命令和产物目录。
两台机器各自生成 `release/`,发布前把 Windows 的 exe 与 macOS 的 dmg **汇总到同一份发布物**(SHA256SUMS 合并核对)。
docs/seed-manual.md:86
- 新增 macOS 附录后,上面的已知限制仍写着“仅 Windows x64;macOS……在后续版本”,手册会同时声称 Mac 不支持又提供 Mac 安装步骤。请同步更新该限制,明确当前支持的 Windows x64 与 macOS 12+ universal,并保留签名/自动更新为后续限制。
## 8. macOS 附录(Mac 种子用户)
- **安装**:双击 DMG,把 ResearchThread 拖进「应用程序」。安装包未签名,首次启动若提示「无法验证开发者」:在「应用程序」里**右键 ResearchThread → 打开 → 再点「打开」**(只需一次),不要去系统设置里关 Gatekeeper。
scripts/make-release.mjs:61
- This accepts any
.dmgleft in either bundle directory, including an older version or an unrelated stale artifact. Since the Windows path is version-specific, filter the macOS filename by the current product/version before choosing the newest candidate.
if (f.endsWith(".dmg")) {
src-tauri/capabilities/common.json:33
openInFileManageronly needsopenPath, butopener:defaultgrants the plugin's broader default command set in addition toopener:allow-open-path(including unrelated URL/reveal operations). This unnecessarily enlarges the renderer's OS-launch surface; keep only the specific permission required by this feature.
"opener:default",
"opener:allow-open-path",
src-tauri/capabilities/common.json:4
- 这次拆分删除了
capabilities/default.json,但仓库维护说明仍把已不存在的文件作为 shell 白名单入口(AGENTS.md:50、README.md:48)。后续按文档新增 CLI 会改错文件,导致对应平台无法启动;请同步改为shell-windows.json和shell-macos.json,并说明两处 execute/spawn allow 列表都要更新。
"description": "跨平台能力:数据目录文件 IO 与监听、目录打开(opener)、全局快捷键",
- Files reviewed: 17/19 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| found.sort((a, b) => b.mtime - a.mtime); // 取最新(universal 优先构建时通常也更新) | ||
| return found[0]; |
| await writeFile( | ||
| join(outDir, "SHA256SUMS.txt"), | ||
| `${installerHash} ${installerName}\n${manualHash} 种子测试手册.md\n`, | ||
| `${installerHash} ${installer.name}\n${manualHash} 种子测试手册.md\n`, |
| ); | ||
|
|
||
| const buildDate = new Date().toISOString().slice(0, 10); | ||
| const platformLabel = isMac ? "macOS(universal:Apple Silicon + Intel)" : "Windows x64"; |
| - **发布物料**:关于页读真实版本(`getVersion()`)标「种子测试版」;[docs/seed-manual.md](docs/seed-manual.md) 种子手册——隐私边界(**明确撤回「打包数据目录反馈」**,改为脱敏反馈模板)、SmartScreen 安装步骤、卸载数据保留说明、外部编辑并发规则 | ||
| - **发布包与安装提示**:`npm run make-release`([scripts/make-release.mjs](scripts/make-release.mjs))把 NSIS 安装包、SHA256SUMS、README、种子手册归拢到 `release/`(gitignore,脚本可重复生成);安装器中文化(`bundle.windows.nsis.languages` 简中+英文+语言选择器)并以 `bundle.license`(`src-tauri/INSTALL-NOTES.txt`)在安装前展示中文安装须知;应用首启弹欢迎卡(数据位置/快照警告含义/脱敏反馈,`settings.introSeen` 持久化开关) | ||
| - **发布包与安装提示**:`npm run make-release`([scripts/make-release.mjs](scripts/make-release.mjs))平台感知(win 收 NSIS exe / darwin 收 DMG),归拢安装包、SHA256SUMS、README、种子手册到 `release/`(gitignore,脚本可重复生成);安装器中文化(`bundle.windows.nsis.languages` 简中+英文+语言选择器)并以 `bundle.license`(`src-tauri/INSTALL-NOTES.txt`)在安装前展示中文安装须知;应用首启弹欢迎卡(数据位置/快照警告含义/脱敏反馈,`settings.introSeen` 持久化开关) | ||
| - **macOS 适配(v0.1.0,PR feat/v0.1-macos-support)**:Tauri 配置拆三文件(`tauri.conf.json` 公共 / `tauri.windows.conf.json` NSIS+WebView2Loader / `tauri.macos.conf.json` app+dmg+minimumSystemVersion 12.0,构建时自动合并);文件管理器改 `plugin-opener`(`openPath`,替代硬编码 explorer);**Finder/Dock 启动 PATH 修复**(`fix-path-env` crate,lib.rs setup 里 `fix()`,mac 验收 = Finder 双击启动后终端 git/claude/codex 可用);shell capability 拆平台(`shell-windows.json` / `shell-macos.json`——mac 只留 git/claude/codex/npm/node,explorer/cmd/powershell 不进 mac 白名单);universal 构建命令与 mac 测试矩阵见 docs/release.md §0/§3/§4-6。**签名两阶段**:内测不签名(右键→打开过 Gatekeeper),面向陌生用户前必须 Developer ID + 公证 |
tauri-plugin-fs reads require_literal_leading_dot only from the plugins.fs section of tauri.conf.json; the same key inside a capability fs:scope entry is silently ignored. Unset, it defaults to true on Unix (dotfiles never match **), so data-layer init failed on macOS with 'forbidden path: ~/ResearchThread/.activity' while Windows (default false) worked. Set plugins.fs.requireLiteralLeadingDot = false (no-op on Windows) and drop the dead capability-level key.
Real-download verification on M5 / macOS 26.6: a quarantined unsigned app shows the hard 'move to trash / done' dialog even via right-click open; the bypass now lives in System Settings > Privacy & Security > 'Open Anyway'. Split the guidance by OS version in the seed manual, release playbook (§3/§4-6/§7), make-release README template, and AGENTS.md status.
…rivilege Review closeout (5 items), no new features: - make-release.mjs: darwin now strictly requires the universal DMG at src-tauri/target/universal-apple-darwin/... with productName+version filename match -- native/ARM-only DMGs can never ship; release/ now ACCUMULATES current-version installers across platforms (old-version artifacts auto-cleaned) and SHA256SUMS.txt/README.md are recomputed over whatever is present, so copying the other platform's installer and re-running yields one unified checksum file (resolves the overwrite-vs-merge contradiction); README template lists both installers with the Intel-untested wording - capabilities/common.json: opener:default dropped; allow-open-path now carries an explicit path scope limited to the data dir. Note: a bare allow-open-path has an empty scope and the command is silently denied -- verified at runtime (open failed silently without scope, works with scope); least privilege AND functional - seed manual: title/known-limits updated to Windows+macOS reality, Intel-not-separately-tested caveat added - release.md: assembly semantics documented (accumulate + recompute), universal-only rule, Intel release-note wording requirement - AGENTS.md: capabilities/default.json references replaced with the platform-split files; stale 'data dir changeable in settings' claim removed Windows regression on latest head: 63 vitest green, tsc+vite build, NSIS rebuilt, aggregation semantics exercised (fake 0.0.9 dmg cleaned, 0.1.0 dmg from 'other platform' merged into unified SHA256SUMS), opener click opens Explorer at the data dir (verified via Shell.Application).
|
最终 review:原 5 个收口问题已经实质解决,
只改这两处文案/模板,不扩任何功能;CI 再绿后即可 merge。 |
…/ copy-in rule - make-release README template: macOS 15+ first-launch guidance now matches the verified manual flow (System Settings -> Privacy & Security -> 'Open Anyway'), not xattr quarantine clearing - release.md: rule restated precisely -- platform installers may be copied into release/ as assembly input (then make-release MUST be re-run so SHA256SUMS covers the final artifact set); generated metadata (README/SHA256SUMS/manual copy) is never hand-edited
…rivilege Review closeout (5 items), no new features: - make-release.mjs: darwin now strictly requires the universal DMG at src-tauri/target/universal-apple-darwin/... with productName+version filename match -- native/ARM-only DMGs can never ship; release/ now ACCUMULATES current-version installers across platforms (old-version artifacts auto-cleaned) and SHA256SUMS.txt/README.md are recomputed over whatever is present, so copying the other platform's installer and re-running yields one unified checksum file (resolves the overwrite-vs-merge contradiction); README template lists both installers with the Intel-untested wording - capabilities/common.json: opener:default dropped; allow-open-path now carries an explicit path scope limited to the data dir. Note: a bare allow-open-path has an empty scope and the command is silently denied -- verified at runtime (open failed silently without scope, works with scope); least privilege AND functional - seed manual: title/known-limits updated to Windows+macOS reality, Intel-not-separately-tested caveat added - release.md: assembly semantics documented (accumulate + recompute), universal-only rule, Intel release-note wording requirement - AGENTS.md: capabilities/default.json references replaced with the platform-split files; stale 'data dir changeable in settings' claim removed Windows regression on latest head: 63 vitest green, tsc+vite build, NSIS rebuilt, aggregation semantics exercised (fake 0.0.9 dmg cleaned, 0.1.0 dmg from 'other platform' merged into unified SHA256SUMS), opener click opens Explorer at the data dir (verified via Shell.Application).
这是什么
v0.1.0 的 macOS 适配(平台适配 only,不引入任何 2a agent 功能)。基于已合并的 PR #1。设计范围遵循发布前评审结论:Windows x64 + macOS 12+(universal DMG,不上 App Store、内测期不签名)。
改动清单
tauri.conf.json(公共:窗口/CSP/图标含 icns)+tauri.windows.conf.json(NSIS/WebView2Loader/须知页/语言)+tauri.macos.conf.json(app+dmg / minimumSystemVersion 12.0)plugin-opener的openPath(Explorer/Finder 通吃);explorer 从 shell 白名单移除。Windows 实机验证:点「打开数据目录」唤起 Explorer 到数据目录fix-path-env(Tauri 官方 crate)在 Rust setup 里恢复登录 shell PATH;红线入档 docs/release.md §3(验收 = Finder 双击启动后终端 git/claude/codex 可用)shell-windows.json/shell-macos.json:mac 只留 git/claude/codex/npm/node,cmd/powershell 不进 mac;explorer 全平台移除(opener 取代)——Issue #2「收紧 allowlist」的第一刀顺手修掉(评审要求):
main.tsx初始化失败的错误文案从root.innerHTML拼接改为textContent构建——与 renderer 安全红线一致,不留到 agent 输出接入之后。基本不用改的部分(评审已确认): 数据目录
homeDir()构造、CommandOrControl+Shift+Space快捷键、storage/atomicWrite/.trash——原样跨平台。签名策略(评审定的两阶段)
内测期不签名(手册写明「右键 → 打开」过 Gatekeeper);面向陌生用户分发前必须 Developer ID + 公证(docs/release.md §7 红线)。
Windows 回归验证(本机已完成)
d7cb5515…b3769,e19f840 干净树)npm run make-release(win32 路径)正常归拢需要在 macOS 上完成
任务书:Issue #4(自包含清单:环境/native dev/PATH 验收/universal DMG/完整矩阵/回报格式,可直接交给 Mac 上的 agent 执行)。验收标准细节见 docs/release.md §4-6。
native ARM 先过一轮(dev + Finder 双击 + PATH 三件套 + 数据/冲突/快照/trash/快捷键),再
--target universal-apple-darwin出 DMG 复测核心项。DMG 产出后npm run make-release归拢,与 Windows exe 汇总为 v0.1.0 发布物。