macOS app
macOS app 指交付物是原生 macOS 图形应用,仓库需要长期处理 app bundle、平台工具链、桌面运行行为和 macOS 特有能力,而不是只有一个能在 macOS 上运行的 CLI。这里真正重要的是应用外壳和平台契约:如何构建 .app、怎样运行 dev/prod variant、何时接入 Keychain、文件访问与本地状态如何管理,以及后续是否能顺利走到签名、打包或分发(projects/televy-backup.
- 前端
- 工具
目录
Definition
macOS app 指交付物是原生 macOS 图形应用,仓库需要长期处理 app bundle、平台工具链、桌面运行行为和 macOS 特有能力,而不是只有一个能在 macOS 上运行的 CLI。这里真正重要的是应用外壳和平台契约:如何构建 .app、怎样运行 dev/prod variant、何时接入 Keychain、文件访问与本地状态如何管理,以及后续是否能顺利走到签名、打包或分发(projects/televy-backup.md)。
它和 Rust application、Rust workspace 相邻,但不相同。Rust application 解释“这是一个面向用户的应用”,Rust workspace 解释 crate 边界如何拆;macOS app 解释的是 Apple 平台本身带来的运行、打包和维护约束。
窗口截图证据是相邻但独立的 Native macOS visual evidence Topic:本 Topic 负责 .app 生命周期、平台能力、Keychain、签名/公证和 packaging;新 Topic 负责 target-window 的 PID/bundle/AX/WindowServer identity、fixture isolation、changed-surface matrix 与 PR PNG 生命周期。不要因为项目属于 macOS app 就把应用内 bitmap/PDF preview 或标题猜测当成真实窗口证据。
When to use
当仓库明确维护 macOS GUI shell、macos/ 目录、app build/run scripts、桌面态本地存储或 Keychain 行为时使用。若改动会影响 app bundle 结构、build-app.sh / run-app.sh、dev/prod-like variant、Keychain 开关、打包材料、菜单栏/窗口启动流程、文件访问权限或未来的签名/公证路径,就应该命中本 Topic。
如果项目只是普通 Rust 工具偶尔在 Mac 上运行,或者仓库里仅有一份针对 macOS 的说明文档,不应提升到 macOS app。这里关注的是“平台本身构成交付面”,不是“开发者碰巧在 Mac 上工作”。
Habits / defaults
- 构建和运行入口应通过 repo 内脚本显式暴露,而不是要求维护者记一长串
xcodebuild、环境变量或本地目录约定。像projects/televy-backup.md这样把scripts/macos/build-app.sh、scripts/macos/run-app.sh固化下来,能显著降低桌面壳层漂移。 - 把 dev 与 prod-like 的平台行为分开描述,尤其是 Keychain、登录项、沙箱或本地系统集成这类能力。开发环境为了迭代速度可以降级,但 Topic 回答里必须写清楚哪些行为只在正式运行形态下成立。
- GUI 壳层尽量薄,核心业务逻辑放在可测试的 Rust crate 或 daemon 边界里。这样桌面 app 改壳、重做窗口或切换运行模式时,不会把备份/同步/状态机逻辑一并打散。
- 平台相关验证不能只依赖 Linux CI。即便已有
ci-main.yml、release.yml等门禁,凡是涉及窗口、Keychain、本地路径、打包材料或用户交互的改动,最终都要在真实 macOS 上过一遍。 - 打包和分发材料要与应用入口一起维护。对桌面项目来说,
packaging/不是附件目录,而是 release contract 的一部分;不把它写进 Topic,后续很容易出现“能跑但不能发”的半成品状态。
Reference implementations
projects/televy-backup.md:当前核心样本。它把 workspace crates、macOS app source、build/run scripts、packaging 和 release workflow 放进同一仓库里,足够说明macOS app不是“多一个 UI 目录”,而是一整套平台交付面。projects/spotibind.md:轻量菜单栏 app 样本。它证明菜单栏MenuBarExtra、SwiftUI lifecycle、真实 bundle 与 release 入口同样属于本 Topic;其严格窗口截图规则见topics/native-macos-visual-evidence/TOPIC.md。skills/style-macos-app/SKILL.md:对应 group Skill 进一步证明消费侧要看的不是抽象名词,而是平台 build/run、Keychain variant 和打包路径这些实际维护动作。
Failure modes
- 把任意桌面项目都贴成
macOS app,会模糊真正的平台约束。没有 app shell、构建脚本和分发语义的项目,更适合留在Rust application。 - 只在开发模式下验证,忽略 prod-like Keychain、打包和真实 app bundle 行为,会让问题集中在最晚的 release 阶段暴露。
- 让 GUI 壳层直接承载核心逻辑,会导致任何窗口层改动都变成高风险业务改动,也让 CLI/daemon 复用变得困难。
- 只保证
cargo build通过,却不验证.app是否能实际运行、读取状态或接入系统能力,是桌面项目里最常见的假绿。 - 把
macOS app的平台交付责任和截图证据责任混在一起,会让窗口验收退化为“能打开就算通过”;改动窗口时同时阅读Native macOS visual evidence,按其严格 target-window 合同验收。
Evidence index
projects/televy-backup.mdskills/style-macos-app/SKILL.mdskills/style-playbook/references/data/topics/macos-app.json
相关内容
SpotiBind
项目实践SpotiBind 是一个 macOS 菜单栏 companion,将标准 play/pause、next、previous media keys 路由到选定的播放器。它的 owner-facing surface 是 MenuBarExtra(.
TelevyBackup
项目实践TelevyBackup 是 macOS desktop backup app + Rust backend。README.md 标记为 work in progress,但已经有 Rust workspace、macOS app build/run scripts、packaging 和 release workflow,说明它不是单 crate 实验。