Commit graph

38 commits

Author SHA1 Message Date
Lawrence Chen
f617032ad5 Require launch tag for cmux DEV 2026-02-24 20:39:55 -08:00
Lawrence Chen
5ac633445f Fail partial release assets and short-circuit reruns 2026-02-21 15:27:24 -08:00
Lawrence Chen
cf1cd096b1 Make release asset guard idempotent 2026-02-21 15:19:10 -08:00
Lawrence Chen
a5b1039fbc release: block accidental overwrite of signed assets 2026-02-21 04:07:00 -08:00
Lawrence Chen
a5c7600458 Harden drag overlay routing and add terminal overlay regression probes 2026-02-20 19:58:58 -08:00
Lawrence Chen
b4bb51c509 Use SHA stamp to safely reuse local xcframework on cache miss
Instead of always rebuilding, write a .ghostty_sha stamp file
inside the xcframework after each build. On cache miss, only
seed from local if the stamp matches the current submodule SHA.
This avoids both unnecessary rebuilds and stale ABI mismatches.
2026-02-20 17:42:35 -08:00
Lawrence Chen
9952955184 Fix setup.sh cache: always rebuild on miss, add stale lock timeout
- Remove local xcframework seeding on cache miss — the local build
  output isn't tied to the current submodule SHA and can produce
  ABI mismatches. Always run zig build when cache misses.
- Add 300s timeout on lock acquisition. If a prior setup was killed
  uncleanly (SIGKILL, host crash), the lock dir persists forever
  and blocks all future runs. Now auto-removes stale locks.
2026-02-20 16:08:20 -08:00
Lawrence Chen
f3a4e4db43
Cache GhosttyKit builds by ghostty commit in setup script (#204) 2026-02-20 14:30:31 -08:00
Lawrence Chen
ca09a7a6d5
Fix nightly icon to match debug icon style (#167)
Recolor the debug icon (orange DEV → purple NIGHTLY) instead of
pasting a banner onto the production icon. This preserves the exact
same chevron positioning, glow effects, and banner integration.
2026-02-20 04:19:10 -08:00
Lawrence Chen
ec9b80f389
Add nightly-specific app icon with purple NIGHTLY banner (#166)
Follows the same pattern as AppIcon-Debug (orange DEV banner) but with
a purple banner and "NIGHTLY" text. The nightly CI workflow now passes
ASSETCATALOG_COMPILER_APPICON_NAME=AppIcon-Nightly to xcodebuild so
the nightly app gets its own distinct icon.

Includes scripts/generate_nightly_icon.py for regenerating the icons
from the production AppIcon source files.
2026-02-20 04:10:32 -08:00
Lawrence Chen
fc1de08561
Fix homebrew SHA mismatch race condition (#111)
Root cause: update-homebrew.yml triggered on release:published, which fires
before softprops/action-gh-release finishes uploading assets. The workflow
downloaded a 404 page instead of the DMG and committed its SHA.

Fix:
- Change trigger from release:published to workflow_run (fires after the
  release workflow completes, guaranteeing assets are uploaded)
- Add download validation with retries and file size checks
- Add SHA verification step before committing to the cask
- Add homebrew cask update to build-sign-upload.sh for local releases
- Add regression test (tests/test_homebrew_sha.sh)
- Update /release and /release-local skills with homebrew verification steps

Fixes #110
2026-02-19 17:44:00 -08:00
Lawrence Chen
09a85e93d2 Extract build/sign/notarize into scripts/build-sign-upload.sh 2026-02-19 04:33:42 -08:00
Lawrence Chen
7aa80b9cdc Stabilize rapid workspace switching handoff 2026-02-18 21:17:53 -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
6d6efb6b60 Reversion all 1.x.x to 0.x.x for pre-launch versioning 2026-02-17 18:31:05 -08:00
Lawrence Chen
6d68cd2f08 Polish browser suggestions, focus, and tagged reload flow 2026-02-14 21:33:28 -08:00
Lawrence Chen
faf1bd44c2 release: fix Sparkle upgrade path for 1.27.0 users 2026-02-14 03:26:42 -08:00
Lawrence Chen
2bae2ca2f0 scripts: require --tag for debug reload 2026-02-14 03:13:10 -08:00
Lawrence Chen
50f0dd334d
Fix frozen terminals after split churn (#12)
* Fix blank terminal after split operations and add visual tests

## Blank Terminal Fix
- Add `needsRefreshAfterWindowChange` flag in GhosttyTerminalView
- Force terminal refresh when view is added to window, even if size unchanged
- Add `ghostty_surface_refresh()` call in attachToView for same-view reattachment
- Add debug logging for surface attachment lifecycle (DEBUG builds only)

## Bonsplit Migration
- Add bonsplit as local Swift package (vendor/bonsplit submodule)
- Replace custom SplitTree with BonsplitController
- Add Panel protocol with TerminalPanel and BrowserPanel implementations
- Add SidebarTab as main tab container with BonsplitController
- Remove old Splits/ directory (SplitTree, SplitView, TerminalSplitTreeView)

## Visual Screenshot Tests
- Add test_visual_screenshots.py for automated visual regression testing
- Uses in-app screenshot API (CGWindowListCreateImage) - no screen recording needed
- Generates HTML report with before/after comparisons
- Tests: splits, browser panels, focus switching, close operations, rapid cycles
- Includes annotation fields for easy feedback

## Browser Shortcut (⌘⇧B)
- Add keyboard shortcut to open browser panel in current pane
- Add openBrowser() method to TabManager
- Add shortcut configuration in KeyboardShortcutSettings

## Screenshot Command
- Add 'screenshot' command to TerminalController for in-app window capture
- Returns OK with screenshot ID and path

## Other
- Add tests/visual_output/ and tests/visual_report.html to .gitignore

* Add browser title subscription and set tab height to 30px

- Subscribe to BrowserPanel.$pageTitle changes to update bonsplit tabs
- Update tab titles in real-time as page navigation occurs
- Clean up subscriptions when panels are removed
- Set bonsplit tab bar and tab height to 30px (in submodule)

* Fix socket API regressions in list_surfaces, list_bonsplit_tabs, focus_pane

- list_surfaces: Remove [terminal]/[browser] suffix to keep UUID-only format
  that clients and tests expect for parsing
- list_bonsplit_tabs --pane: Properly look up pane by UUID instead of
  creating a new PaneID (requires bonsplit PaneID.id to be public)
- focus_pane: Accept both UUID strings and integer indices as documented

* Fix browser panel stability and keyboard shortcuts

- Prevent WKWebView focus lifecycle crashes during split/view reshuffles
- Match bracket shortcuts via keyCode (Cmd+Shift+[ / ], Cmd+Ctrl+[ / ])
- Support Ghostty config goto_split:* keybinds when WebView is focused
- Add focus_webview/is_webview_focused socket commands and regression tests
- Rename SidebarTab to Workspace and update docs

* Make ctrl+enter keybind test skippable

Skip when the Ghostty keybind isn't configured or when osascript can't send keystrokes (no Accessibility permission), so VM runs stay green.

* Auto-focus browser omnibar when blank

When a browser surface is focused but no URL is loaded yet, focus the address bar instead of the WKWebView.

* Stabilize socket surface indexing

* Focus browser omnibar escape; add webview keybind UI tests

- Escape in omnibar now returns focus to WKWebView\n- Add UI tests for Cmd+Ctrl+H pane navigation with WebKit focused (including Ghostty config)\n- Avoid flaky element screenshots in UpdatePillUITests on the UTM VM

* Fix browser drag-to-split blanks and socket parsing

* Fix webview-focused shortcuts and stabilize browser splits

- Match ctrl/shift shortcuts by keyCode where needed (Ctrl+H, bracket keys)
- Load Ghostty goto_split triggers reliably and refresh on config load
- Add debug socket helpers: set_shortcut + simulate_shortcut for tests
- Convert browser goto_split/keybind tests to socket-based injection (no osascript)
- Bump bonsplit for drag-to-split fixes

* Fix split layout collapse and harden socket pane APIs

* Stabilize OSC 99 notification test timing

* Fix terminal focus routing after split reparent

* Support simulate_shortcut enter for focus routing test

* Stabilize terminal focus routing test

* Fix frozen new terminal tabs after many splits

* Fix frozen new terminal tabs after splits

* Fix terminal freeze on launch/new tabs

* Update ghostty submodule

* Fix terminal focus/render stalls after split churn

* Fix nested split collapsing existing pane

* Fix nested split collapse + stabilize new-surface focus

* Update bonsplit submodule

* Fix SIGINT test flake

* Remove bonsplit tab-switch crossfade

* Remove PROJECTS.md

* Remove bonsplit tab selection animation

* Ignore generated test reports

* Middle click closes tab

* Revert unintended .gitignore change

* Fix build after main merge

* Revert "Fix build after main merge"

This reverts commit 16bf9816d0856b5385d52f886aa5eb50f3c9d9a4.

* Revert "Merge remote-tracking branch 'origin/main' into fix/blank-terminal-and-visual-tests"

This reverts commit 7c20fb53fd71fea7a19a3673f2dd73e5f0c783c4, reversing
changes made to 0aff107d787bc9d8bbc28220090b4ca7af72e040.

* Remove tab close fade animation

* Use terminal.fill icon

* Make terminal tab icon smaller

* Match browser globe tab icon size

* Bonsplit: tab min width 48 and tighter close button

* Bonsplit: smaller tab title font

* Show unread notification badge in bonsplit tabs and improve UI polish

Sync unread notification state to bonsplit tab badges (blue dot).
Improve EmptyPanelView with Terminal/Browser buttons and shortcut hints.
Add tooltips to close tab button and search overlay buttons.

* Fix reload.sh single-instance safety check on macOS

Replace GNU-only `ps -o etimes=` with portable `ps -o etime=` and
parse the dd-hh:mm:ss format manually for macOS compatibility.

* Centralize keyboard shortcut definitions into Action enum

Replace per-shortcut boilerplate with a single Action enum that holds
the label, defaults key, and default binding for each shortcut. All
call sites now use shortcut(for:). Settings UI is data-driven via
ForEach(Action.allCases). Titlebar tooltips update dynamically when
shortcuts are changed. Remove duplicate .keyboardShortcut() modifiers
from menu items that are already handled by the event monitor.

* Fix WKWebView consuming app menu shortcuts and close panel confirmation

Add CmuxWebView subclass that routes key equivalents through the main
menu before WebKit, so Cmd+N/Cmd+W/tab switching work when a browser
pane is focused. Fix Cmd+W close-panel path: bypass Bonsplit delegate
gating after the user confirms the running-process dialog by tracking
forceCloseTabIds. Add unit tests (CmuxWebViewKeyEquivalentTests) and
UI test scaffolding (MenuKeyEquivalentRoutingUITests) with a new
cmux-unit Xcode scheme.

* Update CLAUDE.md and PROJECTS.md with recent changes

CLAUDE.md: enforce --tag for reload commands, add cleanup safety rules.
PROJECTS.md: log notification badge, reload.sh fix, Cmd+W fix, WebView
key equiv fix, and centralized shortcuts work.

* Keep selection index stable on close

* Add concepts page documenting terminology hierarchy

New docs page explaining Window > Workspace > Pane > Surface > Panel
hierarchy with aligned ASCII diagram. Updated tabs.mdx and splits.mdx
to use consistent terminology (workspace instead of tab, surface
instead of panel) and corrected outdated CLI command references.

* Update bonsplit submodule

* WIP: improve split close stability and UI regressions

* Close terminal panel on child exit; hide terminal dirty dot

* Fix split close/focus regressions and stabilize UI tests

* Add unread Dock/Cmd+Tab badge with settings toggle

* Fix browser-surface shortcuts and Cmd+L browser opening

* Snapshot current workspace state before regression fixes

* Update bonsplit submodule snapshot

* Stabilize split-close regression capture and sidebar resize assertions

* Change default Show Notifications shortcut from Cmd+Shift+I to Cmd+I

* Fix update check readiness race, enable release update logging, and improve checking spinner

* Restore terminal file drop, fix browser omnibar click focus, and add panel workspace ID mutation for surface moves

* Add Cmd+digit workspace hints, titlebar shortcut pills, sidebar drag-reorder, and workspace placement settings

* Add v2 browser automation API, surface move/reorder commands, and short-handle ref system to TerminalController

* Add CLI browser command surface, --id-format flag, and move/reorder commands

* Extend test clients with move/reorder APIs, ref-handle support, and increased timeouts

* Harden test runner scripts with deterministic builds, retry logic, and robust socket readiness

* Stabilize existing test suites with focus-wait helpers, increased timeouts, and API shape updates

* Add terminal file drop e2e regression test

* Add v2 browser API, CLI ref resolution, and surface move/reorder test suites

* Add unit tests for shortcut hints, workspace reorder, drop planner, and update UI test stabilization

* Add cmux-debug-windows skill with snapshot script and agent config

* Update project docs: mark browser parity and move/reorder phases complete, add parallel agent workflow guidelines

* Update bonsplit submodule: re-entrant setPosition guard, tab shortcut hints, and moveTab/reorderTab API

* Add browser agent UX improvements: snapshot refs, placement reuse, diagnostics, and skill docs

- Upgrade browser.snapshot to emit accessibility tree text with element refs (eN)
- Add right-sibling pane reuse policy for browser.open_split placement
- Add rich not_found diagnostics with retry logic for selector actions
- Support --snapshot-after for post-action verification on mutating commands
- Allow browser fill with empty text for clearing inputs
- Default CLI --id-format to refs-first (UUIDs opt-in via --id-format uuids|both)
- Format legacy new-pane/new-surface output with short surface refs
- Add skills/cmuxterm-browser/ and skills/cmuxterm/ end-user skill docs
- Add regression tests for placement policy, snapshot refs, diagnostics, and ID defaults

* Update bonsplit submodule: keep raster favicons in color when inactive
2026-02-13 16:45:31 -08:00
Lawrence Chen
2db074b03b
Bump version to 1.25.0 (#33)
Fix blank terminal on macOS 26 and macOS 15:
- Add macOS 26 guard to two additional code paths that set window non-opaque
- Fix NSVisualEffectView z-order: add to themeFrame instead of contentView
- Align sidebarBlendMode defaults between @AppStorage and UserDefaults
- Add read_screen socket command and blank screen regression test
- Add reloads.sh staging script
2026-02-11 16:24:31 -08:00
Lawrence Chen
9817d131f8
Release v1.23.0 (#31)
* Rename cmuxterm to cmux across entire codebase

- Rename GitHub repos: manaflow-ai/cmuxterm -> manaflow-ai/cmux,
  manaflow-ai/homebrew-cmuxterm -> manaflow-ai/homebrew-cmux
- Rename bundle IDs: com.cmuxterm.app -> com.cmux.app
- Rename CLI: CLI/cmuxterm.swift -> CLI/cmux.swift
- Rename homebrew submodule: homebrew-cmuxterm -> homebrew-cmux
- Update all socket paths: /tmp/cmuxterm*.sock -> /tmp/cmux*.sock
- Update all GitHub URLs, DMG names, Sparkle URLs
- Update all source files, scripts, tests, docs, CI workflows

* Bump version to 1.23.0
2026-02-09 15:30:43 -08:00
Lawrence Chen
9ba1d02b2b scripts: don't inherit GIT_PAGER/GH_PAGER into app 2026-02-09 15:11:01 -08:00
Lawrence Chen
7e69751e1b
Sidebar metadata + tagged reload isolation (#16)
* Sidebar primitives + tagged dev isolation

* Allow wider sidebar resize

* Fix tagged socket selection + panel id errors

* Fix progress label quoting + bundle suffix sanitize

* Skip ctrl-enter keybind test when keystrokes blocked

* Fix shell nc hang + prune stale per-surface sidebar metadata
2026-02-06 18:09:56 -08:00
Lawrence Chen
0340e794b8
Fix Sparkle auto-update: inject SUPublicEDKey into Info.plist via PlistBuddy (#15)
Root cause: INFOPLIST_KEY_ build setting prefix only works for Apple-recognized
keys (CF*, NS*, LS*), not custom keys like SUPublicEDKey. The key was never
being added to Info.plist, so generate_appcast silently skipped EdDSA signing
(no public key in app = nothing to match against).

Fix:
- Derive public key from private key at build time using CryptoKit
- Use PlistBuddy to inject SUPublicEDKey and SUFeedURL after build
- Add sign_update fallback in appcast script if generate_appcast skips signing
- Add base64 padding normalization for key handling
2026-02-05 19:57:01 -08:00
Lawrence Chen
6391300d52 Fix Sparkle appcast signing: write key to file instead of stdin
generate_appcast doesn't reliably read EdDSA key from stdin via
--ed-key-file -. Write key to a temp file instead.
2026-02-05 19:38:38 -08:00
Lawrence Chen
cc71e5797e
Add sidebar blur effect with withinWindow blending (#9)
* Add sidebar blur effect with withinWindow blending

- Add NSVisualEffectView-based blur backdrop for sidebar
- Support withinWindow blending mode to blur terminal content behind sidebar
- Auto-switch to overlay layout when withinWindow mode is selected
- Add sidebar debug panel with material, blending, tint, and opacity controls
- Add preset options (HUD Glass, Popover Glass, etc.)
- Default to HUD Glass preset with withinWindow blur

* Simplify tab close button visibility and remove hover background

Show close button only on hover instead of when active/multi-selected.
Remove the hover background color from tabs for cleaner appearance.

* Add config reload support with notification system

- Add reloadConfiguration() methods for app-wide and per-surface reload
- Handle GHOSTTY_ACTION_RELOAD_CONFIG action from Ghostty
- Add ghosttyConfigDidReload notification for views to react
- TerminalSplitTreeView reloads GhosttyConfig on notification
- Add openConfigurationInTextEdit() helper
- Fix activeMainWindow() to correctly find main window

* Add custom tab titles and pinned tabs support

- Add customTitle and isPinned properties to Tab
- Separate process title from custom title with applyProcessTitle()
- Add setCustomTitle()/clearCustomTitle() for user-defined tab names
- Add togglePin()/setPinned() with automatic reordering
- Pinned tabs stay at the top, new tabs insert after pinned section
- moveTabToTop/moveTabsToTop respect pinned tab ordering

* Add --panel option to new-split command

- CLI: Parse --panel <id|index> option for new-split
- Controller: Resolve panel argument to split specific surface
- Return new panel UUID on successful split creation

* Fix notifications popover positioning with layout-aware anchor

- Use AnchorNSView with layout callback for reliable positioning
- Force layout before showing popover to ensure current geometry
- Convert anchor bounds to window content view coordinates
- Add fallback positioning near top-left when anchor unavailable
- Fix button hit testing with explicit frame and contentShape

* Improve app termination in reload script

Use osascript to gracefully quit by bundle ID before pkill fallback.
Add more robust pkill patterns to catch instances from any DerivedData path.

* Add sidebar blur effect with live-adjustable glass settings

- Add WindowGlassEffect for window-level NSGlassEffectView (macOS 26+)
- Add SidebarBackdrop with configurable material, blend mode, tint, and opacity
- Add Sidebar Debug panel (Debug menu) for live adjustment of sidebar appearance
- Add Background Debug panel for window glass tint settings
- Support both behindWindow and withinWindow blur modes
- Live tint updates without requiring window reload

* Align titlebar text to left edge of content area
2026-02-04 03:04:45 -08:00
Lawrence Chen
7bae1216ff Fix race condition in reload.sh causing -600 error
Add delay after pkill to give Launch Services time to release the
old process handle before opening the new app.
2026-02-03 15:30:23 -08:00
Lawrence Chen
2afadbbbb9
Add bump-version script and improve reload script (#7)
- bump-version.sh: Automated version bumping for marketing and build
  versions with major/minor/patch support
- reload.sh: Enhanced with better process management, GhosttyKit
  rebuild detection, and improved error handling
2026-02-03 15:17:49 -08:00
Lawrence Chen
e234123c17 Include local changes 2026-01-30 16:46:30 -08:00
Lawrence Chen
4b77b1117d Fix focus-on-scroll and harden reload scripts 2026-01-30 16:46:30 -08:00
Lawrence Chen
a0bf5dfc84 Add cmuxterm CLI and socket control modes 2026-01-28 21:19:48 -08:00
Lawrence Chen
f0e2efe8e4 Refine titlebar controls and clear notifications on close 2026-01-28 17:35:48 -08:00
Lawrence Chen
3877dc2d98 Rename app to cmuxterm 2026-01-28 02:38:24 -08:00
Lawrence Chen
6d3bbb1577 Rename reload-prod to reloadp and parallelize reload2 2026-01-28 02:14:14 -08:00
Lawrence Chen
17a3e2033f Add dev build branding and reload scripts 2026-01-28 01:20:48 -08:00
Lawrence Chen
e3ee246930 Add Sparkle auto-update flow and titlebar update UI 2026-01-26 17:25:34 -08:00
Lawrence Chen
8320d5805a Rename to cmux and add About panel 2026-01-26 03:05:03 -08:00
Lawrence Chen
c5bd543fe0 Initial commit: macOS terminal app with vertical tabs using libghostty
Features:
- Vertical tabs sidebar with SwiftUI
- Terminal emulation via GhosttyKit.xcframework (libghostty)
- Keyboard shortcuts: Cmd+T/N, Ctrl+Shift+` (new tab), Cmd+W (close),
  Cmd+Shift+[/], Ctrl+Tab (navigation), Cmd+1-9 (jump to tab)
- Reads Ghostty config from ~/Library/Application Support/com.mitchellh.ghostty/config
- Metal-based rendering
2026-01-22 01:16:24 -08:00