* 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
Previously, Cmd+W on the last surface kept the workspace alive with a
replacement shell, unless the user toggled a hidden setting. This was
confusing—users expect Cmd+W to close the window when there's nothing
left.
Now Cmd+W (and the tab-strip X button) always close the workspace when
they close its last surface, and close the window when that was the last
workspace. Internal/programmatic closes (e.g. process exit, panel moves)
still spawn a replacement shell so the workspace stays alive.
Key changes:
- Track explicit user close gestures via markExplicitClose / onTabCloseRequest
- Remove the LastSurfaceCloseShortcutSettings toggle (now always-on)
- Use window.performClose for last-workspace window close
- Update tests to match the new behavior
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Snapshot TabManager's published state (tabs, selectedTabId) at the start
of workspace creation so mutations don't bounce through Combine-backed
accessors mid-creation. Prevents crashes when adding a workspace via
Cmd+N, the new-workspace button, or any other creation path that
triggers re-entrant publishes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add last-surface close regression tests
* Keep workspaces open when closing last surface
* Add Cmd+W last-surface close setting
* Share Cmd+W surface-close path
* Add multi-workspace close UI regression test
* Summarize multi-workspace close confirmation
* Add Cmd+Shift+W multi-close UI regression test
* Honor sidebar multi-select for close workspace
---------
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add typing hot path timing diagnostics
* Add stress workspace debug menu item
* Restore stress workspace preload debug path
* Reduce typing lag from sidebar re-evaluation and hitTest overhead
hitTest: gate divider/sidebar/drag routing to pointer events only,
avoiding two full view-tree walks per non-pointer event.
forceRefresh: replace per-keystroke ISO8601DateFormatter + FileHandle
I/O with dlog() in DEBUG builds.
TabItemView: replace @EnvironmentObject subscriptions with plain refs
and precomputed parameters, add Equatable conformance to skip body
re-evaluation when parent rebuilds with unchanged values. @self changed
re-evaluations dropped from 668 to 1 during rapid typing.
* Add typing-latency guardrail comments and CLAUDE.md pitfalls
Strategic comments on hitTest, TabItemView, and forceRefresh to prevent
future regressions. Adds typing-latency-sensitive paths to CLAUDE.md
pitfalls section so agents know the constraints before editing.
* Add workspace palette actions and fix release autosave typing guard
Add Move Up/Down/Top, Close Other/Above/Below, Mark Read/Unread to
Cmd+Shift+P command palette and a Workspace submenu in the menu bar.
Fix recordTypingActivity() being gated behind #if DEBUG, which prevented
release builds from honoring the typing quiet period in autosave.
* 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 regression test for terminal notification click dismissal
* Dismiss terminal notifications on direct clicks
* Add regression for focused terminal notification ring
* Keep focused terminal notifications unread until click
* Verify direct notification dismiss triggers flash
* Use focus-flash path for direct notification dismiss
* Align notification dismiss flash with ring geometry
* Add sidebar help menu
* Fix help menu test wiring
* Fix help menu accessibility
* Use native popup for help menu
* Use icon button for sidebar help
* Add feedback composer and feedback API
* Allow preview builds without feedback env
* Tighten feedback upload limits
* Adjust sidebar footer padding
* Tighten sidebar footer spacing
* Add link affordances to help menu
* Polish sidebar feedback composer
* Move feedback icon to trailing edge
* Normalize help menu trailing icon sizes
* Enlarge help menu trailing icons
* Reduce help menu link icon size
* Shrink help menu link arrow
* Reduce help menu link arrow again
* Fix feedback message editor focus
* Add send feedback keyboard shortcut
* Polish feedback launch and delivery