* Set cmux TestAction to Debug for UI tests
* Broaden XCTest detection for debug launch gate
* Fix AutomationSocketUITests launch hang in CI
* Stabilize CI Swift package resolution for test jobs
* Stabilize Xcode Cloud UI test focus and socket handling
* Add Xcode Cloud pre-xcodebuild submodule bootstrap
* Harden Xcode Cloud bonsplit bootstrap fallback
Sidebar body was calling sidebarOrderedPanelIds() multiple times per
render for branches, directories, and pull requests. Now computes it
once and passes through. Reduces redundant work during scroll frames.
Closes https://github.com/manaflow-ai/cmux/issues/655
- Notification/focus flash uses workspace customColor (fallback: accent)
- Selection bar/indicator uses workspace customColor when set
- Flash color propagated through Panel.triggerFlash(color:) API
- Browser panel flash overlay uses workspace color
- Regression tests for flash color resolution
Fixes https://github.com/manaflow-ai/cmux/issues/557
* Fix --help flag executing commands instead of showing help (#650)
The --help check fell through to command dispatch when subcommandUsage
returned nil for a command. Now --help always returns before dispatch,
printing a generic fallback when no specific help text exists.
Also adds missing subcommandUsage entries for: new-window, list-panes,
list-pane-surfaces, surface-health, trigger-flash, list-panels,
focus-panel, set-app-focus, ping, capabilities, identify, list-windows,
current-window, refresh-surfaces, current-workspace, list-notifications,
clear-notifications.
Closes#650
* Document all flags and options in CLI --help output
Every subcommand's help text now shows all accepted flags, options,
environment variable fallbacks, and positional arguments matching the
actual dispatch code. Also adds help entries for commands that were
returning the generic fallback (list-workspaces, list-panes,
list-pane-surfaces, surface-health, trigger-flash, list-panels,
focus-panel, set-app-focus, etc.)
* Show 'Unknown command' for invalid commands, add legacy alias help
Unknown commands now show "Unknown command 'X'. Run 'cmux help' to see
available commands." instead of the misleading "No detailed help
available." Also adds help entries for legacy browser aliases
(open-browser, navigate, etc.) pointing to 'cmux browser --help'.
* Audit all 89 CLI commands for complete help coverage
- Add missing `help` subcommandUsage entry
- Expand id|ref → id|ref|index for move-workspace-to-window,
close-workspace, select-workspace, rename-workspace
- Document CMUX_WORKSPACE_ID/CMUX_TAB_ID/CMUX_SURFACE_ID env var
defaults in tab-action, rename-workspace
- Expand browser help: get (--selector, --attr, --property),
find (--name, --exact, --index), network route (--abort, --body),
open/open-split/new env var defaults
- Remove duplicate rename-window help case (now handled by
rename-workspace combined case)
- Upgrade regression test to auto-extract dispatch+subcommandUsage
switches and flag any commands missing help entries
* Add "Open Folder…" command to open a workspace at a chosen directory
Adds a native folder picker (NSOpenPanel) accessible from:
- Command Palette (⌘⇧P → "Open Folder…")
- File menu with ⌘O shortcut
Selecting a folder opens a new workspace at that path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Rename openRepository → openFolder, add customizable shortcut
- Rename command ID from palette.openRepository to palette.openFolder
- Register openFolder in KeyboardShortcutSettings (default: Cmd+O)
- Wire menu bar shortcut through settings instead of hardcoding
- Add commandPaletteShortcutAction mapping for shortcut hint display
* Dismiss command palette before showing Open Folder panel
The NSOpenPanel.runModal() call blocked the main thread, keeping the
command palette visible behind the file picker. Wrapping in
DispatchQueue.main.async lets the palette dismiss first.
* Trigger GitHub PR refresh
---------
Co-authored-by: michalstrnadel <michal.strnadel@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* Set up full test suite in CI and Xcode Cloud
Add build-ghosttykit.yml workflow to pre-build and publish
GhosttyKit.xcframework as a GitHub release on manaflow-ai/ghostty,
keyed by submodule SHA. Add ci_scripts/ci_post_clone.sh for Xcode
Cloud to download the pre-built xcframework with retry logic. Create
cmux-ci scheme that runs both cmuxTests and cmuxUITests. Switch the
CI tests job from running a single UI test class to the full suite.
* Run unit tests + single UI test class on self-hosted runner
The self-hosted runner can't launch the full app for UI tests (no GUI
session), so run all unit tests via cmux-unit scheme and keep the
original UpdatePillUITests as a smoke test. Full UI test suite runs
on Xcode Cloud which has proper macOS GUI support.
* Handle expected test failures in unit tests step
xcodebuild returns exit code 65 even for expected failures
(XCTExpectFailure). Parse the summary line to only fail the CI job
when there are unexpected failures.
* Redesign changelog page with feature highlights and visual hierarchy
Major releases now show narrative summaries, feature highlight cards
(with image support for screenshots), colored section badges, and
contributor avatars. Minor releases stay compact. Adds changelog-media.ts
as a supplementary data layer alongside CHANGELOG.md.
* Use Next.js Image for optimized loading and GitHub avatar remotes
* Add screenshots for Open With and Tab Colors features
* Add workspace metadata screenshot
* Switch to single-column inline layout, add command palette screenshot
* Conductor-style titles, narrower body, narrative descriptions, reorder features
* Add pin workspace and tab context menu screenshots, remove subtitle
* Add View Changelog link to front page, add DevTools to 0.60.0
* Add CJK input screenshot to 0.60.0
* Read real PNG dimensions at build time, add proper sizes attribute
* Fix image overflow: wrap in overflow-hidden container, add max-w-full
* Fix CSS cascade: move docs-content styles into @layer base
Unlayered CSS beats @layer utilities in the cascade, so .docs-content
rules (margins, padding, list-style) were overriding Tailwind utilities
on ul, li, h2 elements in the changelog page. Moving them into
@layer base lets utilities win without needing !important hacks.
* Switch docs-content spacing from margin to padding
Margins were collapsing and conflicting with Tailwind layout utilities
in the changelog. Padding doesn't collapse and can't interfere with
external spacing set by parent containers.
* Fix changelog layout: use flex column + inline styles for all spacing
Block layout was collapsing when articles had media content (h2, feature
divs, section divs all rendered at the same position). Switching to
display:flex + flex-direction:column on articles and using inline styles
for all spacing guarantees proper vertical stacking regardless of
docs-content CSS interference.
* Remove border from changelog images
* Replace devtools screenshot with cmux inspecting cmux.dev
Registers palette.triggerFlash wired to triggerFocusFlash() (same as
Cmd+Shift+H). Shortcut hint reads from KeyboardShortcutSettings so it
stays in sync with custom bindings.
Closes https://github.com/manaflow-ai/cmux/issues/633
Adds CmuxCLIPathInstaller with symlink management at /usr/local/bin/cmux,
exposed via Cmd+Shift+P command palette (VS Code style). Install entry
shown when CLI is not in PATH, uninstall entry shown when it is.
Falls back to osascript admin privilege escalation when /usr/local/bin
is not user-writable. Uses attributesOfItem instead of fileExists to
correctly handle dangling symlinks from relocated app bundles.
Closes https://github.com/manaflow-ai/cmux/issues/618
Cmd+Shift+Enter toggles zoom on the focused pane, expanding it to fill
the workspace. Splitting or creating new tabs auto-unzooms. Zoom state
shown as icon in sidebar tab. Includes bonsplit zoom toggle support.
Closes https://github.com/manaflow-ai/cmux/issues/136
Add nil guard in forceRefresh() to prevent dereferencing freed surface
pointer. Split else-if chains in Workspace.swift so
requestBackgroundSurfaceStartIfNeeded() runs if surface is freed during
the refresh call. Add regression test exercising the crash path.
- Wrap eval scripts in async IIFE that detects and awaits thenables,
using callAsyncJavaScript when available (macOS 11+) (#603)
- Register console/error telemetry hooks as WKUserScript at document
start so they survive navigation and are active before page JS (#604)
- Return typed envelope {__cmux_t, __cmux_v} from eval to distinguish
undefined from no return value; CLI prints "undefined" (#605)
- Keep dialog hooks as lazy injection only (not document-start) to
avoid suppressing WKUIDelegate native dialogs
- Add regression tests for async wrapper and undefined CLI rendering
Add window-identity check to windowDragHandleShouldCaptureHit so stale
leftMouseDown events from other apps (Finder, Dock) during launch don't
trigger the SwiftUI hierarchy walk while initial layout is mutating.
Add NSLock to breadcrumb limiter for thread safety. Update existing
tests to pass eventWindow for window-attached drag handles.
All four switch statements (case list, commandPaletteTitle,
commandPaletteKeywords, applicationBundlePathCandidates) are now
in consistent alphabetical order.
* Add browser automation docs page (#594)
Comprehensive reference for all cmux browser subcommands: navigation,
waiting, DOM interaction, inspection, JS eval, state management,
tabs, dialogs, frames, and downloads. Includes common patterns section.
* Remove unnecessary callout from browser automation docs
* Add "The Zen of cmux" blog post
New blog post about cmux's philosophy: composable primitives over
opinionated solutions. Added to blog index and README.
* List all cmux primitives in blog post
Terminal, browser, notifications, workspaces, splits, tabs, and a CLI
to control all of it.
* Add Zen of cmux section to README
The app sometimes launched to a frozen blank state with an empty sidebar
and no terminal loaded. This was caused by restoreSessionSnapshot emitting
intermediate @Published states (empty tabs, nil selectedTabId) that left
SwiftUI's mountedWorkspaceIds empty.
Two fixes:
1. Make restoreSessionSnapshot atomic: build the new tab list locally
before assigning to @Published properties in a single batch, so
SwiftUI observers never see an intermediate empty state.
2. Add a startup recovery timer that detects and fixes broken state
(empty tabs, invalid selection, unmounted workspaces) 500ms after
the view appears, with Sentry breadcrumbs for diagnostics.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Adds a "Send anonymous telemetry" toggle in Settings that lets users
disable Sentry crash reporting and PostHog analytics. The setting is
frozen at launch so toggling mid-session shows a restart hint. The hint
correctly clears if the user toggles back to the launch-time value.
Hide browser subcommands that always return not_supported on WKWebView
(viewport, geolocation, offline, trace, network, screencast, input)
and the legacy browser alias notice from the help output. Command
handlers remain for backwards compatibility.
Closes https://github.com/manaflow-ai/cmux/issues/593
Adds `cmux tree` that prints the window > workspace > pane > surface
hierarchy with box-drawing characters. Includes server-side system.tree
RPC for single-round-trip performance.
Features:
- --all flag for all windows (default: current window only)
- --workspace flag to filter to a single workspace
- --json for structured JSON output
- Active path markers (◀ active) and caller identification (◀ here)
- Browser surfaces show their current URL
Closes https://github.com/manaflow-ai/cmux/issues/586
Add a cached lazy keychain fallback to SocketControlPasswordStore so
that authentication paths in TerminalController can transparently read
a legacy keychain password without blocking on every request. The
keychain is read at most once and the result is cached behind an
NSLock. File-based and environment passwords still take priority.
Closes https://github.com/manaflow-ai/cmux/issues/579