Commit graph

73 commits

Author SHA1 Message Date
Lawrence Chen
6eeca9c5da Merge remote-tracking branch 'origin/main' into pr-317-session-persistence
# Conflicts:
#	Sources/AppDelegate.swift
#	Sources/cmuxApp.swift
2026-02-23 14:58:16 -08:00
Lawrence Chen
2426590e91
Fix terminal focus when window loses key (#359)
* Fix terminal blur when window loses key

* Fix shortcut routing across multiple windows

* Fix shortcut window detection when identifiers change
2026-02-23 05:50:10 -08:00
Lawrence Chen
5d63c5f035
Add command palette (Cmd+Shift+P) (#358)
Implements a VS Code-style command palette with fuzzy search,
workspace/surface switching, rename mode, and keyboard navigation.

Closes https://github.com/manaflow-ai/cmux/issues/133
2026-02-23 03:26:36 -08:00
Lawrence Chen
cd570dbab2 Unify runtime theme reload path and prioritize surface background updates 2026-02-23 01:03:16 -08:00
Lawrence Chen
6f44f17f33 Fix follow-up PR331 settings and split focus regressions 2026-02-22 19:55:06 -08:00
Lawrence Chen
0046b674aa Split open-wrapper interception into its own setting 2026-02-22 18:26:07 -08:00
Lawrence Chen
923c62820f
Move workspace indicator setting into workspace colors (#329) 2026-02-22 17:45:11 -08:00
Lawrence Chen
d496a07a84
Hide new-tab toggles and align dark-mode button styling (#322)
* Hide new-tab browser toggles and align dark-mode button style

* Switch forced dark mode from dimming overlay to dark theme

* Add tri-state browser theme mode for embedded web view

* Hide browser theme menu chevron in toolbar

* Use outline icons for browser theme toggle

* Align browser theme icon tint with DevTools button

* Force monochrome rendering for browser toolbar icons

* Reduce browser theme icon weight for visual parity

* Tune browser theme icon stroke for perceptual color match

* Force flat SF Symbol color rendering for toolbar icons

* Use button popover for browser theme selector
2026-02-22 17:41:10 -08:00
Lawrence Chen
0105b6256a
Add workspace tab color schemes and debug scheme toggle (#324)
* Add tab color feature to sidebar workspaces

Lets users assign a custom background color to any sidebar workspace tab
via a right-click "Tab Color" submenu. The primary motivation is working
across multiple projects simultaneously — coloring tabs by project makes
it instant to visually locate the right workspace without reading the title.

- Workspace: adds `customColor: String?` (@Published hex string) and
  `setCustomColor()` setter
- TabManager: adds `setTabColor(tabId:color:)` convenience method
- ContentView: 16-color dark palette (all luminance < 0.30, white text
  always readable), `Color(hex:)` extension, `coloredCircleImage(hex:)`
  helper to render bitmapped NSImage circles (needed because macOS menus
  strip SwiftUI foregroundColor from SF Symbols), updated `backgroundColor`
  to use custom color at full/70%/35% opacity for active/inactive/
  multi-selected states, "Tab Color" submenu in context menu with
  "Clear Color" option, and a 1.5pt `Color.primary` border overlay on
  the active tab for clear selection indication when custom colors are set

* Add workspace tab color schemes with settings and debug toggles

* Remove Kelly scheme and keep only original tab color palette

* Preserve neutral grayscale when brightening tab colors

* Harden UpdatePill UI test polling timeouts

---------

Co-authored-by: Andreas Fruth <andreas.fruth@gmail.com>
2026-02-22 17:30:30 -08:00
Lawrence Chen
07796232d7 Sync customizable shortcuts across menus and tooltips 2026-02-22 16:24:43 -08:00
Lawrence Chen
927b0eb2d1 Implement session persistence pass 1 with multi-window restore 2026-02-22 15:39:59 -08:00
Brian Le
1824d1a8f1
feat(shortcuts): add rename-workspace keybind 2026-02-22 18:38:34 -05:00
Lawrence Chen
18550e5d1f Add expanded socket access modes with password auth
Implements https://github.com/manaflow-ai/cmux/issues/296 with new modes: off, cmuxOnly, automation, password, and allowAll.

Adds keychain-backed password storage, connection-level auth gates (v1 auth + v2 auth.login), settings UX with warning confirmation, CLI --password support, and regression tests.
2026-02-22 00:55:14 -08:00
Lawrence Chen
4c733d4e8e
Add Cmd+Q quit warning with suppression toggle (#295) 2026-02-21 21:53:39 -08:00
Austin Wang
fb2ae855db
Light mode (#258) 2026-02-21 15:39:25 -08:00
Lawrence Chen
ff11ba0309
Enable Claude Code integration by default (#247) 2026-02-21 04:31:00 -08:00
Lawrence Chen
a2c39802d1 Merge origin/main into feat-sidebar-branch-refresh-on-close 2026-02-20 23:36:11 -08:00
Lawrence Chen
12374c4a76
Add Cmd+Shift+T reopen for closed browser panels (#253)
Implements browser-only recently-closed restore stack with capped LIFO behavior and split-placement fallback.

Issue: https://github.com/manaflow-ai/cmux/issues/244
2026-02-20 23:06:49 -08:00
Lawrence Chen
5ca1616bd2 Add vertical sidebar branch layout setting 2026-02-20 22:26:10 -08:00
Lawrence Chen
3603db7547 Gate socket path override by update channel 2026-02-20 22:13:57 -08:00
Lawrence Chen
01313b6c9a Expand default HTTP host allowlist for local dev 2026-02-20 19:55:59 -08:00
Lawrence Chen
c6675c1a88 Clarify optional 0.0.0.0 allowlist usage 2026-02-20 19:49:02 -08:00
Lawrence Chen
3a24c20764 Merge remote-tracking branch 'origin/main' into pr-203-browser-whitelist 2026-02-20 19:46:39 -08:00
Lawrence Chen
a210d77f7f Clarify embedded browser allowlist wording and docs 2026-02-20 19:45:57 -08:00
Lawrence Chen
745c89fba9
Merge pull request #212 from manaflow-ai/issue-171-homebrew-claude-socket-errors
Default Claude Code integration to off
2026-02-20 19:32:30 -08:00
Lawrence Chen
64f6e34e7b Merge origin/main into pr-203-browser-whitelist 2026-02-20 19:10:59 -08:00
Lawrence Chen
a7363a5702 Merge remote-tracking branch 'origin/main' into fix/browser-devtools-shortcuts-pr
# Conflicts:
#	cmuxTests/CmuxWebViewKeyEquivalentTests.swift
2026-02-20 16:41:08 -08:00
Austin Wang
1f3f366294
Fix #205: Add setting to disable workspace auto-reorder on notification (#215)
* chore(claude-opus-4-6): From HN feedback: https://news.ycombinator.com/item?id=47...

* Centralize workspace auto-reorder into addNotification

Move moveTabToTop into TerminalNotificationStore.addNotification so all
notification paths (Ghostty actions, v2 API, control socket) respect the
reorder-on-notification setting, not just the two Ghostty action sites.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 15:55:31 -08:00
Lawrence Chen
438b7a6a41 Merge remote-tracking branch 'origin/main' into fix/browser-devtools-shortcuts-pr
# Conflicts:
#	Sources/Panels/BrowserPanel.swift
#	Sources/cmuxApp.swift
#	cmuxTests/CmuxWebViewKeyEquivalentTests.swift
#	vendor/bonsplit
2026-02-20 15:48:27 -08:00
Lawrence Chen
c9cafc0806 Merge origin/main into issue-180-http-nonsecure-hosts 2026-02-20 15:27:59 -08:00
Lawrence Chen
834e156556 Make HTTP allowlist helper and save row responsive 2026-02-20 15:20:44 -08:00
Lawrence Chen
df9ba6dcd9
Fix #155: remap-aware bonsplit tooltips + browser split shortcuts (#200)
* Issue #155: remap bonsplit tooltips and add browser split shortcuts

* Fix split button mousedown feedback regression

* Match split button sizing with main
2026-02-20 15:17:00 -08:00
Lawrence Chen
eb6caa5ce5 Default Claude Code integration to off 2026-02-20 15:10:48 -08:00
Lawrence Chen
d1bcb17b0d Add explicit save for HTTP host allowlist setting 2026-02-20 15:04:58 -08:00
Lawrence Chen
573cec4a75
Fix inconsistent Tab/Workspace terminology in settings and menus (#187)
Unify user-facing labels to consistently use "Workspace" instead of
mixing "Tab" and "Workspace":

- Settings: "New Tab" → "New Workspace" (keyboard shortcuts section)
- Menu: "Tab 1"–"Tab 9" → "Workspace 1"–"Workspace 9" (Cmd+1–9)
- Sidebar context menu: "Close Tabs" → "Close Workspaces",
  "Close Tabs Below/Above" → "Close Workspaces Below/Above"

Fixes https://github.com/manaflow-ai/cmux/issues/182

Co-authored-by: austinpower1258 <austinwang115@gmail.com>
2026-02-20 14:58:58 -08:00
Lawrence Chen
821e3ab4c3 Guard insecure HTTP in browser with allowlist and proceed flow 2026-02-20 14:55:26 -08:00
Carl Mercier
5e74161324
Add wildcard hostname allowlist for built-in browser routing (#195)
Adds a configurable host allowlist in Settings > Browser that controls
which terminal links open in the cmux embedded browser vs the system
default browser. Supports exact match and wildcard prefix patterns
(e.g. localhost, 127.0.0.1, *.localtest.me). Empty list preserves
existing behavior of opening all web links in cmux.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 16:24:50 -06:00
Lawrence Chen
cae40d1a4c
Sidebar ports on own line, wider sidebar, CMUX_PORT env vars (#160)
* Sidebar ports on own line, wider sidebar, CMUX_PORT env vars

- Move listening ports to dedicated sidebar row (removed from branch/directory line)
- Allow sidebar to resize up to 2/3 of screen width (was capped at 360px)
- Add CMUX_PORT, CMUX_PORT_END, CMUX_PORT_RANGE env vars per workspace
- Each workspace gets a dedicated port range (default: base 9100, range 10)
- Add settings UI for port base and range size
- Add portOrdinal to Workspace, monotonic counter in TabManager

Closes #129

* Make port ordinal counter static to avoid overlap across windows

Each window creates its own TabManager, so a per-instance counter
would reset and reuse port ranges. Making it static ensures unique
ranges across all windows.

* Fix portOrdinal race: pass through Workspace init instead of setting after

The first TerminalPanel is created inside Workspace.init, so setting
portOrdinal after init returns meant the initial terminal always got
ordinal 0. Pass portOrdinal as an init parameter and set it before
the TerminalPanel is created.

* Fix P2/P3: snapshot port settings at surface creation, use window screen for sidebar cap

P2: Port base/range are now snapshotted on TerminalSurface when the
panel is created, so changing settings mid-session won't cause
inconsistent CMUX_PORT values across terminals in the same workspace.

P3: Sidebar max width now uses NSApp.keyWindow?.screen instead of
NSScreen.main, so multi-monitor setups get the correct 2/3 cap for
the display the window is actually on.

* Fix P1: snapshot port base/range once per app session, not per panel

Port base and range size are now static properties on TerminalSurface,
initialized once from UserDefaults at first access. This prevents
overlapping port ranges across workspaces when settings are changed
mid-session (e.g., workspace 1 with range=10 at 9110-9119, then
range changed to 5, workspace 2 would overlap at 9110).
2026-02-20 14:12:14 -08:00
Lawrence Chen
5560492d27
Add preference to disable in-app browser for terminal links (#174)
* Add preference for terminal link browser target

Fixes https://github.com/manaflow-ai/cmux/issues/172

* Route non-web terminal links to external opener

Only route http/https terminal links to cmux's embedded browser.
Absolute paths, file:// URLs, and non-web schemes now open via NSWorkspace.

Refs https://github.com/manaflow-ai/cmux/issues/172
2026-02-20 13:58:39 -08:00
Lawrence Chen
7b2675cd1e
Fix theme initialization to respect configured/system appearance (#161)
* Respect configured appearance before Ghostty initialization

* Apply Ghostty theme colors to cmux titlebar and tab chrome

* Fix builtin theme resolution and tab strip icon contrast

* Alias builtin Solarized names to current Ghostty themes

* Sync tab chrome with active Ghostty theme

* Fix system appearance theme switching for surfaces

* Refresh titlebar on background theme updates

* Refresh split overlay config on appearance change

* Update bonsplit for chrome color review fixes
2026-02-20 04:51:01 -08:00
Lawrence Chen
707be44aaf
Separate cmux NIGHTLY as standalone app with its own bundle ID (#164)
The nightly build is now a distinct app called "cmux NIGHTLY" with
bundle ID com.cmuxterm.app.nightly, allowing side-by-side installation
with the stable release. The nightly appcast URL is baked into the
app's Info.plist by CI, so no in-app channel switching is needed.

- Nightly workflow: rename app to "cmux NIGHTLY", set bundle ID to
  com.cmuxterm.app.nightly, hardcode nightly Sparkle feed URL, publish
  DMG as cmux-nightly-macos.dmg
- Remove "Receive Nightly Builds" toggle from settings
- Remove UpdateChannelSettings enum and simplify feed URL resolution
  to just use SUFeedURL from Info.plist
- Remove UpdateChannelSettingsTests (no longer applicable)
2026-02-20 03:54:07 -08:00
Lawrence Chen
743cfcdc6d Fix browser devtools persistence and Safari shortcut wiring 2026-02-19 20:21:01 -08:00
Lawrence Chen
51a67e31fd
Socket access control: process ancestry check (#58)
* Socket access control: process ancestry check + file permissions

Redesign socket control modes from (off, notifications, full) to
(off, cmuxOnly, allowAll):

- cmuxOnly (default): uses LOCAL_PEERPID + sysctl process tree walk to
  verify the connecting process is a descendant of cmux. External
  processes (SSH, other terminals) are rejected.
- allowAll: hidden mode accessible only via CMUX_SOCKET_MODE=allowAll
  env var, skips ancestry check. Legacy "full"/"notifications" env
  values map here for backward compat.
- off: disables socket entirely.

Security hardening:
- Server: chmod 0600 on socket after bind (owner-only access)
- CLI: stat() ownership check before connect (reject fake sockets)

Removes per-command allow-list (isCommandAllowed) — once a process
passes the ancestry check, all commands are available.

Includes migration for persisted UserDefaults values and env var
aliases (cmux_only, cmux-only, allow_all, allow-all).

* Add /sync-branch skill for submodule + main sync
2026-02-18 01:09:24 -08:00
Lawrence Chen
f0e4ccdc1d
Show sidebar/notification/new-tab controls in fullscreen without hovering titlebar (#55)
In fullscreen mode, the NSTitlebarAccessoryViewController buttons are hidden
with the system titlebar. This adds SwiftUI-based fullscreen controls that
appear in the sidebar area (when visible) or inline in the custom titlebar
(when sidebar is hidden), reusing the existing TitlebarControlsView component.

- Track fullscreen state via window notifications and toggle controls visibility
- Hide original titlebar accessory (isHidden + alphaValue=0) in fullscreen
- Route notification popover anchoring through fullscreen controls view model
  so both button clicks and keyboard shortcuts (Cmd+Shift+I) position correctly
- Add debug titlebar spacing slider for fine-tuning leading inset
2026-02-17 20:24:01 -08:00
Lawrence Chen
c0f7a07a7b Fix sidebar tabs getting extra left padding when update pill is visible
Move GeometryReader from wrapping the entire VStack to wrapping only the
ScrollView so proxy.size.height reflects available height (minus pill),
preventing unnecessary scrollability that triggered macOS horizontal insets.

Also clamp update pill text width with maxWidth instead of fixed width so
it truncates gracefully at narrow sidebar widths and grows when wider, add
horizontal padding, left-align truncated text, and add debug menu item for
testing with long nightly version strings.
2026-02-16 03:20:51 -08:00
Lawrence Chen
ac4b49d7a4 move update pill to sidebar only, add Install Update menu item 2026-02-15 21:17:33 -08:00
Lawrence Chen
777d6b048e Replace CLAUDE_CONFIG_DIR with claude wrapper + richer notifications
Instead of creating a merged config directory and injecting
CLAUDE_CONFIG_DIR on every terminal spawn, place a thin wrapper
script at Resources/bin/claude that intercepts claude invocations
to inject --session-id and --settings flags. This eliminates
blocking I/O on terminal creation and removes config management
complexity.

- Add Resources/bin/claude wrapper script with hook injection
- Add shell integration PATH fix (re-prepend after .zshrc/.bashrc)
- Add transcript reading for richer stop notifications
- Add set_status/clear_status to notifications socket allowlist
- Add Settings toggle to disable Claude Code integration
- Update docs to reflect automatic integration approach
- Unset CLAUDECODE env var to avoid nested session detection
2026-02-15 18:33:36 -08:00
Lawrence Chen
2c205893fb Change reload configuration shortcut to Cmd+Shift+, 2026-02-15 17:04:45 -08:00
Lawrence Chen
5a1cc7bc8d bundle third-party licenses in app and add Licenses button to About
Add THIRD_PARTY_LICENSES.md as a bundled resource so it ships inside
the .app bundle. Add a "Licenses" button to the About panel that opens
a scrollable window displaying the file contents.
2026-02-14 21:15:35 -08:00
Lawrence Chen
f47d964a7e Fix settings control alignment and divider consistency 2026-02-14 02:33:18 -08:00