Remove -Dxcframework-target=native from CI and release workflows,
defaulting to universal (matching upstream ghostty). The native target
produces a macos-arm64 xcframework slice that causes Xcode to link the
final binary differently (~70KB more __text), resulting in menubar and
right-click lag on M1 Max. The arm64 static libraries are byte-for-byte
identical between native and universal builds - the difference is purely
in how Xcode resolves the xcframework slice.
* Fix browser panel opening new tabs on every link click
Navigate target=_blank and window.open() links in the current webview
instead of spawning new browser tabs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Preserve cmd+click new tab behavior in createWebViewWith
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The -Dxcframework-target flag controls platform slices (native=macOS
only, universal=macOS+iOS), not CPU microarchitecture. Removing it
caused CI to attempt iOS builds which fail due to missing Metal
iOS toolchain on the runner.
* Fix zsh git branch refresh race after cwd change
* Clarify intentional duplicate cwd check in git refresh path
* Add Metal Toolchain download step to CI and release workflows
Fixes build failure when compiling Metal shaders for iOS xcframework
targets — the self-hosted runner needs `xcodebuild -downloadComponent
MetalToolchain` installed before `xcrun metal` can run.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
The self-hosted runner (M4 Mac Mini) was building GhosttyKit with
-Dxcframework-target=native, producing M4-tuned binaries. This caused
menubar and right-click lag on M1 machines. Dropping the flag defaults
to universal, which works well across all Apple Silicon chips.
- New /release-nightly: end-to-end version bump + local build + release
- Fix /release-local: source secrets directly, use signing hash to avoid
keychain ambiguity, correct create-dmg --codesign flag, export
SPARKLE_PRIVATE_KEY for appcast generation
- Add `say` notification on completion/failure to all release skills
The hide-send-unhide pattern in forwardEvent() can recurse infinitely
when gesture recognizer routing re-delivers the event despite isHidden.
Add a re-entrancy guard to break the cycle.
Fixes EXC_BAD_ACCESS (stack overflow) crash in production.
The shim always injected --session-id with a fresh UUID, which broke
`claude --resume <id>` and `claude --continue` by conflicting with the
user's session flag. Now scans args and skips injection when the user
already specifies a session/resume flag.
Also passes through subcommands (mcp, config, api-key) without injecting
hooks or session flags since they don't support them.
* 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
- 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)
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.
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.
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.
* 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
* 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
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.