Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Build a custom cmux sidebar from a plain-language request. Use when the user asks for a custom sidebar, a sidebar that shows their workspaces/tabs/PRs/clock, a vibe-coded sidebar, or anything involving files in ~/.config/cmux/sidebars/. Covers authoring the interpreted SwiftUI-style file, enabling the beta flag, selecting it, and iterating with hot reload.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 29% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -31% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -16% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 5% | 0% |
| case-06 | ✗→✓ | ▲ Improved | -10% | 0% |
cmux renders custom sidebars from a small SwiftUI-style file at runtime: no Xcode, no build step, no signing. The file hot-reloads on save, binds to live cmux state (workspaces, tabs, git, PRs, clock), and runs real cmux commands on tap.
The person asking is describing a result ("a sidebar that shows my workspaces and lets me jump between them"), not an implementation. Make the engineering decisions for them; do not ask them about SwiftUI, files, or syntax.
This skill is the workflow summary. Read the complete authoring contract (every supported view, modifier, language feature, and data field) before writing a non-trivial sidebar:
bashcmux docs sidebars curl -fsSL https://raw.githubusercontent.com/manaflow-ai/cmux/main/docs/custom-sidebars.md
customSidebars.beta.enabled). If a written sidebar does not appear in the picker, check this first.~/.config/cmux/sidebars/<name>.swift. The name becomes the menu label; use short kebab-case. The file is a single SwiftUI-style view expression (no struct, no var body, no imports). A .json variant exists for static layouts; prefer .swift for anything dynamic.bash cmux sidebar validate <name> # parse/interpret check with real data shapes cmux sidebar select <name> The user can also right-click the sidebar toggle button to pick it.
cmux sidebar reload forces it). Verify rows show real data and taps do the right thing before declaring it done.workspaces context instead of hard-coding text, so the sidebar stays correct on its own.cmux(...) action on tap. A list that only displays text is rarely what they wanted.Reorderable for workspace-like lists; it gives persisted drag-and-drop reordering for free..prefix(20), filter/sort before rendering). The sidebar re-evaluates about once a second.bashcat > ~/.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
workspaces: id, title, selected, pinned, index, directory, ports + portCount, unread, tabs + tabCount; when present also 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; plus directory, branch + dirty, ports when available.clock: {time, hour, minute, second, weekday, epoch}.workspaceCount, selectedTitle, selectedId, unreadTotal.Optional fields are omitted when absent; guard with if let b = w.branch { ... } or w.pr != nil ? ... : ....
A button or .onTapGesture body calls cmux("<method>", param: value), dispatched through the same surface as the CLI. Common methods: workspace.select (workspace_id), surface.focus (surface_id), workspace.reorder (workspace_id + index). openURL("https://...") opens links. Full command surface: cmux docs api.
Containers: stacks (including lazy), Group, List, Section, grids, ViewThatFits, ScrollView, HSplitView (two resizable columns). Content: Text, Label, Image(systemName:), Button (title and label form), Menu, ProgressView, Gauge, Spacer, Divider, shapes, gradients via .background. Modifiers: full typography set, colors as hex strings or tokens, .padding/.frame/layout, .background/.overlay/.mask/.contextMenu with arbitrary nested views, shadows/borders/opacity/effects, .onTapGesture, .help, .disabled. Language: let, user func helpers, for/ForEach, if/else, ternary, string interpolation, arithmetic, array methods (filter/map/sorted/prefix), string and number formatting.
Not yet supported (write the natural Swift anyway; it degrades gracefully): @State and input controls (TextField, Toggle, Slider, Picker), custom struct/View definitions, navigation (sheet/popover), AsyncImage. Two-way editing does not work yet; taps that run cmux(...) do.
~/.config/cmux/sidebars/.cmux sidebar validate <name>. Errors show inline in the sidebar with the failing location; a broken save keeps the last working render on screen, so re-save after fixing.Button(action: { cmux(...) }) { ... } or add .onTapGesture { cmux(...) }.Reorderable(data, move: "workspace.reorder"), not List/.onMove/.draggable.Other measured skills in the registry, with their headline benchmark lift.