根據自然語言需求建立自訂 cmux 側邊欄。當使用者要求自訂側邊欄、顯示工作區/分頁/PR/時鐘的側邊欄、特定風格(vibe-coded)側邊欄,或是涉及 ~/.config/cmux/sidebars/ 檔案時使用。涵蓋撰寫直譯式 SwiftUI 風格檔案、開啟 Beta 功能旗標、選取側邊欄,以及透過熱重載(Hot Reload)進行迭代。
cmux Custom Sidebar
cmux 能在執行期(runtime)直接根據精簡的 SwiftUI 風格檔案繪製自訂側邊欄:不需要 Xcode、不需要建置步驟,也不需要簽署。檔案只要存檔就會熱重載(hot-reload),可直接綁定 cmux 的即時狀態(工作區、分頁、git、PR、時鐘),並在點擊時執行真實的 cmux 指令。
提出需求的人通常是在描述期望的結果(例如:「一個能顯示我的工作區並讓我快速切換的側邊欄」),而非具體的實作方式。請直接替他們做好工程決策;不要反問他們關於 SwiftUI、檔案結構或語法細節的問題。
本 Skill 是工作流程的總覽。在撰寫較複雜的側邊欄之前,請務必先閱讀完整的撰寫規範(包含所有支援的 View、Modifier、語言特性與資料欄位):
cmux docs sidebars
curl -fsSL https://raw.githubusercontent.com/manaflow-ai/cmux/main/docs/custom-sidebars.md
Workflow
- 啟用 Beta 功能(僅需一次):設定 (Settings) > Beta 功能 (Beta features) > 自訂側邊欄 (Custom sidebars,
customSidebars.beta.enabled)。如果寫好的側邊欄沒有出現在選單中,請先檢查此設定。 - 建立指定名稱的檔案,路徑為
~/.config/cmux/sidebars/<name>.swift。檔名即為選單標籤,請使用簡短的 kebab-case。檔案內容為單一 SwiftUI 風格的 View 運算式(不需要struct、不需要var body,也不需要import)。如果是靜態版面配置也可以使用.json格式;但只要涉及動態內容,建議優先選擇.swift。 - 驗證與選取:
使用者也可以透過右鍵點擊側邊欄切換按鈕來選取它。cmux sidebar validate <name> # 使用真實資料結構進行剖析與直譯檢查 cmux sidebar select <name> - 迭代修訂。 儲存檔案即可原地熱重載(亦可使用
cmux sidebar reload強制重載)。在宣告完成前,請先確認每一列都正確顯示真實資料,且點擊動作能正常運作。
Authoring rules
- 綁定
workspaces上下文,避免硬編碼(hard-code)文字,確保側邊欄能自動保持最新狀態。 - 代表可開啟項目的列表列(Row),點擊時應執行對應的
cmux(...)動作。純文字顯示的列表通常不符使用者期待。 - 類似工作區的列表請使用
Reorderable;它能直接提供持久化的拖放重排(drag-and-drop reordering)功能。 - 保持原生且簡潔的風格:標題、分隔線,接著是主要內容。
- 限制長列表的顯示數量(在渲染前使用
.prefix(20)或是先進行過濾/排序)。側邊欄大約每秒會重新評估一次。 - 請勿超出支援的語法子集。遇到不支援的語法時會優雅跳過而非崩潰,但仍應選擇最接近的替代方案,避免交付半空白的側邊欄。
Quick start
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
Live data context (read-only, refreshes ~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}。- 純量(Scalars):
workspaceCount、selectedTitle、selectedId、unreadTotal。
可選欄位在不存在時會直接省略;請使用 if let b = w.branch { ... } 或 w.pr != nil ? ... : ... 進行安全防護。
Actions
Button 或 .onTapGesture 區塊可呼叫 cmux("<method>", param: value),其發送管道與 CLI 相同。常用方法包括:workspace.select (workspace_id)、surface.focus (surface_id)、workspace.reorder (workspace_id + index)。使用 openURL("https://...") 可開啟連結。完整指令介面請查閱:cmux docs api。
Supported subset
容器(Containers):Stacks(包含 Lazy 系列)、Group、List、Section、Grids、ViewThatFits、ScrollView、HSplitView(雙欄可調整大小)。內容元件(Content):Text、Label、Image(systemName:)、Button(title 與 label 形式)、Menu、ProgressView、Gauge、Spacer、Divider、圖形(shapes)、透過 .background 建立的漸層(gradients)。修飾符(Modifiers):完整字型設定、Hex 字串或 Token 顏色、.padding/.frame/版面配置、支援任意巢狀 View 的 .background/.overlay/.mask/.contextMenu、陰影/邊框/不透明度/特效、.onTapGesture、.help、.disabled。語言特性(Language):let、自訂 func 輔助函式、for/ForEach、if/else、三元運算子、字串插值、算術運算、陣列方法(filter/map/sorted/prefix)、字串與數字格式化。
尚未支援(仍可照常寫出自然 Swift,系統會優雅降級處理):@State 與輸入控制元件(TextField、Toggle、Slider、Picker)、自訂 struct/View 定義、導覽快顯(sheet/popover)、AsyncImage。目前尚不支援雙向編輯;但點擊觸發 cmux(...) 動作可正常運作。
Troubleshooting
- 未出現在右鍵選單中:Beta 功能旗標未開啟,或檔案未直接放置於
~/.config/cmux/sidebars/目錄下。 - 畫面空白或僅部分渲染:請執行
cmux sidebar validate <name>。錯誤訊息會直接行內(inline)顯示在側邊欄中並標示出錯位置;存檔出錯時畫面會保留上一次正常渲染的結果,請修復後重新存檔。 - 列表列無法點擊:請將該列包覆在
Button(action: { cmux(...) }) { ... }中,或加上.onTapGesture { cmux(...) }。 - 重新排序無法持久化保存:請使用
Reorderable(data, move: "workspace.reorder"),而非List/.onMove/.draggable。






