Add set-color/clear-color workspace actions for tab color via CLI - #1873
Conversation
Expose the existing tab color functionality through the workspace-action CLI command, enabling programmatic tab color setting without the GUI context menu. Supports both named colors (Red, Blue, Amber, etc.) and hex values (#RRGGBB). Named colors resolve against the built-in palette via case-insensitive matching. Usage: cmux workspace-action --action set-color --color blue cmux workspace-action --action set-color --color "#C0392B" cmux workspace-action set-color Amber cmux workspace-action clear-color
|
@arieltobiana is attempting to deploy a commit to the Manaflow Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
📝 WalkthroughWalkthroughWorkspace action parsing and handling for Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as CLI Parser
participant Server as TerminalController
participant Palette as WorkspaceTabColorSettings
User->>CLI: workspace-action set_color blue
CLI->>CLI: Infer color (positional or --color)
CLI->>Server: RPC workspace.action params["color"]
Server->>Server: Trim input
Server->>Palette: Request defaultPaletteWithOverrides()
Palette-->>Server: Named palette
Server->>Palette: Case-insensitive match for "blue"
alt Named match
Palette-->>Server: Return hex (`#xxxxxx`)
Server->>Server: Set tab color to hex
Server-->>CLI: finish({ "color": "#xxxxxx" })
else No named match
Server->>Server: Attempt hex normalization
alt Valid hex
Server->>Server: Set tab color to hex
Server-->>CLI: finish({ "color": "#xxxxxx" })
else Invalid
Server-->>CLI: invalid_params (message + named_colors)
end
end
CLI-->>User: Print response (includes color=<value> if present)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip You can disable the changed files summary in the walkthrough.Disable the |
Greptile SummaryThis PR wires the existing tab color functionality ( Key changes and observations:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User as User (CLI)
participant CLI as cmux.swift
participant Socket as SocketClient
participant TC as TerminalController
participant WCS as WorkspaceTabColorSettings
participant TM as TabManager
User->>CLI: cmux workspace-action set-color Amber
CLI->>CLI: Parse action="set_color", infer color from positional="Amber"
CLI->>CLI: Trim whitespace, validate non-empty
CLI->>Socket: sendV2("workspace.action", {action:"set_color", color:"Amber"})
Socket->>TC: v2WorkspaceAction(params)
TC->>WCS: defaultPaletteWithOverrides()
WCS-->>TC: [WorkspaceTabColorEntry, ...]
TC->>TC: caseInsensitiveCompare("Amber") → found → hex="#FFC107"
TC->>TM: setTabColor(tabId:, color:"#FFC107")
TC-->>Socket: finish(["color": "#FFC107"])
Socket-->>CLI: payload {color:"#FFC107", ...}
CLI-->>User: OK action=set_color color=#FFC107
User->>CLI: cmux workspace-action clear-color
CLI->>Socket: sendV2("workspace.action", {action:"clear_color"})
Socket->>TC: v2WorkspaceAction(params)
TC->>TM: setTabColor(tabId:, color:nil)
TC-->>Socket: finish()
Socket-->>CLI: payload {action:"clear_color", ...} (no color key)
CLI-->>User: OK action=clear_color
Last reviewed commit: "Add set-color/clear-..." |
Restore "color": null in the clear_color response payload so JSON consumers can distinguish "color was cleared" from "no color field".
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
CLI/cmux.swift (1)
3299-3315: Reject stray trailing args for non-value actions.After the inference split, commands like
workspace-action clear-color extrano longer reuseextraas a title, but they still succeed while silently dropping it. That makes typos look successful. Consider erroring whenever leftover positional text exists for actions other thanrenameandset-color.Possible follow-up
let action = actionRaw.lowercased().replacingOccurrences(of: "-", with: "_") + if action != "rename", action != "set_color", + let extra = positional.first(where: { + !$0.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty + }) { + throw CLIError( + message: "workspace-action \(actionRaw) does not accept trailing argument '\(extra)'" + ) + } let workspaceArg = workspaceOpt ?? (windowOverride == nil ? ProcessInfo.processInfo.environment["CMUX_WORKSPACE_ID"] : nil) let workspaceId = try normalizeWorkspaceHandle(workspaceArg, client: client, allowCurrent: true)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@CLI/cmux.swift` around lines 3299 - 3315, After computing action (from actionRaw) and inferredPositional, add a validation that rejects any non-empty inferredPositional for actions that do not accept a trailing value: i.e., if inferredPositional is not empty and action is not "rename" and not "set_color" then throw a CLIError with a clear message about unexpected trailing arguments; place this check after title/color inference (near where title is derived and color is trimmed) so it covers both rename and set_color exceptions and references action, inferredPositional, and CLIError.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Sources/TerminalController.swift`:
- Around line 4071-4087: The palette-derived hex (entry.hex from
effectivePalette in the lookup block) must be normalized before being used or
reported because user overrides may be malformed; change the code that handles
the found entry to call WorkspaceTabColorSettings.normalizedHex(entry.hex) and
assign that normalized value to hex (and if normalization returns nil treat it
like the invalid branch and return the same error), then call
tabManager.setTabColor(tabId:workspace.id, color:hex) and finish(["color":hex])
so the persisted and reported color match.
---
Nitpick comments:
In `@CLI/cmux.swift`:
- Around line 3299-3315: After computing action (from actionRaw) and
inferredPositional, add a validation that rejects any non-empty
inferredPositional for actions that do not accept a trailing value: i.e., if
inferredPositional is not empty and action is not "rename" and not "set_color"
then throw a CLIError with a clear message about unexpected trailing arguments;
place this check after title/color inference (near where title is derived and
color is trimmed) so it covers both rename and set_color exceptions and
references action, inferredPositional, and CLIError.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b365707a-99e1-4fd3-a86f-5e17e75d20b3
📒 Files selected for processing (2)
CLI/cmux.swiftSources/TerminalController.swift
There was a problem hiding this comment.
No issues found across 2 files
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Add one-off context when rerunning by tagging
@cubic-dev-aiwith guidance or docs links (includingllms.txt) - Ask questions if you need clarification on any suggestion
|
Re: CodeRabbit nitpick about rejecting stray trailing args for non-value actions (e.g. Good suggestion — this is a pre-existing behavior across all workspace actions (e.g. |
|
Thank you for the contribution! |
…naflow-ai#1873) * Add set-color/clear-color workspace actions for tab color via CLI Expose the existing tab color functionality through the workspace-action CLI command, enabling programmatic tab color setting without the GUI context menu. Supports both named colors (Red, Blue, Amber, etc.) and hex values (#RRGGBB). Named colors resolve against the built-in palette via case-insensitive matching. Usage: cmux workspace-action --action set-color --color blue cmux workspace-action --action set-color --color "#C0392B" cmux workspace-action set-color Amber cmux workspace-action clear-color * Return explicit null color in clear_color JSON response Restore "color": null in the clear_color response payload so JSON consumers can distinguish "color was cleared" from "no color field". --------- Co-authored-by: Ariel Tobiana <arieltobiana@gmail.com>
…naflow-ai#1873) * Add set-color/clear-color workspace actions for tab color via CLI Expose the existing tab color functionality through the workspace-action CLI command, enabling programmatic tab color setting without the GUI context menu. Supports both named colors (Red, Blue, Amber, etc.) and hex values (#RRGGBB). Named colors resolve against the built-in palette via case-insensitive matching. Usage: cmux workspace-action --action set-color --color blue cmux workspace-action --action set-color --color "#C0392B" cmux workspace-action set-color Amber cmux workspace-action clear-color * Return explicit null color in clear_color JSON response Restore "color": null in the clear_color response payload so JSON consumers can distinguish "color was cleared" from "no color field". --------- Co-authored-by: Ariel Tobiana <arieltobiana@gmail.com>
Transcribed from upstream manaflow-ai/cmux HEAD b46dcb7 per ADR-0004 amendment (narrow slices with upstream PR breadcrumbs, never rebase). Implements fadi-orchestrator#26 and #27. fadi-orchestrator#26: - workspace.action set_color/clear_color with upstream's shape: 16-color named palette or #RRGGBB, named_colors in the error payload (upstream: PR manaflow-ai#1873). Drives the existing customColor rail end to end (sidebar left rail, bonsplit tab accent, ghostty_surface_set_accent_color). - workspace.action set_description/clear_description wired into new per-workspace state Workspace.customDescription, persisted through SessionWorkspaceSnapshot (upstream: PR manaflow-ai#2475). - CLI: workspace-action --color/--description flags + help. - waitAfterCommand child-exit handling: TerminalChildExitPolicy (upstream: PR manaflow-ai#8681) — SHOW_CHILD_EXITED now reads runtime ms; normal/established exits (Ctrl+D, tmux detach) close the pane so a spawn-command surface is never stranded, abnormal fast exits keep the dead surface visible for inspection (handler returns false so ghostty renders its error text). - Spawn-command seam (ADR-0004): surface.create accepts an optional "command"; plumbed through newTerminalSurface -> TerminalPanel -> TerminalSurface into ghostty_surface_config_s.command with wait_after_command=true. fadi-orchestrator#27: - Label precedence: upstream's CustomTitleSource (.user/.auto) provenance for workspace and panel custom titles (upstream: PR manaflow-ai#5547). .auto (daemon semantic label) beats auto-derived titles but never overwrites or clears a user rename; ordering documented on Workspace.resolvedPanelTitle; provenance persists through session snapshots. - workspace.set_auto_title verb transcribed (probe/panel_id/ panel_only_if_multiple), minus upstream's opt-in auto-naming setting — fadid is the labeler here, so always enabled. - Hover description: .help() on the sidebar workspace row, applied only when a description exists. (The pane tab bar lives in the vendor/bonsplit submodule — follow-up via bonsplit remote.) Also contained build fixes in shared files, required to compile the fadi-layer snapshot: PanelType.observatory switch arms in Workspace.swift, dedup of Color(hex:) in ContentView (Fadicode's internal extension collides with the old private one), and pbxproj registration for Sources/Fadicode/Helpers/NetworkRetry.swift which existed on disk but was never in the target. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
workspace-actionCLI commandRed,Blue,Amber, etc.) and hex values (#RRGGBB)WorkspaceTabColorSettings.defaultPaletteWithOverrides()(respects user hex overrides, excludes ad-hoc custom entries)Usage
cmux workspace-action --action set-color --color blue cmux workspace-action --action set-color --color "#C0392B" cmux workspace-action set-color Amber cmux workspace-action clear-colorImplementation
No new infrastructure needed — this wires up the existing
tabManager.setTabColor(tabId:color:)method (used by the right-click context menu) to the socket-based CLI.Sources/TerminalController.swift: Addedset_colorandclear_colortov2WorkspaceAction. Theset_colorhandler resolves named colors fromdefaultPaletteWithOverrides(), falls back to hex validation vianormalizedHex(), and returns an error with the list of valid color names if neither matches.CLI/cmux.swift: Added--colorflag parsing torunWorkspaceAction(), trims whitespace before validation, restricts positional inference to onlyrename(title) andset-color(color) actions, and updated help text with named color list and examples.Test plan
cmux workspace-action --action set-color --color bluesets tab color to bluecmux workspace-action set-color Ambersets tab color to amber (positional syntax)cmux workspace-action --action set-color --color "#C0392B"sets tab color via hexcmux workspace-action clear-colorremoves tab colorcmux workspace-action --helpshows new actions, flags, and examples--color " "is rejected (whitespace trimming)workspace-action clear-color extradoes not silently sendtitle=extraSummary by cubic
Adds CLI actions to set or clear a workspace tab color via
workspace-action. Supports named colors and#RRGGBB, trims whitespace, improves help, and returns explicit null on clear.New Features
set-colorandclear-colortoworkspace-action.WorkspaceTabColorSettings.defaultPaletteWithOverrides(); hex validated withnormalizedHex().set-color; onlyrenameinfers positional title; trims whitespace.named_colors; help and CLI summary updated with color names, examples, andcolorin output.Bug Fixes
clear-colorJSON response now includes"color": nullto signal a cleared value.Written for commit f70991d. Summary will update on new commits.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation