- Remove tests for shouldLoadReleaseAppSupportGhosttyConfig (function was
deleted but tests survived, breaking CI on all branches)
- Fix missed localization on optional-chain notification fallback path
- Validate explicit-but-empty --pid as invalid input
* feat: support window.open() popup windows (#742)
Return a live WKWebView from createWebViewWith using WebKit's supplied
configuration, preserving popup browsing-context semantics (window.opener,
postMessage). This fixes OAuth/OIDC flows and any site relying on standard
popup patterns.
- Add BrowserPopupWindowController: NSPanel-based popup with self-retention,
KVO title/URL, read-only URL label, nested popup depth limit (3),
insecure-HTTP prompt parity, auth challenge parity, download delegate
- Classifier: scripted requests (window.open) create popups; user-initiated
actions (Cmd+click, middle-click, context menu) open tabs
- Retarget context menu "Open Link in New Tab" to bypass createWebViewWith,
wired in both main browser and popup web views
- Cmd+W fast path in AppDelegate for popup windows
- Opener panel owns popup lifecycle; close() tears down all child popups
* fix: Cmd+W closes only the popup, not the parent tab
Add BrowserPopupPanel (NSPanel subclass) that intercepts Cmd+W in
performKeyEquivalent before the swizzled cmux_performKeyEquivalent
can dispatch it to the main menu's "Close Tab" action.
Also refine the popup classifier to reuse browserNavigationShouldOpenInNewTab
for Cmd+click/middle-click detection, add download delegate wiring, and
wire onContextMenuOpenLinkInNewTab for popup web views.
* fix: tighten popup routing and window behavior
* test: cover oversized popup frame clamping
* test: cover plain link-activated popup routing
---------
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
The hooks configuration example used a format that was valid when
originally written but broke across two Claude Code releases:
- v1.0.41: Added `hook_event_name` to hook input, replacing the
previous field name. The hook script was still reading `.event`,
causing the case statement to always fall through to unknown.
- v2.1.63: Added HTTP hooks with `{ "type": "command", "command": "..." }`
object format. Bare string paths in the hooks array are no longer
valid now that hook type disambiguation is required.
Changes:
- Stop hooks now use the full matcher/hooks object structure
- PostToolUse inner hooks use typed command objects
- Hook script reads `hook_event_name` instead of `event`
Ref: https://docs.anthropic.com/en/docs/claude-code/hooks
Add Startpage (startpage.com) to the BrowserSearchEngine enum alongside
Google, DuckDuckGo, Bing, and Kagi. Startpage provides an OpenSearch-
compatible suggestions endpoint at /osuggestions, so autosuggestions
work out of the box using the existing OSJSON parser.
Co-authored-by: Zlatko Cajic <git@zlat.co>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
When socket connection mode is not 'off', the shell integration runs
_cmux_stop_pr_poll_loop in the preexec hook before every command.
This function had a blocking 'sleep 0.1' call that caused noticeable
lag on every command execution.
The fix replaces the TERM+sleep+KILL pattern with direct SIGKILL.
The PR poll loop is a lightweight background process that only runs
'gh pr view' periodically - it's safe to kill abruptly without
waiting for graceful termination.
Fixes#1436
Co-authored-by: BillionClaw <267901332+BillionClaw@users.noreply.github.com>
keyCodeForShortcutKey() did not map arrow glyphs (←→↑↓) to their
macOS key codes (123-126). The shortcut recorder correctly stored
arrow keys as glyphs via storedKey(), but matchShortcut() could
not resolve them back to key codes for ANSI fallback matching.
This only affected non-directional shortcut actions (e.g. Next/Previous
Surface) since pane focus shortcuts use a separate matchDirectionalShortcut()
path that already handles arrow keys.
- Config: sidebar-background supports plain hex (#336699) or
light/dark syntax (light:#fbf3db,dark:#103c48)
- Config: sidebar-tint-opacity overrides tint opacity
- Settings UI: per-scheme color pickers, opacity slider (0-70%), reset
- SidebarBackdrop resolves light/dark hex based on @Environment colorScheme
- applySidebarAppearanceToUserDefaults guards on rawSidebarBackground presence
so UI picks survive appearance toggles when no config is set
- Stale light/dark UserDefaults keys cleared when config switches from
dual-mode to single or sidebar-background is removed
- applyPreset() and Reset Tint clear per-scheme overrides
- Debug snapshot (combinedPayload + copySidebarConfig) includes new keys
- ColorPicker labels use String(localized:) per localization policy
- Opacity slider capped at 0.7 to match debug view vibrancy constraint
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.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
The SwiftUI TextField lost arrow-key and backspace handlers when the
query prefix (">") was deleted, because the scope transition tore down
the .onKeyPress modifiers. Using an NSViewRepresentable with an AppKit
field editor keeps navigation commands (up/down/enter/escape) on the
native delegate, making them immune to SwiftUI scope changes.
Fixes#1409
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 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>