Skip to content

Add extension browser pane - #5053

Merged
azooz2003-bit merged 3 commits into
mainfrom
feat-extension-browser-tab
May 31, 2026
Merged

azooz2003-bit merged 3 commits into
mainfrom
feat-extension-browser-tab

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented May 31, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a sidebar ExtensionKit browser panel tab.
  • Sizes the native ExtensionKit browser so the toggle column remains visible in normal panes.
  • Uses a compact localized fallback only when the pane is too constrained to render the browser usefully.

Validation

  • git diff --check
  • jq empty Resources/Localizable.xcstrings
  • ./scripts/reload.sh --tag extux --launch --swift-frontend-workaround

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.


Summary by cubic

Adds a Sidebar Extensions browser as a pane tab, replacing the floating utility window. Polishes layout with adaptive insets, a compact “Open larger” message, and click-to-focus for a better experience in narrow panes.

  • New Features

    • New PanelType.extensionBrowser and CMUXSidebarExtensionBrowserPanel rendered inside the pane.
    • App entry point openSidebarExtensionBrowser(from:title:) to open from menu or host view anchor.
    • Adaptive container: prefers wider width, adjusts horizontal/vertical insets, and hides the browser to show a centered, localized compact label when below 600×420.
    • UI polish: more opaque card background with a subtle border; compact label supports wrapping.
    • Localization: added sidebar.extensions.browser.compact for en and ja.
    • Workspace wiring for tab creation/focus, analytics identifiers, history title, and command palette keywords; unit test ensures the tab is created and focused.
  • Refactors

    • Replaced floating panel presenter with makeViewController(title:); present(from:title:) is unavailable to enforce the pane-tab flow.
    • PanelContentView now fills available space; file path header spacing and padding adjusted.

Written for commit 4eb4d29. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added an extension browser panel to the sidebar with support for both compact and expanded viewing modes for flexible space management.
    • Localization added in English and Japanese for the new sidebar extension browser functionality.

@vercel

vercel Bot commented May 31, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment May 31, 2026 4:57pm
cmux-staging Building Building Preview, Comment May 31, 2026 4:57pm

@coderabbitai

coderabbitai Bot commented May 31, 2026 •

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Failed to post review comments

📝 Walkthrough

Walkthrough

Adds a SwiftUI/AppKit sidebar panel surface for the extension browser, featuring a card-styled container with responsive layout constraints, dynamic compact/full mode toggling, and integration into the panel rendering system with English and Japanese localization for the compact layout label.

Changes

Extension Browser Panel UI Implementation

Layer / File(s) Summary
Panel ownership and view wrapper
Sources/CMUXSidebarExtensionBrowserPanel.swift (lines 1–63)
CMUXSidebarExtensionBrowserPanel creates and owns the browser view controller, handles focus by setting first responder, and provides lifecycle methods. CMUXSidebarExtensionBrowserPanelView wraps it as NSViewControllerRepresentable, managing container construction and browser attachment through SwiftUI lifecycle callbacks.
Container UI, layout, and attachment logic
Sources/CMUXSidebarExtensionBrowserPanel.swift (lines 65–307)
CMUXSidebarExtensionBrowserContainerViewController builds an AppKit hierarchy with card styling, compact label, and event wiring. Browser attachment conditionally reparents the view controller and manages constraints. Layout updates compute visible bounds, calculate inset/width dimensions via breakpoints, refresh styling, and toggle compact vs. full mode. Constants and sizing helpers define dimensions, corner radius, and colors.
PanelContentView rendering and system integration
Sources/Panels/PanelContentView.swift (lines 104–129)
PanelContentView handles .extensionBrowser by downcasting and rendering the panel view with focus wiring and unconstrained frame. Drop target installation includes .extensionBrowser as an eligible panel type.
Localization for compact layout label
Resources/Localizable.xcstrings (lines 166995–167011)
Adds sidebar.extensions.browser.compact entry with English and Japanese translations for the compact mode label.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • manaflow-ai/cmux#5038: Complements the pane-tab wiring for the extension browser surface that this PR provides the panel UI implementation for.

Poem

A card springs forth with rounded grace,
Resizing bounds within its place,
AppKit and SwiftUI entwine,
The browser panel looks divine,
Japanese whispers "大きく開く" shine! 📦✨


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (2 errors, 1 warning)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error New 'sidebar.extensions.browser.compact' string catalog entry only has 2 locales (en, ja) but catalog supports 20 locales. Missing 18 translations. Add translations for all 20 locales to 'sidebar.extensions.browser.compact' in Resources/Localizable.xcstrings matching existing catalog coverage.
Cmux Architecture Rethink ❌ Error Split UI lifecycle ownership: Panel owns browserViewController while Container manages its AppKit parent with transient reparenting, leaving browser orphaned in dismantleNSViewController. Consolidate lifecycle: either Container creates/owns browserViewController, or Panel manages all AppKit parent state without transient reparenting between separate controllers.
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (15 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add extension browser pane' directly and clearly summarizes the main change—adding a new sidebar extension browser panel tab as documented in the objectives and raw summary.
Description check ✅ Passed The description is substantially complete with a clear summary section and validation steps, though it deviates from the template by omitting Testing, Demo Video, Review Trigger, and Checklist sections.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed CMUXSidebarExtensionBrowserPanel and container are explicitly @MainActor-isolated UI types. No implicit isolation, Sendable without isolation, or background context access issues detected.
Cmux Swift Blocking Runtime ✅ Passed No blocking synchronization primitives detected. Code uses standard AppKit/SwiftUI patterns without semaphores, sleeps, locks, waits, or polling.
Cmux No Hacky Sleeps ✅ Passed PR modifies only Swift and resource files; rule applies only to TypeScript, JavaScript, shell, and build/runtime scripts. Zero such files changed.
Cmux Algorithmic Complexity ✅ Passed No algorithmic complexity violations found. Code contains only O(1) UI initialization and constraint management with no loops, collection scans, or unbounded operations on scalable collections.
Cmux Swift Concurrency ✅ Passed No legacy async patterns introduced. ObservableObject conformance is required by Panel protocol (empty conformance). Closures are for SwiftUI-AppKit boundary callbacks (allowed case).
Cmux Swift @Concurrent ✅ Passed No concurrency rule violations found. Code has no async functions, @concurrent misuse, or heavy operations without proper isolation. All work is UI-bound and properly annotated.
Cmux Swift File And Package Boundaries ✅ Passed 307-line new file has clear single responsibility (UI panel), no inappropriate mixing, correctly placed in app target as AppKit/SwiftUI glue per allowed cases.
Cmux Swift Logging ✅ Passed No logging violations found. Code adds 307 lines without using print, debugPrint, dump, NSLog, or ad hoc file/stdout logging.
Cmux User-Facing Error Privacy ✅ Passed All user-facing strings are safe UI labels; no vendor names, credentials, errors, or implementation details exposed.
Cmux Swiftui State Layout ✅ Passed ObservableObject conformance required by Panel protocol. No @Published, state mutations, GeometryReader layout, or lazy view issues. Proper AppKit bridge pattern.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds sidebar panel/tab via NSViewControllerRepresentable with NSViewController—no new standalone windows. Sidebar tabs are allowed per review-bot-rules.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-extension-browser-tab

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…r-tab

# Conflicts:
#	Resources/Localizable.xcstrings
#	Sources/CMUXSidebarExtensionBrowserPanel.swift
#	Sources/Panels/PanelContentView.swift
@greptile-apps

greptile-apps Bot commented May 31, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR moves the ExtensionKit browser from a floating panel into a sidebar pane tab, adding CMUXSidebarExtensionBrowserPanel, an adaptive container view controller, and wiring in PanelContentView. The layout now stretches to fill the pane height and shows a compact fallback label when the pane is below a minimum usable size.

  • New panel type: PanelType.extensionBrowser rendered by CMUXSidebarExtensionBrowserPanelView, which wraps a native NSViewController in an auto-layout card that tracks pane bounds and shows a localized "Open larger" message when space is insufficient.
  • Layout refactor: Removed fixed-height constraint in favor of top/bottom anchors that pin the card to the pane edges, updated inset helpers for narrow panes, and revised PanelFilePathHeader spacing/sizing constants.
  • String catalog: Added three new localization keys (sidebar.extensions.browser.title, sidebar.extensions.browser.compact, sidebar.extensions.manage); the compact key covers only en and ja while the title and manage keys include the full 19-locale catalog.

Confidence Score: 4/5

Safe to merge after addressing the compact-label flash; the remaining gap is the incomplete locale coverage for sidebar.extensions.browser.compact already called out in the prior review thread.

The compact-mode visibility check uses raw visibleRect dimensions, which are zero on the first onMoveToWindow callback, causing the browser content to be hidden and the "Open larger" fallback label to appear briefly every time the panel is opened. This is a present, observable display defect on the changed code path. The locale gap for the compact string (17 missing translations) is a real user-facing regression for those locales. Both issues live in the newly introduced code; everything else — the layout constraint refactor, the panel wiring, and the PanelFilePathHeader cleanup — is straightforward.

Sources/CMUXSidebarExtensionBrowserPanel.swift (isCompact guard) and Resources/Localizable.xcstrings (compact string locale coverage)

Important Files Changed

Filename Overview
Sources/CMUXSidebarExtensionBrowserPanel.swift New panel class and container view controller; layout logic is sound but the compact-mode check reads raw visibleRect without the same zero-fallback used by the constraint updater, which may flash the compact label briefly on first layout.
Resources/Localizable.xcstrings Adds three new keys; sidebar.extensions.browser.compact ships only en + ja translations while the other two new keys cover the full 19-locale catalog — users in 17 locales will see raw English fallback in the compact state.
Sources/Panels/PanelContentView.swift Wires extensionBrowser into the panel content switch and adds .frame(maxWidth/Height: .infinity); also inlines PanelFilePathHeader spacing constants — straightforward and safe.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["PanelContentView\n(SwiftUI)"] -->|"case .extensionBrowser"| B["CMUXSidebarExtensionBrowserPanelView\n(NSViewControllerRepresentable)"]
    B -->|makeNSViewController| C["CMUXSidebarExtensionBrowserContainerViewController"]
    B -->|updateNSViewController| C
    B -->|dismantleNSViewController| D["detachBrowserForTransientReparent()"]

    C --> E["RootView (NSView)\nonLayout / onMouseDown / onMoveToWindow"]
    C --> F["FocusCardView\nonMouseDown → onRequestPanelFocus"]
    F --> G["contentView (NSView)\n4-edge pinned to cardView"]
    F --> H["compactLabel (NSTextField)\ncentered in cardView"]
    G --> I["browserViewController.view\n4-edge pinned to contentView"]

    E -->|"layout()"| J{"updateLayoutForCurrentBounds()"}
    J -->|"layoutWidth/Height > minimumUsable"| K["contentView visible\ncompactLabel hidden"]
    J -->|"below minimum OR zero bounds"| L["contentView hidden\ncompactLabel shown\n'Open larger'"]

    C --> M["CMUXSidebarExtensionBrowserPanel\n(ObservableObject, Panel)"]
    M -->|"browserViewController"| C
Loading

Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

Comment on lines 995 to 1011
await withCheckedContinuation { continuation in
continuationBox.set(continuation)
Task {
await continuationBox.set(continuation)
}
withObservationTracking {
applyModernExtensionState(monitor.state)
} onChange: {
continuationBox.resume()
Task {
await continuationBox.resume()
}
}
}
} onCancel: {
continuationBox.cancel()
Task {
await continuationBox.cancel()
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unstructured fire-and-forget Tasks wrapping actor calls

Task { await continuationBox.set(continuation) }, Task { await continuationBox.resume() }, and Task { await continuationBox.cancel() } are all unstructured tasks with no parent in the Swift concurrency task tree. They are not cancelled when the enclosing Task is cancelled, and any errors they surface are silently dropped. Per the cmux-swift-concurrency-modernization rule, actor hops from non-isolated callbacks should use Task only when there is no structured alternative — but the lifecycle of these Tasks should be tied to the owning context. Consider capturing the Task references (or using withCheckedContinuation's structured cancellation directly) so the actor operations remain bound to the observation loop's lifetime.

Rule Used: Flag new legacy async patterns in cmux-owned Swift... (source)

Comment on lines +270 to +271
let isCompact = visibleBounds.width < Self.minimumUsableWidth ||
visibleBounds.height < Self.minimumUsableHeight

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 The compact-mode check reads raw visibleBounds without the same zero-fallback that the constraint update code applies. When viewDidMoveToWindow fires before the first Auto Layout pass, rootView.visibleRect returns CGRect.zero, so both comparisons evaluate as true (0 < 600, 0 < 420). This sets contentView.isHidden = true and compactLabel.isHidden = false on every initial window attachment, producing a visible flash of the "Open larger" label before the real layout arrives.

Suggested change
let isCompact = visibleBounds.width < Self.minimumUsableWidth ||
visibleBounds.height < Self.minimumUsableHeight
let isCompact = layoutWidth > 0 && layoutHeight > 0 && (
layoutWidth < Self.minimumUsableWidth ||
layoutHeight < Self.minimumUsableHeight
)

@azooz2003-bit
azooz2003-bit merged commit 440f734 into main May 31, 2026
20 checks passed
hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request Jun 1, 2026
- Add Send Ctrl-F to Terminal passthrough (manaflow-ai#5011, force-stop CC agents)
- Fix sidebar worktree spawn worktree-setup-as-input bug (manaflow-ai#5032)
- Add boundary-aware ranking layer for command-palette fuzzy search
- Open extension browser as pane tab + polish (manaflow-ai#5053)
- Move sidebar kind selection to titlebar menu, fix clipped tooltip
  and floor sidebar width (manaflow-ai#5045)
- Extract CmuxFoundation package — modular refactor wave 1 (manaflow-ai#5055)
- Center empty sidebar-extension state, fade host bottom edge (manaflow-ai#5057)
- Align titlebar accessory hints (manaflow-ai#5059)
- Restore sidebar minimum width (manaflow-ai#5062)

Conflicts resolved:
- cmux.xcodeproj/project.pbxproj: merge fork's CMUXSettingsCore +
  CMUXSessionDaemon package refs with upstream's new CmuxFoundation
  package reference and product dependency.

This branch was successfully deployed

1 active deployment
Preview – cmux — 4eb4d29b Deployed May 31, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant