SpotiBind
SpotiBind 是一个 macOS 菜单栏 companion,将标准 play/pause、next、previous media keys 路由到选定的播放器。它的 owner-facing surface 是 MenuBarExtra(.
- macOS app
- macOS Launch Services window handoff
- Native macOS visual evidence
- Quality gates
- PR label release
目录
技术栈
运行与交付
- CI 工作流
- label-gate.yml
- main.yml
- pr.yml
- release-completion.yml
- release-intent-defaults.yml
- release-preparation.yml
- release.yml
- 能力标记
- github_actions
配置与质量
- 配置文件
- .gitignore
{
"ci_workflows": [
"label-gate.yml",
"main.yml",
"pr.yml",
"release-completion.yml",
"release-intent-defaults.yml",
"release-preparation.yml",
"release.yml"
],
"configs_root": [
".gitignore"
],
"markers_present": [
"github_actions"
]
}Purpose
SpotiBind 是一个 macOS 菜单栏 companion,将标准 play/pause、next、previous media keys 路由到选定的播放器。它的 owner-facing surface 是 MenuBarExtra(.window) popover 和保留的 settings window;播放器自身的播放状态、私有 MediaRemote API 和无关桌面窗口不在项目边界内(docs/specs/spotibind/SPEC.md)。
Taxonomy
- Tags: macOS app, macOS Launch Services window handoff, Native macOS visual evidence, Quality gates, PR label release
- Why / evidence: 这些 tags 由
Package.swift、Sources/SpotiBind/SpotiBindApp.swift、Sources/SpotiBind/UIDemoScenario.swift、scripts/macos/和.github/workflows/支撑。Native macOS visual evidence 只描述严格的目标窗口证据,不替代 macOS bundle 或 release 生命周期。
Repository map
Sources/SpotiBind/SpotiBindApp.swift定义菜单栏应用与.window风格的 popover;Sources/SpotiBind/ApplicationDelegate.swift负责 Demo 启动、应用生命周期和 Launch Services reopen handoff。Sources/SpotiBind/UIDemoScenario.swift提供固定的 UI Demo 状态;AppState.swift将偏好限制在 Demo 可控的UserDefaults范围。scripts/macos/build.sh、capture-theme-ui.sh、capture-settings-window.sh、popover-window-probe.swift与window-probe.swift组成构建、身份探针和窗口捕获入口。docs/specs/spotibind/SPEC.md记录两个目标 surface、四个 Light/Dark 健康资产和错误场景的 smoke-only 边界。
Runtime and delivery
本地 UI evidence 流程先用 scripts/macos/build.sh 从当前源码构建真实 .app,再由项目脚本启动隔离 Demo。settings window 路径从同一 PID 验证 bundle identity、AX role/title 语义和唯一 WindowServer ID,随后才允许执行 screencapture -x -l;popover probe 目前只验证 PID、bundle、WindowServer ID 和几何约束,缺少 AX role/title,因此只能作为迁移输入,不能进入严格正向矩阵。窗口缺失、歧义、不可成像或 PNG 无效都会失败。真实桌面捕获只在受控本机会话中逐次授权,CI 不承担该权限边界。
Architecture notes
应用使用 SwiftUI 菜单栏壳层,媒体键转发逻辑与播放器 adapter 保持可测试边界。UIDemoScenario.swift 让 popover/settings 在不连接真实播放器、网络或硬件的情况下呈现稳定状态;UISnapshot.swift 只用于真实 status-bar host 的窗口验证,不使用 NSPanel、cacheDisplay 或 PDF/bitmap 合成窗口。settings window probe 把应用 PID、bundle identity、Accessibility 语义和 WindowServer ID 绑定为一个证据链;popover probe 尚未绑定 AX role/title,必须在补齐前保持迁移状态。
Workflow and quality gates
scripts/macos/test-ui-capture-contract.sh 静态检查捕获脚本的 screencapture -x -l、status-bar host 和 probe 入口,并拒绝旧的合成窗口路径。.github/workflows/pr.yml 与 scripts/macos/test.sh 运行静态合同、Swift 单元测试和构建检查,不在 CI 申请桌面权限。发布侧由 .github/workflows/release-preparation.yml、release-completion.yml 和 release.yml 维护版本、签名与 release 证据;这些属于 macOS app / delivery 主题,不改变截图合同。
Reusable decisions
- 将 target-window 证据拆成 build、fixture、probe、capture 四个可审查步骤,任何身份不确定性都 fail closed。
- 通过
LSMultipleInstancesProhibited和applicationShouldHandleReopen把重复 Launch Services 请求交给已有进程,再复用 retained settings presenter/window;不创建第二进程、第二窗口或 custom IPC。该模式的完整上下文见docs/solutions/macos/duplicate-launch-settings-window.md。 - 用固定
UIDemoScenario和隔离的用户状态替代真实播放器、网络、Keychain 或硬件,使截图矩阵可复现。 - 将 Light/Dark settings window 作为当前严格健康矩阵;popover 在补齐 AX role/title probe 前只保留为迁移/smoke 输入。
accessibility-required、no-supported-player、path-unavailable和dispatch-failure保留为 smoke-only。 - 项目负责实际 PNG 与 PR 索引,Playbook 只复用合同和 checklist,不把应用截图复制到 Topic package。
Risks and open questions
- macOS WindowServer、Accessibility 语义和 SwiftUI host 的行为受系统版本影响,项目需要在支持的系统范围内重新验证 probe。
- 真实应用捕获仍需要目标项目逐次本机授权;本 snapshot 不代表已在本 Playbook PR 中运行应用或生成新的 PNG。
- 该仓库样本为 private;对外导出的 Playbook 内容只保留相对证据路径和通用合同,不公开来源、checkout 或运行日志。
Evidence index
docs/specs/spotibind/SPEC.mdSources/SpotiBind/SpotiBindApp.swiftSources/SpotiBind/ApplicationDelegate.swiftSources/SpotiBind/AppState.swiftSources/SpotiBind/UIDemoScenario.swiftSources/SpotiBind/UISnapshot.swiftscripts/macos/build.shscripts/macos/capture-theme-ui.shscripts/macos/capture-settings-window.shscripts/macos/popover-window-probe.swiftscripts/macos/window-probe.swiftscripts/macos/test-ui-capture-contract.sh.github/workflows/pr.ymldocs/solutions/macos/duplicate-launch-settings-window.mdSources/SpotiBind/ApplicationDelegate.swiftSources/SpotiBind/SettingsWindowController.swiftSources/SpotiBind/ApplicationPresentationController.swiftpackaging/macos/Info.plistTests/SpotiBindAppTests/ApplicationDelegateTests.swiftTests/SpotiBindAppTests/ApplicationPresentationTests.swift
相关内容
macOS app
主题macOS app 指交付物是原生 macOS 图形应用,仓库需要长期处理 app bundle、平台工具链、桌面运行行为和 macOS 特有能力,而不是只有一个能在 macOS 上运行的 CLI。这里真正重要的是应用外壳和平台契约:如何构建 .app、怎样运行 dev/prod variant、何时接入 Keychain、文件访问与本地状态如何管理,以及后续是否能顺利走到签名、打包或分发(projects/televy-backup.
macOS Launch Services window handoff
主题macOS Launch Services window handoff 指这样的原生 macOS 应用行为合同:用户从 Finder、Dock、Spotlight 或其他正常 Launch Services 入口再次启动一个已经运行的 app 时,系统把请求交给已有进程;已有进程复用 retained presenter 和 retained primary user window,将它恢复并前置,而不是创建第二个进程或第二个窗口。
Native macOS visual evidence
主题Native macOS visual evidence 是一套把原生 macOS 应用的 owner-facing 窗口截图当作可审计交付物的合同。它要求截图来自当前源码构建并运行的真实 .app,并且可以沿着 PID、bundle identifier、Accessibility role/title 语义和唯一 WindowServer window ID 回溯到目标窗口;PNG 只是证据载体,不是验收本身。
PR label release
主题PR label release 是逐 PR 的产品发布协议:PR labels 只提供经过 gate 验证的发布操作与发布阶段;最高的合格 final vX.Y.Z Git release tag 是唯一数字版本基线,VERSION 只锁定 trusted preparation 已决定的精确产品版本。label 不能计算、覆盖或为版本提供 fallback。