根据自然语言需求构建自定义 cmux 侧边栏。当用户要求创建自定义侧边栏、展示其工作区/标签页/PR/时钟的侧边栏、随性定制(vibe-coded)侧边栏,或者涉及 ~/.config/cmux/sidebars/ 中文件的任何需求时使用。涵盖编写解释型 SwiftUI 风格文件、开启 Beta 功能开关、选择侧边栏以及通过热重载快速迭代的完整流程。
cmux 自定义侧边栏
cmux 能在运行时直接解析并渲染轻量级的 SwiftUI 风格文件来生成自定义侧边栏:无需 Xcode、无需构建步骤、无需代码签名。文件在保存时会自动热重载,可以实时绑定 cmux 的动态状态(工作区、标签页、git、PR、时钟),并在点击时触发真实的 cmux 命令。
提出需求的用户描述的是最终效果(例如“帮我做个能显示工作区并且能方便切换的侧边栏”),而不是具体的技术实现。请直接替他们做好技术决策,不要向他们询问 SwiftUI 语法、文件路径或代码细节。
本 Skill 是工作流概要。在编写相对复杂的侧边栏之前,请先阅读完整的编写规范文档(包含所有支持的视图、修饰符、语言特性及数据字段):
cmux docs sidebars
curl -fsSL https://raw.githubusercontent.com/manaflow-ai/cmux/main/docs/custom-sidebars.md
工作流
- 开启 Beta 功能(仅需设置一次):设置(Settings)> Beta 功能(Beta features)> 自定义侧边栏(Custom sidebars,配置项
customSidebars.beta.enabled)。如果写好的侧边栏没有出现在选择器中,请优先检查此项。 - 在
~/.config/cmux/sidebars/<name>.swift创建命名文件。文件名会直接作为菜单上的显示标签;请使用短 kebab-case 格式。该文件是一个独立的 SwiftUI 风格视图表达式(无需struct、无需var body,也无需 import 语句)。虽然也支持.json变体来放置静态布局,但对于任何动态效果,请首选.swift。 - 校验与选中:
用户也可以右键点击侧边栏切换按钮来进行选择。cmux sidebar validate <name> # 使用真实数据结构进行解析与解释执行校验 cmux sidebar select <name> - 迭代调试。保存文件即可完成原地热重载(也可使用
cmux sidebar reload强制重载)。在宣布完成前,请确认各项列表展现的是真实数据,且点击操作行为正常。
编写规则
- 绑定到
workspaces上下文,而不是硬编码文本,这样侧边栏能始终保持数据同步。 - 代表可打开项的行,在点击时应运行对应的
cmux(...)操作。仅展示纯文本的列表通常不是用户想要的。 - 对于类似工作区的列表,请使用
Reorderable;它直接开箱即用支持持久化的拖拽排序。 - 保持原生且清爽的视觉样式:标题、分隔线,然后是具体内容。
- 对长列表进行截断(例如
.prefix(20),在渲染前先过滤/排序)。侧边栏大约每秒重新评估更新一次。 - 严格在受支持的语法子集中编写。不支持的语法会被平滑跳过而不是直接崩溃,但应当选择最接近的受支持方案,避免交付一个半空白的侧边栏。
快速上手
cat > ~/.config/cmux/sidebars/mine.swift <<'SWIFT'
VStack(alignment: .leading, spacing: 8) {
Text("My sidebar").font(.title3).bold()
Text(clock.time).font(.caption).foregroundColor(.secondary)
Divider()
Reorderable(workspaces, move: "workspace.reorder") { w in
Button(action: { cmux("workspace.select", workspace_id: w.id) }) {
HStack {
Text(w.selected ? "●" : "○").foregroundColor(w.selected ? "#FF8800" : .secondary)
Text(w.title)
Spacer()
}.padding(4)
}
}
}
SWIFT
cmux sidebar validate mine && cmux sidebar select mine
实时数据上下文(只读,刷新频率约 1s)
workspaces:id、title、selected、pinned、index、directory、ports+portCount、unread、tabs+tabCount;存在时还包含description、color、branch+dirty、pr/prs({number, label, url, status, stale, branch})、progress({value, label})、latestMessage、latestPrompt、latestAt、remote({target, state, connected})。workspaces[i].tabs:id、title、focused、pinned;可用时还包含directory、branch+dirty、ports。clock:{time, hour, minute, second, weekday, epoch}。- 标量字段:
workspaceCount、selectedTitle、selectedId、unreadTotal。
可选字段在缺失时会被忽略;请使用 if let b = w.branch { ... } 或 w.pr != nil ? ... : ... 进行安全防护。
操作指令
按钮或 .onTapGesture 主体通过 cmux("<method>", param: value) 进行调用,分发途径与 CLI 相同。常用方法包括:workspace.select (workspace_id)、surface.focus (surface_id)、workspace.reorder (workspace_id + index)。openURL("https://...") 用于打开外部链接。完整命令接口可查阅:cmux docs api。
支持的语法子集
容器组件:Stacks 布局(包括 Lazy 变体)、Group、List、Section、Grid 网格、ViewThatFits、ScrollView、HSplitView(双列可调大小分栏)。内容组件:Text、Label、Image(systemName:)、Button(支持 title 和 label 两种形式)、Menu、ProgressView、Gauge、Spacer、Divider、几何图形(Shapes)、通过 .background 实现的渐变。修饰符:完整排版样式集、十六进制字符串或 Token 格式的颜色、.padding/.frame/布局、支持任意嵌套视图的 .background/.overlay/.mask/.contextMenu、阴影/边框/透明度/视觉效果、.onTapGesture、.help、.disabled。语言特性:let、自定义 func 辅助函数、for/ForEach、if/else、三元运算符、字符串插值、算术运算、数组方法(filter/map/sorted/prefix)、字符串与数字格式化。
暂不支持的功能(直接按标准 Swift 方式编写即可,系统会平滑降级):@State 以及输入控件(TextField、Toggle、Slider、Picker)、自定义 struct/View 定义、导航相关(sheet/popover)、AsyncImage。目前暂不支持双向编辑数据绑定;但点击触发 cmux(...) 命令是可以正常工作的。
故障排查
- 右键选择器中找不到:Beta 功能开关未开启,或者文件未直接放置在
~/.config/cmux/sidebars/目录下。 - 渲染为空或仅渲染部分:运行
cmux sidebar validate <name>。错误信息会直接在侧边栏中内联显示,并标明出错位置;如果保存的代码有错,屏幕上会保留上一次正常渲染的结果,因此修复后再重新保存即可。 - 列表行不可点击:将该行包裹在
Button(action: { cmux(...) }) { ... }中,或添加.onTapGesture { cmux(...) }。 - 拖拽排序无法持久化:请使用
Reorderable(data, move: "workspace.reorder"),而不是List/.onMove/.draggable。






