Commit graph

309 commits

Author SHA1 Message Date
Lawrence Chen
6748c202f2
Fix sidebar drag-and-drop broken by FileDropOverlayView (#76)
* Fix sidebar drag-and-drop broken by FileDropOverlayView

The FileDropOverlayView (added in 9fd3cc2) sits on the window's theme
frame above the content view. Its hitTest returned self for all events,
causing AppKit to route drag sessions to the overlay instead of the
content view where SwiftUI lives. AppKit walks UP the superview chain
from the hit-tested view, never checking siblings — so SwiftUI's
.onDrop handlers for sidebar tab reordering were never reached.

Three changes fix this:

1. Smart hitTest: check NSPasteboard(name: .drag) for .fileURL and only
   return self during Finder file drags. Return nil otherwise so mouse
   events and internal drags pass through to the content view.

2. Custom UTType for sidebar drags: replace the fragile UTType.plainText
   hack with a proper com.cmux.sidebar-tab-reorder type registered in
   Info.plist. Uses visibility: .ownProcess since it's internal-only.

3. Narrow overlay registration: only register for .fileURL instead of
   .fileURL + .URL + .string. The broad .string type collided with
   text-based drag payloads.

* Add custom UTType Info.plist pitfall to CLAUDE.md
2026-02-18 17:20:22 -08:00
Lawrence Chen
cf0f08f0e2
Bump version to 0.46.0 (#75) 2026-02-18 16:49:22 -08:00
Austin Wang
5647aacacd
Revert "ok (#68)" (#74)
This reverts commit 5a10ec8d17.
2026-02-18 16:42:41 -08:00
Lawrence Chen
9105ecbf03 Bump version to 0.45.0 2026-02-18 16:27:15 -08:00
Lawrence Chen
5e4f07d8e9 Update homebrew-cmux submodule to latest 2026-02-18 16:13:40 -08:00
Austin Wang
adac50c5b9
Bump version to 0.44.0 (#70)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:41:20 -08:00
Austin Wang
5a10ec8d17
ok (#68) 2026-02-18 14:38:07 -08:00
Lawrence Chen
cb86322e98
Remove docs-site, add PostHog analytics to web (#66)
- Delete docs-site/ (superseded by web/app/docs)
- Add posthog-js with Vercel reverse proxy at /cdata to bypass adblockers
- Track pageviews (SPA-aware), download clicks (hero/navbar/mobile_drawer),
  and GitHub link clicks (hero/navbar/mobile_drawer/footer)
2026-02-18 04:00:04 -08:00
Lawrence Chen
fdd8029c00 Bump version to 0.43.0 2026-02-18 02:19:30 -08:00
Lawrence Chen
0ec5a3af1b Restore lost bonsplit + button commits via merge
Three bonsplit commits (429af82, 2ff740d, b1948ab) adding the tab bar
+ button were lost when ad159da moved the submodule pointer to a
branch that forked before those commits. Merge origin/term-browser-icons
back into bonsplit main to restore them.
2026-02-18 02:17:46 -08:00
Lawrence Chen
4c42bd8078 Fix migrateMode dropping allowAll to default cmuxOnly
migrateMode() had no case for "allowAll" rawValue, so it fell
through to the default branch which returned .cmuxOnly. This
silently downgraded any persisted allowAll setting.
2026-02-18 02:12:19 -08:00
Lawrence Chen
21bbe80410
Add features table with images to README (#64)
Replace the hero screenshot and add a visual features table showing
notification rings, notification panel, in-app browser, and vertical
tabs & splits with per-feature screenshots.
2026-02-18 01:31:21 -08:00
Lawrence Chen
f2f4fb8a22
Add features table with images to README (#63)
* Add features table with images to README

Replace the hero screenshot and add a visual features table showing
notification rings, notification panel, in-app browser, and vertical
tabs & splits with per-feature screenshots.

* Rename feature heading to "Vertical + horizontal tabs"

* Remove parenthetical from notification rings description
2026-02-18 01:24:54 -08:00
Lawrence Chen
ad159daa80 Update bonsplit: onFileDrop API, PaneDragContainerView, dirty indicator fix 2026-02-18 01:21:17 -08:00
Lawrence Chen
fb93a9f5ef Bump version to 0.42.0 2026-02-18 01:11:18 -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
60978d4d8b Update secrets path from cmux.env to cmuxterm.env 2026-02-18 01:03:03 -08:00
Lawrence Chen
d62153bdc6 Update submodules: ghostty upstream sync, homebrew cask bumps 2026-02-18 01:01:40 -08:00
Lawrence Chen
4d6a3f81bf Bump version to 0.41.0 2026-02-17 22:23:12 -08:00
Lawrence Chen
e4d31819d2 Merge remote-tracking branch 'origin/main' into fix-file-drop-targeting 2026-02-17 22:16:15 -08:00
Lawrence Chen
3b4c6f124b Add submodule safety rule to CLAUDE.md
Instructs AI agents to always push submodule commits to remote main
before updating the parent pointer, preventing orphaned commits.
2026-02-17 22:14:32 -08:00
Lawrence Chen
893e1a5d4b Fix ghostty submodule pointer to existing commit
Reverts ghostty to 5a987a14 (the state before 50fce94 pointed it at
orphaned commit eac00f3 which no longer exists on the remote).
2026-02-17 22:14:26 -08:00
Lawrence Chen
d8b39aeaa4 Merge remote-tracking branch 'origin/main' into fix-file-drop-targeting 2026-02-17 22:12:26 -08:00
Lawrence Chen
8104c1675b Use paste path for file drops and don't steal focus
Switch from ghostty_surface_key (key event path) to ghostty_surface_text
(paste path) for file drops, matching upstream Ghostty. This triggers
bracketed paste mode and eliminates the lag on drop.

Remove makeFirstResponder calls from insertDroppedPasteboard and
handleDroppedURLs so dropping a file doesn't steal keyboard focus from
the currently focused terminal.
2026-02-17 22:11:47 -08:00
Lawrence Chen
e322403f9b Always show close button on active tab
Re-applies lost change from a8834d8 (commit was orphaned by a
force-push on the bonsplit submodule).
2026-02-17 22:04:16 -08:00
Lawrence Chen
c7d4a52c8e Update bonsplit submodule to latest after force-push 2026-02-17 22:04:16 -08:00
Austin Wang
514df0bd97
Update Discord invite link (#59)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 22:03:41 -08:00
Lawrence Chen
5f314cd6a7 Bump version to 0.40.0 2026-02-17 22:00:47 -08:00
Lawrence Chen
9af7df0dac Fix socket accept loop not restarted after Sparkle update relaunch
After a Sparkle auto-update relaunches cmux, the control socket stops
accepting connections because start() early-returns when isRunning is
true, without checking if the accept loop thread is actually alive.

- Add acceptLoopAlive flag to track accept loop thread liveness
- Fix start() early-return to also check acceptLoopAlive, so a dead
  thread triggers full socket re-creation
- Break acceptLoop() after 50 consecutive accept() failures with 10ms
  backoff instead of tight-spinning forever
- Clean up socket in applicationWillTerminate and
  updaterWillRelaunchApplication for clean teardown before relaunch
2026-02-17 22:00:47 -08:00
Lawrence Chen
9fd3cc2a6c Add file drop support from Finder into terminal splits
Nested NSHostingController layers (from bonsplit's SinglePaneWrapper)
prevent AppKit's NSDraggingDestination routing from reaching terminal
views. Install a transparent FileDropOverlayView on the window's theme
frame that intercepts file drags and forwards drops to the GhosttyNSView
under the cursor. Mouse events pass through via a hide-send-unhide
pattern.

Fix y-axis inversion in split targeting: hitTest expects coordinates in
the receiver's superview's coordinate system, not the receiver's own.
Converting to contentView's coords flipped y because NSHostingView is
flipped, causing top/bottom split drops to land in the wrong terminal.

Also adds bonsplit onFileDrop API, PaneDragContainerView, and
drop_hit_test socket command for testing coordinate-to-terminal mapping.
2026-02-17 21:55:31 -08:00
Lawrence Chen
50fce9476c Update submodules: ghostty merge fork + upstream, homebrew cask bumps 2026-02-17 21:51:39 -08:00
Lawrence Chen
bc7cdb2c10 Add /release-local skill and direnv setup
Add a local release skill that builds, signs, notarizes, and uploads
releases without GitHub Actions. Set up direnv to load Apple signing
secrets from ~/.secrets/cmuxterm.env.
2026-02-17 21:33:11 -08:00
Lawrence Chen
fa6fda148c reload: quiet xcodebuild output, save full log to /tmp/cmux-xcodebuild-{tag}.log
Amp-Thread-ID: https://ampcode.com/threads/T-019c6f36-008c-7269-854e-3ea7c6de6058
Co-authored-by: Amp <amp@ampcode.com>
2026-02-17 21:33:11 -08:00
Lawrence Chen
a91e92c7cf Always show close button on active tab
Amp-Thread-ID: https://ampcode.com/threads/T-019c6f32-10c2-70ce-b446-5c25c2ae8cbf
Co-authored-by: Amp <amp@ampcode.com>
2026-02-17 21:33:11 -08:00
Lawrence Chen
bf3d22fa8a
Fix flaky WebKit escape focus tests on slow environments (#57)
Two fixes for escape-focus flakiness on VMs:

1. App-side: recordGotoSplitUITestWebViewFocus now retries with increasing
   delays (0.05, 0.1, 0.25, 0.5s) for the exit-address-bar case, giving
   WebKit more time to accept first responder.

2. Test-side: both testEscapeLeavesOmnibarAndFocusesWebView and
   refocusWebView helper send a second Escape if the first only clears
   suggestions/editing state (Chrome-like two-stage escape behavior).
2026-02-17 21:12:28 -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
4220c3808f
Fix sidebar metadata commands failing in multi-window setups (#54)
resolveTabForReport only searched the active window's tab manager, so
report_ports, report_git_branch, report_pwd, set_status etc. returned
"Tab not found" when the shell's --tab UUID belonged to a different
window. Fall back to AppDelegate.tabManagerFor(tabId:) to search all
window contexts.
2026-02-17 19:33:20 -08:00
Lawrence Chen
be74e73b20 Update TODO with bugs, refactoring items, and UI improvements 2026-02-17 18:45:38 -08:00
Lawrence Chen
55437871d7 Bump version to 0.39.0 2026-02-17 18:43:23 -08:00
Lawrence Chen
6d6efb6b60 Reversion all 1.x.x to 0.x.x for pre-launch versioning 2026-02-17 18:31:05 -08:00
Lawrence Chen
7f8b639ae3
Open cmd+clicked terminal links in cmux browser panel (#53)
* Open cmd+clicked terminal links in cmux browser panel instead of system browser

Handle GHOSTTY_ACTION_OPEN_URL in the Ghostty action callback to intercept
link opens. Uses preferredBrowserTargetPane to reuse an existing right-side
pane, falling back to a new horizontal split.

* Use tab-specific manager for OPEN_URL action

Use tabManagerFor(tabId:) instead of the active-window tabManager so the
lookup succeeds when the surface belongs to a different window context.
2026-02-17 18:24:36 -08:00
Lawrence Chen
14ce05db5f Add release artifacts to gitignore 2026-02-17 17:32:00 -08:00
Lawrence Chen
ee5902de0e Bump version to 1.38.1 2026-02-17 17:14:36 -08:00
austinpower1258
0df1988126 Release v1.38.0 2026-02-17 16:36:15 -08:00
Austin Wang
0cca513eac
Browser searchbar bugs (#51)
* Add "+" menu button to horizontal tab bar for new terminal/browser tabs

Adds a "+" button to the tab bar (next to split buttons) that shows a
dropdown menu with "New Terminal ⌘T" and "New Browser ⌘⇧L" options.

- Uses native NSButton + NSMenu so the icon matches the split buttons
- Menu appears below the button
- Routes tab creation through new didRequestNewTab delegate method

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

* works

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:26:42 -08:00
Austin Wang
23db0a3fa2
maximize-sidebar (#50) 2026-02-17 16:11:00 -08:00
Lawrence Chen
4bf968fd68
Bump version to 1.37.0 (#49) 2026-02-17 15:17:18 -08:00
Austin Wang
addb99ed50
Add "+" menu button to horizontal tab bar for new terminal/browser tabs (#48)
Adds a "+" button to the tab bar (next to split buttons) that shows a
dropdown menu with "New Terminal ⌘T" and "New Browser ⌘⇧L" options.

- Uses native NSButton + NSMenu so the icon matches the split buttons
- Menu appears below the button
- Routes tab creation through new didRequestNewTab delegate method

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 14:59:24 -08:00
Lawrence Chen
c2fdd48290
Release v1.36.0 (#47)
* Fix multi-workspace drag/drop, WebView click focus, and add regression tests

- Wire bonsplit isInteractive to workspace active state so inactive
  workspace NSViews are hidden from AppKit event routing
- Add CmuxWebView.mouseDown notification for browser panel focus
  tracking (AppKit delivers clicks to WKWebView, not SwiftUI overlays)
- Add multi-workspace focus regression test covering isHidden fix,
  rapid workspace switching, and browser panel focus routing

* Bump version to 1.36.0
2026-02-17 04:04:29 -08:00
Lawrence Chen
2678606a20
Fix omnibar tracking timeout using background queue (#46)
The 3-second safety net that posts a synthetic mouseUp to break out of
NSTextView's stuck tracking loop was dispatched on the main queue. Since
super.mouseDown blocks the main thread in the tracking loop, the timeout
could never fire. Use a background queue instead (NSApp.postEvent is
thread-safe). Use DispatchWorkItem.isCancelled for atomic cancellation.
2026-02-17 03:35:49 -08:00