Repository navigation
Merge upstream/main (2026-05-28) - #24
Merged
Merged
Conversation
…aflow-ai#4834) * Add cmux.xcworkspace with Packages visible alongside the project Top-level navigator shows cmux.xcodeproj plus every Packages/* SPM package as siblings, so local packages are editable in the same window without nesting under the project node. Additive only: existing -project build flows (reload.sh, CI) keep working unchanged. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Ignore xcshareddata under xcworkspaces Xcode auto-creates xcshareddata inside .xcworkspace bundles for WorkspaceSettings.xcsettings, IDEWorkspaceChecks.plist, and SwiftPM configuration. None of those carry intentional shared state for cmux today (build is driven by reload.sh and CI, no private SPM registry, no custom file headers). Ignoring them prevents Xcode bookkeeping churn in commits. Project-level xcshareddata (shared .xcscheme files) is unaffected because the pattern only matches inside .xcworkspace directories. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…naflow-ai#4778) * Redesign notifications popover: bigger, minimal, swipe to dismiss - Larger frame (min 460x480, ideal 560x620, max 760x760) so more notifications are visible at once. - Compact rows with a thin accent bar for unread, tighter typography, hover-revealed clear button. No more boxed cards per row, just dividers between rows. - Drag a row left or right to dismiss; passing the threshold slides it out and removes the notification. Tap to open as before. - Empty/loading/populated states share the same outer frame so the popover stops resizing when notifications come and go. * Show jump-to-latest keyboard shortcut next to button label * Stabilize hover on notification rows: dedicated background tracking layer .onHover and .onTapGesture on the same SwiftUI node share AppKit's mouse-tracking pipeline and arbitrate against each other, producing flaky enter/exit events right after the popover opens and when crossing rows fast. Move hover detection to a transparent background layer using .onContinuousHover, scope the opacity animation to the background only so it does not re-animate dragOffset, and bump the hover opacity from 0.07 to 0.11 so it is visible against .windowBackgroundColor in light mode. * Use NSTrackingArea for notification row hover SwiftUI's .onHover and .onContinuousHover still arbitrate with the parent .onTapGesture in macOS popover content, leaving rows where hover never fires (notably on first popover open and when crossing between LazyVStack rows). Replace the SwiftUI hover modifier with an NSViewRepresentable that installs an NSTrackingArea (.mouseEnteredAndExited + .activeAlways + .inVisibleRect). The tracking NSView returns nil from hitTest so clicks pass through to the SwiftUI parent's tap gesture, and the view syncs current inside/outside state on tracking-area install for the case where the pointer is already inside the row when the popover opens. * Notifications popover: keep timestamp visible, drop hover animation, add right-click menu - Always show row timestamp (removed the hide-on-hover opacity). - Removed the hover background fade animation so it's an instant flip. - Right-click a row for Open / Mark as Read / Mark as Unread / Dismiss. - Added TerminalNotificationStore.markUnread(id:) sibling to markRead(id:). - Added en/ja localizations for the new menu strings. * Notifications popover: drop top margin, always semibold title * Make notifications popover resizable, taller default Default size bumped to 560x760 (was 560x620 ideal). User can drag a bottom-right resize handle to set their own size; the chosen width and height persist via @AppStorage. Bounds are 420x320 .. 1000x1200. * Notifications popover: invisible corner resize, drop swipe-to-dismiss NSPopover has no native resize chrome and there's no first-class SwiftUI resize API for it. The closest native-feeling thing is a hit-only corner region that drives a state-driven .frame: no visual button, just a resizeLeftRight cursor on hover (closest standard NSCursor to a diagonal resize). Also removed swipe-to-dismiss. The hover X button and the right-click Dismiss menu item are the dismiss surfaces; swiping rows in an NSPopover row list isn't a macOS convention. * Notifications popover: fix glitchy resize via AppKit screen coords SwiftUI's DragGesture reports translation in a local coordinate space that is literally being resized under the cursor as the popover grows. Each frame the gesture re-derives translation from a moving anchor, which produces dimension oscillation (the popover jumps between two sizes). Replace the SwiftUI gesture with an NSViewRepresentable that tracks NSEvent.mouseLocation in global screen coordinates. Screen coordinates are stable regardless of popover resize, so deltas are monotonic. Also disable implicit animation on the .frame width/height so the popover follows the cursor 1:1. * Notifications popover: use diagonal resize cursor on bottom-right corner * Notifications popover: address review feedback - unreadCount uses notificationMenuSnapshot.unreadCount instead of reducing the live list, so the badge stays consistent with the hasUnreadNotifications / hasNotifications guards that drive the Jump to Latest / Clear All disabled states. - Hide the visual keyboard-shortcut chip from accessibility; the button already exposes the shortcut via .accessibilityValue, so VoiceOver no longer reads it twice. - Add a row-level accessibility action to dismiss a notification, since the visible clear button is hover-only. Adds the localized string notifications.row.clear (en/ja). * markUnread(id:): clear manual workspace unread to avoid double-count When a user marks a read notification unread, the notification itself now provides the workspace unread indicator. If the workspace also had a manual unread flag set, the popover header, dock badge, and workspace badge would double-count that workspace because the count builders sum notification unread counts and workspace indicators. Mirrors what markLatestNotificationAsOldestUnread already does in the same file. Found by Codex review. * Restore Button wrapper on notification rows for keyboard access Replacing the original Button with .onTapGesture removed rows from the SwiftUI key-view loop, so keyboard-only users could tab to the header controls but not open a row. The original reason for dropping Button was that SwiftUI's .onHover arbitrated with the row's primary action — but hover is now driven entirely by an AppKit NSTrackingArea (HoverTrackingRepresentable), independent of the row's activation node. The Button wrapper is therefore safe again and restores space/return activation in the key-view loop. Found by Codex review. * Notifications popover: persist resize once on mouseUp, clamp drag baseline - Live resize uses @State (liveWidth/liveHeight); @AppStorage is written exactly once when the user releases the mouse, instead of on every mouseDragged event. Each @AppStorage write was hitting UserDefaults and broadcasting UserDefaults.didChangeNotification to every app-wide observer. - Drag baseline now comes from the clamped (currently displayed) size, not raw saved doubles, so a drag that starts with out-of-bounds stored values doesn't lose initial pointer travel re-entering the visible range. * Notifications popover: clear button as ZStack sibling, not nested in row Button Nesting clearButton inside the row's Button(action: onOpen) label created the classic SwiftUI nested-button hit-test problem on macOS: clicks on the inner X could be consumed by the outer row Button's tap area instead of clearing the notification. Move clearButton out of rowContent and into a ZStack(alignment: .trailing) at the body level so it's a sibling of the row Button with an independent hit target. Found by Codex review. * Notifications popover: clamp to screen, hide hover-only X from focus - Clamp the popover's frame against NSScreen.main?.visibleFrame minus an 80pt margin so the bottom-right resize handle stays reachable even when the saved size was captured on a larger display. - Mark the hover-only clear button .accessibilityHidden(!isHovering) so Full Keyboard Access / VoiceOver doesn't focus an invisible dismiss control. Dismissal is still exposed via the row's accessibility action and the right-click menu. Found by Codex. * CI: retry — GitHub Actions infra was returning 403/404 on codeload * CI: retrigger now that GitHub Actions infra is back * Mark-as-Read context menu: clear focused pane indicator too A user-initiated 'Mark as Read' should mirror the full dismissal intent, so the pane's focused-read indicator for that surface should clear alongside flipping the notification's isRead flag. Otherwise the unread count drops but the pane badge remains visible until the user later interacts with the terminal. Found by Codex review. * Notifications popover: clamp against host window's screen, fix hover sync race - Clamp popover size against the screen of NSApp.keyWindow (the popover's anchor window), not NSScreen.main. On multi-monitor setups the popover may appear on a different display than 'main'. - Remove the DispatchQueue.main.async hop in HoverTrackingNSView's updateTrackingAreas; the queued onChange(true) could land after mouseExited's synchronous onChange(false), leaving rows stuck in the hovered state. updateTrackingAreas already runs on the main thread, so the call is fine synchronously. Found by Cursor Bugbot. * Mark-as-Read: only clear focused pane indicator for pane-scoped notifications clearFocusedReadIndicator treats surfaceId == nil as 'clear any pane indicator for this tab', so passing nil for a workspace-level notification would wipe an unrelated pane's badge. Gate the call on notification.surfaceId being non-nil. Found by Codex review. * Notifications popover: add a11y label/hint to resize handle The localized notifications.resize key existed but was never wired to the actual control. Adds .accessibilityLabel/.accessibilityHint so VoiceOver and Full Keyboard Access users can discover the resize affordance. Found by Cursor Bugbot. * Notifications popover: move accessibility identifier back onto the row Button XCUITests query rows with app.buttons["NotificationPopoverRow.<id>"]. The previous pass put .accessibilityIdentifier on the combined outer ZStack, exposing the row as a container rather than a button, which breaks both XCUITest lookups and the button accessibility role for assistive tech. Move identifier + primary action + clear action back onto the inner Button. Found by Codex review. * Notifications popover: snapshot list before LazyVStack; clear restored unread on markUnread - ForEach now iterates an immutable snapshot captured outside the LazyVStack instead of reading notificationStore.notifications inside the row builder; the previous code reintroduced a store dependency below the list boundary, which CLAUDE.md flags as the same anti-pattern that caused the LazyLayoutViewCache spin-loop in the sessions panel (manaflow-ai#2586). - markUnread(id:) now also clears the restored workspace unread indicator for the tab, so a session-restored unread hint plus a user-toggled unread notification no longer double-count in the header/dock/workspace badges. Found by Codex review. --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Remove History mode from right sidebar Drops the History tab from the right sidebar mode picker along with its keyboard shortcut, command palette entries, and the 'Open Full History' menu button. Recently Closed/Focused submenus and Reopen Last Closed still work from the menu bar. * Drop tests for deleted HistoryDayGrouping helper * Tolerate obsolete history mode and restore focus-history menu key - SessionRightSidebarToolPanelSnapshot now decodes an unknown mode (e.g. legacy 'history') as nil instead of failing the entire snapshot, so upgraded users can still restore prior sessions. - Restore the 'menu.history.showFullFocusHistory' key still referenced by AppDelegate+FocusHistoryContextMenu for non-sidebar focus history. * Remove duplicate @mainactor attribute left by prior edit --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Test agent restore startup command launch * Launch restored agents with startup commands * Tighten restored startup launch state * Preserve remote startup for agent restore * Relax remote startup restore assertion * Fix startup restore lifecycle * Remove unused restore launch flag * Run startup resumes in login shell * Tighten remote restore assertion * Handle csh agent restore launchers --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Wrap workspace titles in sidebar * Add workspace title wrap toggle * Localize workspace title wrap setting * Align wrapped workspace title accessories * Reset workspace title wrap preference --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
…nal-path-open Open external path arguments without socket access
* Add secure cmux navigation links * Localize cmux navigation link labels --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* test: cover matched sidebar background tint * fix: match sidebar terminal background * fix: remove dead sidebar overlay path * test: cover matched sidebar boundary separators * fix: keep matched sidebar separators visible * test: cover matched sidebar chrome borders * test: sample sidebar boundary resizers --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Fix JSONC // comment skipper for CRLF line endings Swift treats \r\n as a single extended grapheme cluster, so the existing source[index] != "\n" check inside the three // line-comment skippers never matches a CRLF line ending. On a file with CRLF throughout, the loop runs past the rest of the file looking for a standalone LF and strips everything after the first //. preprocess() then produces truncated JSON and loadCmuxSettingsRoot() / jsonObject() throw "Unexpected end of file". This was breaking the tmux corpus terminal-nightly job's testSurfaceResumeApprovalWritesRecordsIntoCmuxJSON, which explicitly exercises the CRLF path. Match any character whose first scalar is CR or LF so we stop at CR, LF, or CRLF correctly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Allow workflow_dispatch to run tmux corpus terminal-nightly So this workflow's macOS test job is reproducible on demand for branches under review, not only on the nightly schedule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Fix JSONC editor indent detection for CRLF line endings indentationBeforeLine walked back to find the start of the line containing a given index by stopping at "\n" or "\r" characters, but on CRLF input Swift treats "\r\n" as a single extended grapheme cluster that equals neither. The loop then walked past every line break to the start of the file and returned an empty indent, so newly inserted properties (e.g. resumeCommands) ended up at the wrong indentation level. Reuse the isLineTerminator helper that already handles CRLF correctly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
) * Open forked conversations without palette action probe * Fix fork probe snapshot selection * Refresh fork probe cache per palette session * Preserve verified fork probe visibility * Preserve fork snapshot cache during live refresh * Allow verified fallback fork execution * Reprobe fork cache after fallback clears * Preserve focus after instant fork commands * Clear fork cache on execution failure * Avoid stale fork cache on palette reopen * Clear stale fallback fork cache before reprobe * Preserve verified fork cache on palette reopen * Require verified fork snapshot before fallback execution * Track actual fork fallback usage * Preserve verified fork cache fallback flag --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
…anaflow-ai#4871) The tmux corpus terminal-nightly runner cannot initialize a Metal-backed Ghostty surface; embedded_window logs "error initializing surface err=error.OutOfMemory" for every surface the suite creates, and ghostty_surface_new returns nil. The test then fails XCTAssertTrue on performKeyEquivalentAfterMenuMiss because ensureSurfaceReadyForInput cannot return a live surface, which looks like a key-forwarding regression rather than the environment issue that it is. Skip the test (via XCTSkipUnless on TerminalSurface.hasLiveSurface) when the surface fails to initialize, so CI surfaces the real problem (Metal unavailable on this runner) without masking it as a key-bind regression. The test still runs end-to-end on developer machines and on runners with a logged-in GUI session. Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add algorithmic complexity review rule * Align algorithmic complexity review hint --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add David Ondrej testimonial * Move David Ondrej testimonial after DeepMind --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* test: cover broken process pipe reads * fix: read process pipes without NSFileHandle exceptions * fix: preserve partial process pipe output * fix: log process pipe read failures * fix: keep available pipe reads nonblocking * fix: distinguish empty available pipe reads * Avoid toggling pipe read descriptor flags
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Migrate macOS CI/CD runners from WarpBuild/Depot to Blacksmith
Switch all macOS jobs to blacksmith-6vcpu-macos-{15,26,latest}:
- ci.yml (tests, tests-build-and-lag, release-build, ui-regressions)
- build-ghosttykit, nightly, release, test-depot, perf-activation,
tmux-corpus, ci-macos-compat
- test-e2e default → blacksmith-6vcpu-macos-latest; existing
workflow_dispatch input keeps depot-macos-* as fallback options
Update tests/test_ci_self_hosted_guard.sh to assert Blacksmith runners
on the paid jobs from issue manaflow-ai#385.
* Diagnose GUI session on Blacksmith for Cmd-Tab perf bench
Cmd-Tab activation bench times out waiting for a visible CGWindow on Blacksmith macOS runners. perf-activation-session.py works because it talks to the debug socket, so the app process launches fine, but the Cmd-Tab bench uses CGWindowListCopyWindowInfo([.optionOnScreenOnly,...]) which only returns windows the WindowServer is rendering. Print enough runner state to decide whether to launchctl asuser the bench step or move it back to a Warp/Depot GUI-enabled runner.
* Run Cmd-Tab perf bench inside the console Aqua session
On Blacksmith macOS runners (and likely any future GitHub-image-based hosted runner), the runner job runs in launchd's system bootstrap even though it is uid 501. Apps launched via NSWorkspace.openApplication still attach to the WindowServer, but CGWindowListCopyWindowInfo([.optionOnScreenOnly,...]) from a system-bootstrap process does not see those windows in the console user's Aqua session, so the Cmd-Tab benchmark times out waiting for an initial visible window. Re-enter the console user's launchd domain with launchctl asuser before invoking the swift bench so visibility polling sees the real on-screen windows. perf-activation-session.py was unaffected because it talks to the debug socket and does not need WindowServer visibility.
* Harden Blacksmith CI runner config
* Harden macOS runner guard diagnostics
---------
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Optimize testimonial avatars * Localize Peter Steinberger subtitle --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add Fork Conversation to tab right-click menu Adds a `Fork Conversation` item to the bonsplit tab context menu. It appears only when the tab is running an agent session that supports forking without a probe (Claude, Codex). On click, opens a new sibling tab to the right of the source with `claude --resume <id> --fork-session` (or the analogous Codex form) as the startup input, so divergence is owned by the agent's native fork support instead of any cmux-side history copy. Companion to manaflow-ai/bonsplit#135 which adds the menu item plumbing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Lock down Fork Conversation isolation + handler guard Addresses PR manaflow-ai#4888 review feedback: - Annotate `liveAgentIndexCache` / `liveAgentIndexCacheLoadedAt` / their accessor with `@MainActor` so the implicit MainActor isolation from the enclosing `Workspace` class is explicit at the static-storage level. The provider closure already runs during SwiftUI body evaluation on the main actor, but the explicit annotation prevents a Swift 6 strict-concurrency violation when that mode is enabled (CodeRabbit critical / Greptile P1). - Tighten the bonsplit `.forkConversation` handler to mirror the menu visibility gate exactly (`== .supportedWithoutProbe`) instead of the weaker `!= .unsupported`. Closes the gap where the action could let a `.requiresProbe` snapshot through if ever wired up outside the controlled menu (Greptile summary note). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add unit tests for Fork Conversation tab action Covers the new Workspace API and the bonsplit context-menu wiring without needing to drive the NSMenu UI (which XCUI can't reach reliably): - forkAgentConversationToNewTab creates a sibling tab in the same pane, not a split pane, with the snapshot's `--fork-session` command as its initial input. - The forked tab lands immediately to the right of its source even when there are other tabs further right. - canForkAgentConversationFromPanel flips on once a restored Claude snapshot is associated with the panel. - The bonsplit `.forkConversation` action dispatches end-to-end through splitTabBar(_:didRequestTabContextAction:for:inPane:) to the same forkAgentConversationToNewTab path, locking in the menu wiring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Fix Fork Conversation tests: use public TabID API CI test target failed to compile because the tests reached into `TabID.id` (which is `internal` in bonsplit), accessible only inside the bonsplit module via `@testable`. Local `./scripts/reload.sh --tag` builds the main app but not the test target, which is why the issue slipped through locally. Compare TabIDs directly (TabID is Hashable) instead of unwrapping the underlying UUID. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Background-refresh live agent index; add Codex parity test Addresses two PR manaflow-ai#4888 review findings: - Greptile P1: `RestorableAgentSessionIndex.load()` performs blocking `sysctl(KERN_PROCARGS2)` per hook record (for live-PID filtering), which is N×2 syscalls on `@MainActor` per right-click within the TTL window. Replace the synchronous main-actor load with an off-main `Task.detached(priority: .utility)` refresh, keyed on a 1s freshness window. The provider reads the cached value synchronously and tolerates a slightly-stale snapshot — claude's `--resume`/`--fork-session` still works against the persisted transcript even if the cmux-recorded PID has died, so showing the menu item briefly for a recently-terminated session is benign. First right-click after a fresh Claude launch may miss the item until the background refresh completes (~hundreds of ms); subsequent SwiftUI body re-renders pick up the new snapshot. - CodeRabbit: add a Codex-parity test that drives the same context-menu dispatcher path with a Codex snapshot and asserts the sibling tab is created with the Codex `--fork-session` command. (The Claude-path test already asserted focus on the new tab.) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Trigger immediate UI refresh after live-index load Addresses PR manaflow-ai#4888 CodeRabbit follow-up: the previous static cache returned nil on the first call after a stale-out and relied on a later SwiftUI body refresh (hover/focus) to pick up the new index, which is why the first right-click could miss the menu item. Move the cache off the static slot and onto the Workspace instance as a `@Published` property. When the background `Task.detached` completes and writes the new index, `objectWillChange` fires on the workspace, ContentView re-renders, and bonsplit's TabBarView re-evaluates its context-menu state on the same frame — so "Fork Conversation" becomes visible the moment the index lands, without a second right-click. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Beep when Fork Conversation tab creation fails silently Greptile P1 (PR manaflow-ai#4888): the bonsplit `.forkConversation` handler discarded `forkAgentConversationToNewTab`'s return value with `_ = …`, so if `newTerminalSurface` ever returned nil (e.g. layout reject, workspace resource constraint) the click produced no visible result and no audio cue, even though every other early-exit in this action branch already calls `NSSound.beep()`. Match the existing convention. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Use shared singleton for live agent index across workspaces PR manaflow-ai#4888 CodeRabbit follow-up: the previous per-Workspace `@Published` cache meant each open workspace performed its own background load of `RestorableAgentSessionIndex.load()`, redundantly running the same JSON + per-PID work N times for N open workspaces. Replace with a single `SharedLiveAgentIndex.shared` actor-isolated singleton that loads once and serves every workspace; each Workspace subscribes to its `objectWillChange` in its initializer and forwards it as its own so the SwiftUI re-render path stays intact (ContentView re-renders → bonsplit's TabBarView re-evaluates Fork Conversation visibility on the same frame). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
…naflow-ai#4919) Adds four CLAUDE.md sections capturing engineering policies that are currently informal: Package architecture (ergonomic, no cycles, broad domain responsibilities, leaf-first extraction), File organization (one major type per file), Documentation (Swift-DocC triple-slash on every public symbol in Packages/), and Test framework (Swift Testing default for new tests, XCUITest for UI tests only). Adds .cursor/rules/main.mdc so Cursor CLI picks up the same CLAUDE.md ruleset that Claude Code reads directly and Codex CLI reads through the existing AGENTS.md -> CLAUDE.md symlink. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add cmd-click Markdown path regression coverage * Open Markdown cmd-clicks in Markdown viewer by default * Update Markdown routing subtitle translations * Handle absolute Markdown path links with punctuation * Fix command-click fallback path normalization * Align Markdown routing settings subtitle --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
…manaflow-ai#4926) This reverts commit 370c412. Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Improve macOS CI runner fallbacks * Harden release-build fallback on hosted macOS --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add TypeScript preview regression test * Resolve textual ts files as source previews * Fix ambiguous ts media sniffing * Stabilize ts preview sniffing across UTType environments * Tighten ts text preview sniffing * Allow UTF-8 BOM in text preview sniff * Preserve ANSI text preview sniffing * Cover nul byte ts preview sniffing * Handle m2ts preview sniffing --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add browser keyboard hit-test regression * Skip browser hit testing during key dispatch * Share window input routing for hit tests * Keep scroll out of tab pass-through routing * Preserve no-event workspace drop hit testing * Preserve appKit browser portal routing * Drop unused input routing helpers * Move window input routing context * Remove unused routing context wrappers --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add failing open-with menu tests * Fix file preview open-with menu * Address open-with review feedback --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Add cmux diff CodeView command * Match Diffs CodeView styling * Respect Ghostty themes in cmux diff * Lower cmux diff default font size * Stabilize cmux diff sticky headers * Add git sources to cmux diff * Polish cmux diff viewer controls * Use Pierre file tree in diff viewer * Address diff viewer closeout feedback * Fix diff viewer warning budget * Fix diff viewer last-turn closeout issues * Address remaining diff viewer review feedback * Bundle diff viewer assets * Clean diff source error messages * Fix diff viewer closeout gaps * Honor diff viewer Ghostty font size * Localize bundled diff viewer labels * Gate nested diff baselines * Disable color in git diff viewer sources * Fix diff target selection and branch base * Fix no-focus diff selection and asset races * Fix diff viewer theme lookup after main merge * Polish diff viewer source closeout * feat: add diff viewer repo navigation * fix: split browser panel view body * fix: localize diff viewer command title * fix: detach diff viewer palette launch * fix: avoid new browser onChange warning * fix: keep last-turn untracked deletions diffable * fix: serve diff viewer from trusted app scheme * fix: keep diff viewer scheme inside browser * fix: sort diff viewer file tree input * fix: close diff viewer review gaps * fix: harden diff viewer closeout cases * fix: compile raw git blob helper * fix: keep diff viewer repo targets source-specific * fix: open diff viewer when selected source is empty * fix: avoid probing non-repo diff siblings * fix: close diff viewer review findings * test: avoid waiting for absent diff open * fix: share diff viewer trust root * fix: preserve empty last-turn source * fix: allow diff viewer wasm highlighter * perf: bound diff viewer deferred targets * test: make diff viewer payload extraction robust * fix: keep last-turn untracked snapshots out of git * fix: retain command palette diff launcher * fix: harden last-turn untracked snapshots * fix: align diff viewer codeview lifecycle * fix: match diffshub diff viewer scrolling * fix: stream diff viewer patches * fix: align diff viewer chrome styling * fix: repair diff viewer scheme test * fix: split diff viewer assets and stabilize large diffs * fix: tighten diff viewer source switching * test: assert diffhub patch sidecar content * fix: improve diff viewer large patch rendering * fix: address diff viewer review cleanup * Speed up diff viewer highlighting * Stabilize diff viewer sticky headers * Fix diff viewer sidecar test assertions * Tame WebKit sticky diff headers * Keep diff viewer scheme in app when browser is disabled * Clarify diff command help flags * Secure diff viewer temp directory * Sanitize diff viewer error copy * Harden diff viewer collapse and snapshots * Preserve last-turn baselines on duplicate hooks * Keep duplicate prompt hooks idempotent * Serialize diff viewer scheme task cancellation * Avoid type erasure in browser panel body * Serve diff viewer from loopback origin * Keep diff viewer loopback URLs temporary * Align diff viewer streaming with Diffshub * Use event-driven diff viewer pending loads * Bound diff viewer pending waits * Fix streamed diff tree selection * Retry deferred diff waits until ready * Stream trusted remote diff viewer patches * Test remote diff streaming manifest * Route cmux diff before path fallback * Stabilize diff viewer sticky headers * Improve diff viewer streaming performance * Keep diff viewer URLs out of browser history * Fix diff viewer closeout review issues * Fix quoted last-turn untracked diff paths * Fix diff viewer restore and socket env leaks * Prefetch trusted PR diffs for viewer performance * Treat loopback alias diff URLs as temporary * Bypass remote proxy for diff viewer panes * test: cover unborn last-turn baselines * fix: baseline unborn repos against empty tree * fix: align diff viewer model with DiffHub * fix: wait for deferred diff pages without polling * fix: retry deferred diff wait on transient failure * fix: avoid rebuilding diff tree entries * fix: skip unchanged tree status refreshes * fix: refresh changed diff tree stats * fix: mount diff viewer with first batch * Match DiffHub CodeView item stream * Fix diff viewer review regressions * Bound deferred diff viewer waits --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
* Expose FeedSidebar launch activation failures * Run E2E xcodebuild in GUI bootstrap --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
…unner-guard Guard E2E Depot runner identity
* Unmask right sidebar chrome UI tests * Fix right sidebar chrome hit-target assertions --------- Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
Merges 83 upstream commits. Notable conflict resolutions: - Follow upstream's removal of the right-sidebar History tab (manaflow-ai#4785): dropped sidebar History across the shortcut/focus/command-palette/tool-panel code, schema, and pbxproj, and deleted HistoryPanelView.swift and AppDelegate+HistoryPane.swift. Preserved the fork's Source Control tab and the separate menu-bar focus/closed-item history. - FilePreviewPanel: adopt upstream's content-sniffing approach for .ts files (TypeScript vs MPEG transport stream) over the fork's knownTextFile path. - project.pbxproj: union of upstream entries plus genuine fork-only entries (CodeViewer/SourceControl/CommandPalette file search families). - vendor/bonsplit -> 082bf66 (adds the Fork Conversation tab action that upstream's Workspace.swift now requires). Debug build verified to compile.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Merges 83 upstream commits (
manaflow-ai/cmux) into the fork. Debug build verified to compile (BUILD SUCCEEDED).Conflict resolutions
HistoryPanelView.swiftandAppDelegate+HistoryPane.swift. Preserved the fork's Source Control tab and the separate menu-bar focus/closed-item history..tsfiles (TypeScript vs MPEG transport stream) over the fork'sknownTextFilepath.082bf66— upstream pointer, which adds theforkConversationtab action that upstream'sWorkspace.swiftnow requires.ghosttyunchanged at176bd550f.Notes
Resources/Localizable.xcstrings(unused, harmless); the file was left as auto-merged.Test plan
.tsfiles open as text, not media🤖 Generated with Claude Code