* 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>
The socket API's send-key command only supported enter, escape, tab,
backspace, and ctrl+letter. Arrow keys and shift+tab had to be sent
as raw escape sequences via send_text, but 0x1B is filtered out by
socketTextChunks and converted to a standalone Escape key event,
breaking multi-byte sequences like \x1b[A (ArrowUp).
This commit extends sendNamedKey to handle:
- Arrow keys: up/down/left/right (with arrow_up/arrowup aliases)
- shift+tab / shift-tab / backtab
- home, end
- delete / del / forward_delete
- pageup / page_up
- pagedown / page_down
These map directly to the existing sendKeyEvent infrastructure using
the appropriate kVK_* keycodes and modifier flags.
Co-authored-by: I Luk Kim <yirugi@gmail.com>
* fix(browser): use native value setter for React/Vue/Angular compatibility
fill, type, and select commands set input values via direct property
assignment (el.value = x), which does not trigger state updates in
frameworks that override the value setter on element instances.
Use Object.getOwnPropertyDescriptor on the prototype to call the
native setter, which bypasses the framework override and allows the
subsequent input/change events to propagate correctly through
React's synthetic event system.
Affects: browser.fill, browser.type, browser.select
* walk prototype chain instead of instanceof for cross-realm and web component support
---------
Co-authored-by: joshuaswanson <joshuaswanson@users.noreply.github.com>
Add tty field to surface items in system.tree JSON response,
reading from existing surfaceTTYNames dictionary. Also show
tty= in the CLI text tree output for terminals that have a
registered TTY.
This enables external tools (e.g. CodeV) to cross-reference
claude process TTYs with cmux surfaces for accurate session
detection when multiple sessions share the same working directory.
* Allow customizing numbered workspace and surface shortcuts
* Update bonsplit submodule to squashed main commit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Fixes#1715
The resolveTabForReport() function had an early guard that returned nil
when self.tabManager was nil, even when a valid --tab argument was
provided. This prevented Claude hook commands from resolving tabs via
AppDelegate.shared when the local tabManager wasn't available.
Changes:
- Modified resolveTabForReport() to allow tab resolution via --tab param
even when self.tabManager is nil
- Removed early guard in upsertSidebarMetadata() that blocked resolution
Co-authored-by: BillionClaw <267901332+BillionClaw@users.noreply.github.com>
* Fix stale Claude status in sidebar by adding missing hooks and OSC suppression
The Claude Code integration only used 3 hooks (SessionStart, Stop, Notification),
leaving gaps that caused stale sidebar status. Now uses 6 hooks:
- SessionEnd: clears status when Claude exits (covers Ctrl+C where Stop doesn't fire)
- UserPromptSubmit: clears "Needs input" and sets "Running" on new prompt
- PreToolUse (async): clears "Needs input" when Claude resumes after permission grant
Also:
- Suppress OSC 9/99 desktop notifications for workspaces with active Claude hook
sessions to prevent duplicates from the raw OSC path
- Store Claude process PID in status entries for stale-session detection
- Add 30-second sweep timer that checks agent PIDs and clears stale entries
(safety net for SIGKILL/crash where no hook fires)
- Update wrapper test expectations for the new hook set
Fixes https://github.com/manaflow-ai/cmux/issues/1301
* Don't show "Running" status on Claude launch, only when actually working
SessionStart now registers the PID for tracking and OSC suppression via
set_agent_pid without setting a visible status entry. "Running" only
appears when the user submits a prompt (UserPromptSubmit) or Claude
starts using tools (PreToolUse).
Added set_agent_pid / clear_agent_pid socket commands to decouple PID
tracking from visible status entries. OSC suppression checks agentPIDs
instead of statusEntries so it works during the initial idle period.
* Don't restore status entries across app restarts
Status entries are ephemeral runtime state tied to running processes
(e.g. claude_code "Running"). Restoring them after restart shows stale
status for processes that no longer exist.
* Address PR review comments and remove debug logging
- session-end: only clear status/PID/notifications when Stop didn't fire first
- PID sweep: check errno == ESRCH instead of treating all kill(pid,0) failures as dead
- Validate CMUX_CLAUDE_PID > 0
- Propagate tracked PID in pre-tool-use setClaudeStatus
- OSC suppression: use tabManagerFor(tabId:) for multi-window support
- clearAgentPID: resolve tab UUID before async dispatch
- restoreSessionSnapshot: also clear agentPIDs alongside statusEntries
- Fix AskUserQuestion surfaceId overwrite (wrong workspace notification)
- Fix notification text matching for "Claude Code needs your attention"
- AskUserQuestion: render option labels as bracketed inline text
- Remove artificial text truncation limits
- Remove temporary JSONL debug logging from all handlers
* Use resolveTabIdForSidebarMutation in clearAgentPID
* Fallback stable socket listener to user socket path
* Move stable socket path out of /tmp
* Keep socket health checks active on fallback paths
---------
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add cmux welcome command with ASCII logo and shortcuts
Adds `cmux welcome` CLI command that prints a blue-to-purple gradient
chevron logo, version info, and key shortcuts. Auto-runs once on first
workspace creation via UserDefaults. Adds "Welcome" to the ? help menu
in the sidebar footer, which opens a new workspace running the command.
* Polish welcome, feedback, and shortcuts flows
* Add workspace pages in the titlebar
* Add workspace pages UI test target entry
* Relax workspace pages UI test titlebar checks
* Use page close button in workspace pages UI test
* Stabilize workspace pages UI test interruptions
* Skip page close confirms in UI tests
* Clean up superseded workspace handoffs
* Tighten page hint UI assertions
---------
Co-authored-by: cmux <cmux@cmuxs-Mac-mini.local>