Commit graph

190 commits

Author SHA1 Message Date
Lawrence Chen
1b4f396a48 Merge remote-tracking branch 'origin/main' into issue-151-ssh-remote-port-proxying
# Conflicts:
#	Sources/Panels/BrowserPanel.swift
2026-03-11 22:52:47 -07:00
Lawrence Chen
7844226ded Fix browser devtools hide fallback 2026-03-11 20:18:46 -07:00
austinpower1258
8aafb68935 Fix browser pane drag/drop follow-ups 2026-03-11 19:16:17 -07:00
austinpower1258
1dbd1e5011 Merge branch 'main' of https://github.com/manaflow-ai/cmux into issue-1208-browser-pane-stale-content 2026-03-11 18:54:12 -07:00
austinpower1258
5233874425 ok 2026-03-11 18:32:23 -07:00
Lawrence Chen
5d82a29f45 Repair local-host devtools reparent geometry 2026-03-11 18:21:41 -07:00
Lawrence Chen
e6a293bd78 Merge remote-tracking branch 'origin/main' into issue-151-ssh-remote-port-proxying 2026-03-11 18:21:39 -07:00
Lawrence Chen
6849b83f8d
Reduce typing lag from sidebar re-evaluation and hitTest overhead (#1204)
* Add typing hot path timing diagnostics

* Add stress workspace debug menu item

* Restore stress workspace preload debug path

* Reduce typing lag from sidebar re-evaluation and hitTest overhead

hitTest: gate divider/sidebar/drag routing to pointer events only,
avoiding two full view-tree walks per non-pointer event.

forceRefresh: replace per-keystroke ISO8601DateFormatter + FileHandle
I/O with dlog() in DEBUG builds.

TabItemView: replace @EnvironmentObject subscriptions with plain refs
and precomputed parameters, add Equatable conformance to skip body
re-evaluation when parent rebuilds with unchanged values. @self changed
re-evaluations dropped from 668 to 1 during rapid typing.

* Add typing-latency guardrail comments and CLAUDE.md pitfalls

Strategic comments on hitTest, TabItemView, and forceRefresh to prevent
future regressions. Adds typing-latency-sensitive paths to CLAUDE.md
pitfalls section so agents know the constraints before editing.

* Add workspace palette actions and fix release autosave typing guard

Add Move Up/Down/Top, Close Other/Above/Below, Mark Read/Unread to
Cmd+Shift+P command palette and a Workspace submenu in the menu bar.

Fix recordTypingActivity() being gated behind #if DEBUG, which prevented
release builds from honoring the typing quiet period in autosave.
2026-03-11 17:54:02 -07:00
Lawrence Chen
d67090994e Merge branch 'main' into issue-151-ssh-remote-port-proxying 2026-03-11 15:56:47 -07:00
Lawrence Chen
d9021861e3 Preserve ssh remote browser proxy flow 2026-03-11 15:45:20 -07:00
austinpower1258
06c5cac4df Stabilize docked devtools side resize 2026-03-11 12:26:19 -07:00
austinpower1258
8b66628b19 Route inline inspector hits to native webkit 2026-03-11 04:21:49 -07:00
austinpower1258
63787c26b1 Stabilize inline developer tools hosting 2026-03-11 04:17:37 -07:00
Lawrence Chen
3ca11a5e00 Keep off-window local hosts from stealing devtools view 2026-03-10 21:12:18 -07:00
Lawrence Chen
359ada8a3f Preserve side-docked browser devtools layout on pane resize 2026-03-10 20:42:26 -07:00
Austin Wang
d25067f38f
Merge pull request #1170 from manaflow-ai/fix-1160-devtools-loop
Fix side-docked browser DevTools resizing
2026-03-10 20:12:17 -07:00
austinpower1258
91061ce341 Fix side-docked browser DevTools resizing 2026-03-10 19:49:06 -07:00
Lawrence Chen
ec10dfdaec
Add browser find focus debug logs (#1162)
* Add browser find focus debug logs

* Allow browser find bar focus in portal host

* Add split and terminal find debug logs

* Avoid stealing search focus across splits

* Generalize panel focus restore intent

* Unify split focus intent activation

* Address focus restore review feedback

* Yield inactive panel focus before restore

* Gate browser find focus retries by generation

* Avoid repeated browser focus invalidation

* Keep browser find ownership while find bar is open
2026-03-10 19:31:52 -07:00
austinpower1258
eea6cdc1bd works 2026-03-10 19:18:30 -07:00
austinpower1258
034f157feb Keep browser omnibar visible across pane zoom 2026-03-10 00:41:00 -07:00
Lawrence Chen
bdebc8ecc9 Merge branch 'main' into issue-151-ssh-remote-port-proxying
# Conflicts:
#	CLI/cmux.swift
#	Sources/ContentView.swift
#	Sources/GhosttyTerminalView.swift
#	Sources/Panels/BrowserPanel.swift
#	Sources/Panels/BrowserPanelView.swift
#	Sources/TabManager.swift
#	Sources/TerminalController.swift
#	Sources/Workspace.swift
#	Sources/WorkspaceContentView.swift
#	ghostty
2026-03-09 18:36:59 -07:00
Lawrence Chen
30bb74dc92 Merge branch 'pr-374-ssh-remote-cli-relay' into issue-151-ssh-remote-port-proxying
# Conflicts:
#	CLI/cmux.swift
#	Sources/ContentView.swift
#	Sources/GhosttyTerminalView.swift
#	Sources/Panels/TerminalPanel.swift
#	Sources/SocketControlSettings.swift
#	Sources/TabManager.swift
#	Sources/TerminalController.swift
#	Sources/Workspace.swift
#	daemon/remote/README.md
#	daemon/remote/cmd/cmuxd-remote/main.go
#	docs/remote-daemon-spec.md
#	tests_v2/test_ssh_remote_cli_metadata.py
2026-03-09 18:31:10 -07:00
Austin Wang
b824147dcb
Fix notification ring dismissal on direct terminal clicks (#1126)
* Add regression test for terminal notification click dismissal

* Dismiss terminal notifications on direct clicks

* Add regression for focused terminal notification ring

* Keep focused terminal notifications unread until click

* Verify direct notification dismiss triggers flash

* Use focus-flash path for direct notification dismiss

* Align notification dismiss flash with ring geometry
2026-03-09 17:55:07 -07:00
Austin Wang
8fa1ca3a4d
Hide browser portal when terminal tab is active (#1130) 2026-03-09 17:24:58 -07:00
Austin Wang
c447bee602
Fix browser pane portal anchor sizing (#1094)
* Fix browser pane webview sizing

* Guard browser portal by pane ownership

* Keep browser portal frame during transient zero geometry

* Guard portal surfaces against duplicate hosts

* Defer terminal surface reflow during tab drags

* Fix browser panel pane ID unit tests
2026-03-09 13:28:05 -07:00
austinpower1258
52bd8cf16a Keep browser webviews alive during drag reparenting 2026-03-08 03:04:12 -07:00
austinpower1258
58f1f34466 Fix browser reattach after pane reparenting 2026-03-07 18:49:42 -08:00
Austin Wang
0c11bc17cd
Merge pull request #1043 from manaflow-ai/issue-1036-tooltip-tracking-area-crash
Fix tooltip tracking lifetime and shortcut lag
2026-03-07 03:05:48 -08:00
Lawrence Chen
e680f1de55
Add DEBUG logging for browser omnibar/content focus handoff (#910)
* Add browser focus debug logging around omnibar/content handoff

* Avoid release-only unused-value warnings in focus debug logs

* Add omnibar focus writer trace logs

* Fix omnibar tap focus race

* Stabilize omnibar focus state transitions

* Propagate event context into responder guard

* Fix webview pointer hit testing in focus guard

* Stop omnibar reacquire on pointer blur intent

* Blur omnibar on webview click intent

* Preserve pointer intent through webview focus handoff

* Restore page input focus after omnibar escape

* Fix omnibar escape focus handoff and restore retry

* Track editable focus for omnibar restore and improve test diagnostics

* Add omnibar focus tracker telemetry to failing UI test

* Wait for page readiness before seeding focused input in UI test setup

* Strengthen omnibar escape focus regression with post-click assertion

* Use deterministic window offsets for post-escape web input click test

* Always enforce webview responder on omnibar escape

* Harden omnibar focus restore and address PR review feedback

---------

Co-authored-by: tiffanysun1 <tiffanysun8@gmail.com>
2026-03-07 03:05:13 -08:00
austinpower1258
01e9a05817 Merge remote-tracking branch 'origin/main' into issue-1036-tooltip-tracking-area-crash
# Conflicts:
#	Sources/ContentView.swift
2026-03-07 02:53:20 -08:00
Lawrence Chen
3432a4a941
Make missing markdown path selectable (#1042)
Co-authored-by: cmux <cmux@cmuxs-Mac-mini.local>
2026-03-07 02:15:55 -08:00
austinpower1258
9e8a401e3c Fix tooltip tracking lifetime and shortcut lag 2026-03-07 01:46:02 -08:00
austinpower1258
d43d7d6a51 Fix drag hover redraw churn in hosted panes 2026-03-06 15:47:11 -08:00
Austin Wang
0f14fc0cd1
Merge pull request #995 from manaflow-ai/issue-969-browser-drag-top-drop-targets
Fix browser portal anchor churn during pane drag
2026-03-06 00:18:18 -08:00
Lawrence Chen
e04787789e
Fix markdown panel text click focus (#991)
* Add markdown click regression test

* Fix markdown panel click focus

* Preserve markdown text selection

* Make markdown observer tests deterministic
2026-03-05 22:38:10 -08:00
austinpower1258
3874cac08e Merge origin/main into issue-969-browser-drag-top-drop-targets 2026-03-05 22:36:33 -08:00
Lawrence Chen
46e810fef2
Move rectApproximatelyEqual out of #if DEBUG in HostContainerView (#1000)
The function was defined inside a #if DEBUG block but called from
non-DEBUG code, breaking Release builds (nightly CI).
2026-03-05 22:18:48 -08:00
Austin Wang
138ed0e2f0
Merge pull request #990 from manaflow-ai/issue-983-browser-unfocusable-after-cmdr
Fix browser focus after dismissing the command palette by click
2026-03-05 22:17:06 -08:00
austinpower1258
2427a2a736 Fix browser portal anchor churn during pane drag 2026-03-05 21:55:26 -08:00
austinpower1258
44910d03e8 fix: preserve browser target lookup on palette dismiss 2026-03-05 21:29:58 -08:00
Austin Wang
15c7c0cc3c
Fix side-docked dev tools resize (#712)
* wip

* Fix side-docked dev tools resize
2026-03-05 21:28:31 -08:00
Lawrence Chen
e49e572505
Fix browser Cmd+F overlay clipping in portal mode (#916)
* Fix browser Cmd+F overlay clipping in portal mode

* Fix browser Cmd+F panel update regression

* Fix browser find overlay lifecycle and focus

* Extract regression test helpers for browser find guards

* Restore new-tab Cmd+F overlay and harden test helper

* Fix browser Cmd+F focus handoff race

* Fix browser Cmd+F focus loss across page load

* Address review feedback on browser find focus guards

* Add Cmd+F pane-switch regression UI tests

* Run Cmd+F pane-switch regressions from existing UI suite

* Restore browser find focus on pane refocus

* Stabilize Cmd+F pane-switch regressions with focus-state recorder

* Make autofocus race UI test wait on deterministic page signal

* Fix cmuxTests WebViewRepresentable init after browser search state param
2026-03-05 15:36:47 -08:00
Austin Wang
9b215eddab
Fix browser portal pane drag routing and uploads (#961) 2026-03-05 15:27:17 -08:00
atani
3a5bd8494c
fix: avoid NSTextView tracking loop in omnibar mouseDown (#928)
* fix: avoid NSTextView tracking loop in omnibar mouseDown (#917)

Replace the synthetic mouseUp timeout workaround with direct cursor
positioning via NSTextView.characterIndexForInsertion(at:). The previous
approach posted a fake mouseUp event via NSApp.postEvent after 3 seconds,
but the NSTextView tracking loop does not always dequeue events from the
application event queue when stuck in an infinite
NSTextLayoutManager.enumerateTextLayoutFragments cycle, so the hang
persisted.

The new approach bypasses super.mouseDown entirely when the field editor
is already active, positioning the cursor (or extending the selection
with Shift+click) without entering the tracking loop. Drag-to-select is
not supported in this code path, but for a single-line omnibar this is
an acceptable trade-off.

* fix: handle double-click, UTF-16 length, and shift-click anchor

Address review feedback:

- Forward double/triple-click events to editor.mouseDown(with:) to
  preserve word and line selection without entering NSTextField's
  tracking loop
- Use (editor.string as NSString).length instead of String.count for
  NSRange clamping (NSRange uses UTF-16 indices)
- Track shift-click anchor independently via shiftClickAnchor property
  to correctly handle bidirectional selection extension

* fix: reset shiftClickAnchor on keyDown to prevent stale anchor

Clear the shift-click selection anchor whenever a key is pressed, so
that keyboard navigation (arrow keys, Shift+arrow, Home/End, etc.)
properly invalidates the mouse-originated anchor. A subsequent
Shift+click will then use the current selection position as anchor
instead of a stale value from a prior mouse interaction.

* fix: reset shiftClickAnchor in performKeyEquivalent and on re-focus

Key equivalents (Cmd+A, Cmd+V, etc.) bypass keyDown and go through
performKeyEquivalent, so the anchor must also be cleared there.
Similarly, re-focusing the field (currentEditor() == nil path) should
reset the anchor since selectAll changes the selection state.
2026-03-05 02:31:23 -08:00
Eray Bozoglu
2712cabac9
Fix orphaned child processes when closing workspace tabs (#889)
* Fix orphaned child processes when closing workspace tabs

When closing a workspace tab via the sidebar X button, child processes
(login → zsh → claude) survived as orphans because TabManager.closeWorkspace()
only removed the workspace from the tabs array without explicitly freeing
Ghostty surfaces. It relied on ARC to cascade deallocation, but SwiftUI views
and Combine publishers held references, delaying or preventing
ghostty_surface_free() (which sends SIGHUP) from ever running.

This adds explicit teardown on the workspace close path:
- TerminalSurface.teardownSurface(): idempotent method to free the Ghostty
  runtime surface eagerly, matching the existing deinit logic
- TerminalPanel.close() now calls teardownSurface() to ensure SIGHUP is sent
- Workspace.teardownAllPanels() iterates all panels and closes them
- TabManager.closeWorkspace() calls teardownAllPanels() before removing
  the workspace from the tabs array

* Harden workspace teardown and ownership checks

* Address follow-up teardown review feedback

---------

Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
2026-03-04 20:00:35 -08:00
Austin Wang
6fe1410918
Fix terminal link opens to stay in source workspace (#912) 2026-03-04 19:21:45 -08:00
Austin Wang
80baae355a
Add browser camera permission support and metadata (#760) (#913) 2026-03-04 18:56:22 -08:00
Ismail Pelaseyed
d72b014d6d
feat: add markdown viewer panel with live file watching (#883)
* Add markdown viewer panel with live file watching

Introduce a new PanelType.markdown that renders .md files in a dedicated
panel using MarkdownUI (SwiftUI), with live file watching via DispatchSource
so content auto-updates when the file changes on disk.

- New MarkdownPanel class with file system watcher (write/delete/rename/extend)
- New MarkdownPanelView with custom cmux theme (headings, code blocks, tables,
  blockquotes, inline code, lists, horizontal rules, light/dark mode)
- Full workspace integration: SurfaceKind, creation methods, tab subscription
- Session persistence: snapshot/restore across app restarts
- V2 socket command: markdown.open (validates path, resolves workspace, splits)
- CLI command: cmux markdown open <path> with routing flags and help text
- Agent skill: skills/cmux-markdown/ with SKILL.md, openai.yaml, and references
- Cross-link from skills/cmux/SKILL.md to the new markdown skill
- SPM dependency: gonzalezreal/swift-markdown-ui 2.4.1

* Fix unreachable guard in markdown subcommand dispatch

Use looksLikePath() to distinguish subcommands from path arguments
so the guard can catch unknown subcommands and future subcommands
are parsed correctly.

* Use .isoLatin1 fallback instead of .ascii for encoding recovery

ASCII is a strict subset of UTF-8, so falling back to .ascii after
UTF-8 fails is dead code. Use .isoLatin1 which accepts all 256 byte
values and covers legacy encodings like Windows-1252.

* Mark fileWatchSource as nonisolated(unsafe) for deinit safety

deinit is not guaranteed to run on the main actor, so accessing
@MainActor-isolated storage is a data race under strict concurrency.
DispatchSource.cancel() is thread-safe, so nonisolated(unsafe) is
sufficient with a documented invariant that writes only occur on main.

* Fix file watcher reattach: retry loop with cancellation guard

- Replace one-shot 500ms retry with up to 6 attempts (3s total window)
  so files that reappear after a slow atomic replace are picked up
- Add isClosed flag checked before each retry to prevent restarting
  the watcher after close()/deinit

* Harden path validation in markdown.open command

Reject directories and non-absolute paths before panel creation
to prevent ambiguous behavior and generic downstream failures.

* Always reattach file watcher on delete/rename events

After an atomic save (delete old + create new), the DispatchSource still
points to the old inode. Previously we only reattached when the file was
unreadable, so successful atomic saves left the watcher on a stale inode
and live updates silently stopped. Now we always stop and reattach:
immediately if the new file is readable, via retry loop if not.

* Restore markdown panels even when file is missing at launch

MarkdownPanel already handles unavailable files gracefully (shows
'file unavailable' UI and retries via the reattach loop). Dropping
the panel on restore lost the user's layout for files that may
reappear shortly after (network drives, build artifacts, etc.).

* Harden markdown CLI parsing and startup reconnect behavior

---------

Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
2026-03-04 17:48:28 -08:00
Lawrence Chen
28977c8e3b
Fix browser panel lifecycle after WebContent process termination (#892)
* Fix browser panel webview lifecycle after web content crashes

* Fix BrowserPanel observer lifecycle during webview replacement

* Fix WebKit termination delegate and harden lifecycle regression check
2026-03-04 16:23:22 -08:00
Yoshiki Agatsuma
76bdf7631a
Add find-in-page (Cmd+F) for browser panels (#837) (#875)
JavaScript-based find using TreeWalker + <mark> highlights with
match counter, next/previous navigation, and drag-to-corner overlay
matching the existing terminal find bar.

- BrowserFindJavaScript: JS generation for search/next/prev/clear
- BrowserSearchOverlay: SwiftUI overlay with IME-safe onSubmit
- BrowserSearchState: Observable state (needle/selected/total)
- TabManager routing: Cmd+F/G dispatches to browser when focused
- Visibility filter: skips script/style/hidden/aria-hidden elements
- Stale DOM guard: isConnected check in next/previous scripts
- Navigation cleanup: clears find on didFinish and didFailNavigation

Co-authored-by: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com>
2026-03-04 16:15:15 -08:00