cmux 环境搭建、Xcode 项目规范化、带 Tag 的侧边栏 ExtensionKit 开发及开发构建的贡献者工作流规范。在初始化 cmux 仓库、修改 Xcode 项目文件、添加侧边栏扩展或使用带 Tag 的 Debug 构建时使用。
cmux 开发工作流
初始搭建
./scripts/setup.sh 会初始化子模块(submodules)、构建 GhosttyKit,并安装用于规范化 pbxproj 的 pre-commit 钩子。
带 Tag 的本地开发
每次修改代码后,都需要重新构建 Debug 应用:
./scripts/reload.sh --tag <short-tag>
该脚本只负责构建而不自动启动;仅在需要打开应用时才加上 --launch 参数。切勿直接运行裸 xcodebuild 命令或打开未带 Tag 的 cmux DEV.app:未带 Tag 的构建会与其它 Agent 共享默认的 Debug socket 和 Bundle ID,导致冲突并抢占窗口焦点。
针对带 Tag 的 Debug 应用进行 CLI 或 Socket 狗粮测试(dogfood):
CMUX_TAG=<tag> scripts/cmux-debug-cli.sh list-workspaces
在进行带 Tag 的狗粮测试时,请勿使用 /tmp/cmux-cli;该软链接始终指向最新重载的构建版本。详情参阅 references/tagged-builds.md。
Xcode 工具链
团队统一固定使用 Xcode 26.x 版本。.xcode-version 是主版本号的唯一真理源(single source of truth);cmux.xcodeproj/project.pbxproj 中包含 objectVersion = 60,这是 Xcode 26 默认写入的值。(objectVersion = 77 专门留给同步文件夹组(synchronized folder groups)使用,而 cmux 并未使用该特性。)
scripts/setup.sh 会安装项目里受版本控制的 scripts/git-hooks/pre-commit。该钩子会在任何暂存的 project.pbxproj 上运行 scripts/normalize-pbxproj.py,确保 Xcode 不确定的排序变更永远不会进入 Commit 中。该钩子具备幂等性(idempotent)。CI 会运行 scripts/check-pbxproj.sh 来强制校验 objectVersion 的版本固定与规范化处理,因此如果跳过了该钩子,PR 将直接报错拦截。升级固定版本是团队慎重决定的事项,详情参阅 references/xcode-project-normalization.md。
侧边栏扩展点(开发构建 Tag 隔离)
每个带 Tag 的开发构建都会拥有自己独立的 ExtensionKit 侧边栏扩展点,防止多个并发开发构建之间发生冲突。这由三个构建设置(build settings)驱动:
CMUX_SIDEBAR_EXTENSION_POINT_ID(默认为com.cmuxterm.app.cmux.sidebar):构建时压入 Info.plist 的扩展点标识符(identifier)。CMUX_BUNDLE_ID_SUFFIX(默认为空):插入到 app 和 appex 的 Bundle ID 中,使带 Tag 的扩展拥有独立身份,以便 pkd 能够单独记录。CMUX_DISPLAY_NAME_SUFFIX(默认为空):追加到 appex 的CFBundleDisplayName末尾。操作系统在宿主应用读取启用/禁用与可用计数时,会按显示名称(display name)对侧边栏扩展进行分组;因此,如果同时安装了两个同名的 appex,系统会将它们视为同一个逻辑扩展,开关其中一个会影响到另一个。
宿主应用会在运行时通过 CmuxSidebarExtensionPoint.identifier(in:) 从 Info.plist 的键名 CMUXSidebarExtensionPointIdentifier 中解析出自身的扩展点 ID。运行 ./scripts/reload.sh --tag <tag> 会将宿主扩展点作用域限制为 com.cmuxterm.app.debug.<tag>.cmux.sidebar。如需构建匹配该 Tag 作用域的示例扩展,请运行:
./scripts/reload-extension.sh --tag <tag> [--host-bundle-id <id>] [--example sample|tabs|both]
参阅 references/sidebar-extension-tagging.md 了解其传递的配置参数、无需重新签名(no-re-signing)的规则,以及编写新的支持 Tag 的示例扩展的检查清单。






