Skip to content

Replace sidebar extension kit contract - #4994

Merged
azooz2003-bit merged 45 commits into
mainfrom
feature-sidebar-extension-kit
May 30, 2026
Merged

azooz2003-bit merged 45 commits into
mainfrom
feature-sidebar-extension-kit

Conversation

@azooz2003-bit

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

Copy link
Copy Markdown
Collaborator

Summary

  • Replaces the old sidebar extension contract with a CMUX-prefixed snapshot/action API in CmuxExtensionKit, while leaving the existing example sidebar package intact.
  • Adds CMUXExtensionClient with registry/session primitives, ExtensionFoundation discovery for com.manaflow.cmux.sidebar, and an EXHostViewController SwiftUI bridge for scene sidebar.
  • Adds the “CMUX Extensions” sidebar provider in the app with localized loading/empty/error states and a tagged build path for dogfood.
  • Organizes the new kit/client source into focused folders and one public top-level type per file where practical.

Acceptance criteria

  • Default sidebar remains available and unchanged.
  • Existing Cmux extension sidebar examples remain in the repo and compile/test.
  • A sidebar extension can target extension point com.manaflow.cmux.sidebar and scene sidebar.
  • With no installed sidebar extension, the app shows a localized empty state instead of failing.

Verification

  • swift test (Packages/CmuxExtensionKit)
  • swift test (Packages/CMUXExtensionClient)
  • swift package clean && swift test (Examples/CmuxExtensionSidebarExamples)
  • ./scripts/check-pbxproj.sh
  • ./scripts/reload.sh --tag extkit
  • GitHub Actions: activation-session, release-build, remote-daemon-tests, tests, tests-build-and-lag, ui-regressions, web-db-migrations, web-typecheck, workflow-guard-tests
  • Vercel: cmux and cmux-staging previews passed
  • Review bots: Greptile pass, CodeRabbit pass/skipped after follow-up commit

Summary by CodeRabbit

  • New Features
    • Added sidebar extension discovery and an "Installed Extensions" provider to find and host third‑party sidebar extensions, with in‑app UI for loading, empty/error states, and selection.
    • Introduced host-side extension session/registry, stable sidebar snapshot/workspace model, action handling, and stricter manifest validation for safer extension integration.
  • Documentation
    • Updated extension kit and client READMEs describing the sidebar contract and host responsibilities; added localized sidebar strings.
  • Tests
    • New unit tests and sample sidebar extension demonstrating the contract and behaviors.

Review Change Stack

@vercel

vercel Bot commented May 29, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cmux Error Error May 30, 2026 6:25pm
cmux-staging Building Building Preview, Comment May 30, 2026 6:25pm

@coderabbitai

coderabbitai Bot commented May 29, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR refactors the CMUX extension system to a snapshot/action contract with API versioning and manifest validation, adds a CMUXExtensionClient host package (registry, discovery, session, host view), and integrates discovery, UI rendering, and localization into the main app.

Changes

CmuxExtensionKit Contract Refactor

Layer / File(s) Summary
API versioning, manifest, and scope contracts
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Common/CMUXExtensionAPIVersion.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionKind.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionManifest.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionScope.swift
Introduces CMUXExtensionAPIVersion with comparable major/minor components; adds CMUXExtensionKind enum (.sidebar); defines CMUXExtensionManifest with id, displayName, kind, minimumAPIVersion, and requestedScopes; introduces CMUXExtensionScope enum for workspace metadata, paths, notifications, and network ports.
Snapshot and workspace data models
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarSnapshot.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarWorkspace.swift
CMUXSidebarSnapshot stores API version, sequence, window/selected workspace IDs, and workspaces array. CMUXSidebarWorkspace encodes identity, title, detail, pinned state, paths, git branch, unread count, latest notification, listening ports, and pull request URLs with sensible defaults.
Action model and extension protocol
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarAction.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXExtensionActionResult.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarExtension.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarHostClient.swift
CMUXSidebarAction defines select/close workspace and open URL actions. CMUXExtensionActionResult wraps acceptance and optional message. CMUXSidebarExtension protocol requires async initial snapshot and action handling. CMUXSidebarHostClient encapsulates async snapshot and dispatch closures.
Manifest validation and error types
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Validation/CMUXExtensionValidationError.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Validation/CMUXExtensionValidator.swift
CMUXExtensionValidationError reports empty identifier/displayName, unsupported kind, and unsupported API version. CMUXExtensionValidator.validateSidebarManifest trims whitespace, enforces .sidebar kind, and validates minimum API version compatibility.
Provider types and sidebar provider protocol
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionLocalizedText.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProviderID.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProviderDescriptor.swift, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProvider.swift
Adds localization wrapper, provider identifier constant, provider descriptor model with defaultWorkspaces, and provider protocol exposing descriptor.
Compatibility layer snapshot models and render updates
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionCompatibility.swift
Removes custom Codable in render model, removes render context current, adds CmuxExtensionCommandResult, and compatibility snapshot/workspace structs with expanded fields; adds pullRequest tab case.
Tests and documentation
Packages/CmuxExtensionKit/README.md, Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift
README now describes a zero-dependency stable snapshot contract and restricted action channel. Tests migrated to Testing framework with three focused tests (snapshot round-trip and manifest validation acceptance/rejection).

CMUXExtensionClient Host Package

Layer / File(s) Summary
Package manifest and documentation
Packages/CMUXExtensionClient/Package.swift, Packages/CMUXExtensionClient/README.md
Adds CMUXExtensionClient package manifest (macOS 14+) and README describing manifest validation, registry, session, discovery, and ExtensionKit host view integration.
Extension point, record, and error definitions
Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/ExtensionPoint/CMUXSidebarExtensionPoint.swift, Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Discovery/CMUXInstalledSidebarExtension.swift, Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXSidebarExtensionRecord.swift, Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXExtensionClientError.swift
Defines sidebar extension point identifier and default scene ID; CMUXInstalledSidebarExtension value type; CMUXSidebarExtensionRecord pairing manifest with host-provided flag; and CMUXExtensionClientError for duplicates/missing records.
Registry validation and session management
Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXSidebarExtensionRegistry.swift, Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Session/CMUXSidebarExtensionSession.swift
Registry validates records via CMUXExtensionValidator, rejects duplicates, stores deterministically and exposes lookup. Session actor validates manifest on init, caches snapshots via refreshSnapshot(), and forwards actions via perform(_:).
Extension discovery and host view integration
Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Discovery/CMUXSidebarExtensionDiscovery.swift, Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Hosting/CMUXSidebarExtensionHostView.swift
Discovery queries AppExtensionIdentity matching and maps to CMUXInstalledSidebarExtension sorted by localizedName. Host view wraps EXHostViewController and avoids redundant reconfiguration via Coordinator-held configuration key.
Extension client tests
Packages/CMUXExtensionClient/Tests/CMUXExtensionClientTests/CMUXExtensionClientTests.swift
Tests registry ordering and duplicate rejection, extension point constants, and session snapshot/dispatch behavior using an ActionRecorder test actor.

Main App Sidebar Extension Integration

Layer / File(s) Summary
Build dependencies and project configuration
cmux.xcodeproj/project.pbxproj
Adds CMUXExtensionClient package product to cmux target dependencies and frameworks; adds local package reference and product mapping; includes CMUXInstalledExtensionSidebarHostView.swift in project and target sources.
Sidebar provider selection and UI integration
Sources/ContentView.swift
Adds hostedExtensionsProviderId and hostedExtensionsDescriptor to provider list and includes it in descriptors.
Extension discovery and conditional rendering
Sources/CMUXInstalledExtensionSidebarHostView.swift, Sources/ContentView.swift
Adds CMUXInstalledExtensionSidebarHostView which discovers installed extensions on appear, shows host view when found, or localized empty/error states otherwise. VerticalTabsSidebar conditionally renders host view when hosted provider is selected.
Localized UI strings
Resources/Localizable.xcstrings
Adds localized strings (provider title/subtitle, loading, empty title/detail, error) with English and Japanese translations.
Sample extension examples and workspace updates
Examples/CMUXSampleSidebarExtension/..., cmux.xcworkspace/contents.xcworkspacedata
Adds CMUXSampleSidebarExtension package, sample extension implementation, SwiftUI views, sample snapshot data, tests, and updates workspace to reference the examples and package.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • manaflow-ai/cmux#4662: Modifies sidebar provider set and selection logic in Sources/ContentView.swift, related to hosted provider wiring.
  • manaflow-ai/cmux#4834: Workspace/package entries changes that also modify cmux.xcworkspace/contents.xcworkspacedata.
  • manaflow-ai/cmux#4309: Prior CmuxExtensionKit sidebar prototype changes that this PR replaces/refactors.

Poem

🐰 Hopping through snapshots bright,

Manifests trimmed and versions right,
Hosts discover, sessions hum,
Sidebar extensions welcome home. 🥕

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature-sidebar-extension-kit

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.

@azooz2003-bit
azooz2003-bit force-pushed the feature-sidebar-extension-kit branch from 69570d6 to 1cf0071 Compare May 29, 2026 18:07
@azooz2003-bit
azooz2003-bit marked this pull request as ready for review May 29, 2026 18:36
@azooz2003-bit

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@greptile-apps

greptile-apps Bot commented May 29, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces the old sidebar extension contract with a new CMUX-prefixed snapshot/action API (CmuxExtensionKit), adds a host-side CMUXExtensionClient package with registry/session/discovery primitives, and integrates an "Installed Extensions" sidebar provider into the main app with permission grants, XPC connection management, and localized empty/error states.

  • New CmuxExtensionKit contract: Adds CMUXSidebarSnapshot, CMUXSidebarAction, CMUXSidebarExtensionConnection (lock-guarded, generation-fenced XPC transport), and CmuxSidebarExtensionScene/CmuxSidebarHost typed APIs for extension authors; old types preserved via CmuxExtensionCompatibility.swift.
  • New CMUXExtensionClient package: Adds CMUXSidebarExtensionRegistry, CMUXSidebarExtensionSession (actor), CMUXSidebarExtensionDiscovery, and CMUXSidebarExtensionHostView (NSViewControllerRepresentable for EXHostViewController), correctly guarding configuration reassignment.
  • App integration: CMUXInstalledExtensionSidebarHostView (1,372 lines) hosts the extension scene via XPC, manages manifest validation, scope grants, and localized UI states; ContentView wires the hosted-extensions provider into the sidebar selection.

Confidence Score: 4/5

The new extension contract and XPC transport are structurally sound, but two previously flagged defects in CMUXInstalledExtensionSidebarHostView — the deactivation path that silently freezes the sidebar and the data race in CMUXSidebarExtensionConnection — remain unaddressed.

The registry, session actor, and EXHostViewController bridge are well-isolated and correctly implemented. The deactivation closure still does not clear identity, so an XPC crash leaves the sidebar frozen with no error state visible; and CMUXSidebarExtensionConnection still uses @unchecked Sendable with mutable vars updated from both the caller context and XPC background-queue handlers. Both were raised in the prior review round and are present in the current diff unchanged.

Sources/CMUXInstalledExtensionSidebarHostView.swift (deactivation path) and Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarExtensionConnection.swift (concurrency)

Important Files Changed

Filename Overview
Sources/CMUXInstalledExtensionSidebarHostView.swift New 1,372-line host view for installed extension sidebar; mixes grant model, persistence, SwiftUI UI, and XPC transport. Contains an onChange(of: snapshotProvider().sequence) that registers broad @Observable dependencies during body rendering.
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarExtensionConnection.swift Lower-level XPC transport for extension side; uses @unchecked Sendable with NSLock-guarded state. Previously flagged data race concern is still present.
Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Hosting/CMUXSidebarExtensionHostView.swift SwiftUI NSViewControllerRepresentable bridge for ExtensionKit; updateNSViewController now correctly guards configuration reassignment with an equality check on HostConfigurationKey.
Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Session/CMUXSidebarExtensionSession.swift Clean actor-isolated session mediating snapshot refresh and action dispatch with correct scope filtering.
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CmuxSidebarHost.swift Well-structured @MainActor typed command channel; CmuxSidebarActionReplyGate correctly uses NSLock to serialize continuation hand-off and cancellation.
Resources/Localizable.xcstrings Large addition of sidebar extension UI strings; all new keys carry only en and ja, leaving 18 of 20 supported locales falling back to English (unresolved from prior review).
Sources/ContentView.swift Adds CMUXInstalledExtensionSidebarHostView integration and titlebar sidebar-edge sync; changes are focused and additive.

Sequence Diagram

sequenceDiagram
    participant App as ContentView
    participant HostView as CMUXInstalledExtensionSidebarHostView
    participant XPC as CMUXSidebarExtensionHostXPC
    participant EKView as CMUXSidebarExtensionHostView
    participant ExtProc as Extension Process
    participant Conn as CMUXSidebarExtensionConnection
    App->>HostView: snapshotProvider / snapshotUpdateToken
    HostView->>HostView: observeExtensionAvailability()
    HostView->>EKView: identity
    EKView->>ExtProc: EXHostViewController.configuration
    ExtProc-->>EKView: hostViewControllerDidActivate
    EKView-->>HostView: onConnection(NSXPCConnection)
    HostView->>XPC: attach(connection, bundleIdentifier)
    XPC->>ExtProc: requestExtensionManifest
    ExtProc-->>XPC: manifest payload
    XPC->>XPC: validateSidebarManifest / applyManifest
    XPC-->>HostView: onGrantChanged(effectiveGrant)
    XPC->>ExtProc: sidebarSnapshotDidChange (push)
    ExtProc->>Conn: accept(NSXPCConnection)
    Conn->>XPC: requestSidebarSnapshot
    XPC-->>Conn: snapshot payload
    Conn-->>ExtProc: onSnapshot(CMUXSidebarSnapshot)
    ExtProc->>Conn: perform(CMUXSidebarAction)
    Conn->>XPC: performSidebarAction
    XPC-->>Conn: CMUXExtensionActionResult
Loading

Reviews (25): Last reviewed commit: "Give UI regressions cold builds more tim..." | Re-trigger Greptile

Comment on lines +144 to +149
public func updateNSViewController(_ viewController: EXHostViewController, context: Context) {
viewController.configuration = EXHostViewController.Configuration(
appExtension: identity,
sceneID: sceneID
)
}

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 updateNSViewController unconditionally recreates and assigns EXHostViewController.Configuration on every SwiftUI update pass. Apple's ExtensionKit documentation notes that assigning a new configuration while a connection is already established can interrupt the running extension scene. Since identity and sceneID are let constants that never change for a given struct instance, the update should be a no-op when neither value has actually changed.

Suggested change
public func updateNSViewController(_ viewController: EXHostViewController, context: Context) {
viewController.configuration = EXHostViewController.Configuration(
appExtension: identity,
sceneID: sceneID
)
}
public func updateNSViewController(_ viewController: EXHostViewController, context: Context) {
// Only update if the extension or scene has changed to avoid interrupting
// an already-established ExtensionKit connection.
let current = viewController.configuration
if current?.appExtension.bundleIdentifier != identity.bundleIdentifier
|| current?.sceneID != sceneID {
viewController.configuration = EXHostViewController.Configuration(
appExtension: identity,
sceneID: sceneID
)
}
}

Rule Used: Flag SwiftUI changes that can cause stale state, b... (source)

Comment on lines +122 to +132
public struct CMUXExtensionActionResult: Codable, Equatable, Sendable {
public var accepted: Bool
public var message: String?

private enum SocketCodingKeys: String, CodingKey {
case id
case title
case customDescription = "description"
case isPinned = "pinned"
case rootPath = "root_path"
case projectRootPath = "project_root_path"
case branchSummary = "branch_summary"
case remoteDisplayTarget = "remote_display_target"
case remoteConnectionState = "remote_connection_state"
case unreadCount = "unread_count"
case latestNotificationText = "latest_notification_text"
case latestSubmittedMessage = "latest_submitted_message"
case latestSubmittedAt = "latest_submitted_at"
case listeningPorts = "listening_ports"
case pullRequestURLs = "pull_request_urls"
case panelDirectories = "panel_directories"
case gitBranches = "git_branches"
public init(accepted: Bool, message: String? = nil) {
self.accepted = accepted
self.message = message
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let socketContainer = try decoder.container(keyedBy: SocketCodingKeys.self)
public static let accepted = CMUXExtensionActionResult(accepted: true)
}

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 Both the static let accepted and the stored property var accepted: Bool are named accepted on the same type. While this compiles, callers see two symbols with the same name and different types — result.accepted reads the Bool, while result == .accepted (or any expression context) resolves to the static instance. This kind of collision can make call-sites misleading: someone who writes guard result.accepted else { ... } means the bool, but a reader may interpret it as a membership check against the static sentinel. Rename the static factory or the bool property to eliminate the ambiguity.

Suggested change
public struct CMUXExtensionActionResult: Codable, Equatable, Sendable {
public var accepted: Bool
public var message: String?
private enum SocketCodingKeys: String, CodingKey {
case id
case title
case customDescription = "description"
case isPinned = "pinned"
case rootPath = "root_path"
case projectRootPath = "project_root_path"
case branchSummary = "branch_summary"
case remoteDisplayTarget = "remote_display_target"
case remoteConnectionState = "remote_connection_state"
case unreadCount = "unread_count"
case latestNotificationText = "latest_notification_text"
case latestSubmittedMessage = "latest_submitted_message"
case latestSubmittedAt = "latest_submitted_at"
case listeningPorts = "listening_ports"
case pullRequestURLs = "pull_request_urls"
case panelDirectories = "panel_directories"
case gitBranches = "git_branches"
public init(accepted: Bool, message: String? = nil) {
self.accepted = accepted
self.message = message
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let socketContainer = try decoder.container(keyedBy: SocketCodingKeys.self)
public static let accepted = CMUXExtensionActionResult(accepted: true)
}
public struct CMUXExtensionActionResult: Codable, Equatable, Sendable {
public var accepted: Bool
public var message: String?
public init(accepted: Bool, message: String? = nil) {
self.accepted = accepted
self.message = message
}
public static let success = CMUXExtensionActionResult(accepted: true)
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

coderabbitai[bot]
coderabbitai Bot previously requested changes May 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Packages/CMUXExtensionClient/README.md`:
- Line 11: Update the README to remove the stale claim that discovery and the
EXHostViewController bridge are future work and instead state that this PR
already implements third-party extension discovery and the EXHostViewController
bridge (see CMUXExtensionClient.swift), and briefly describe the current
exported surface for API and host lifecycle so integrators know these features
are available now.

In
`@Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXExtensionClient.swift`:
- Around line 7-150: Add Swift-DocC triple‑slash comments for every public
symbol in this file: place a concise summary before each public
enum/struct/actor/method/property and include `@param`, `@returns`, and `@throws`
clauses where applicable. Specifically add documentation for
CMUXSidebarExtensionPoint, CMUXSidebarExtensionRecord (and its init),
CMUXExtensionClientError, CMUXSidebarExtensionRegistry (init, records property,
record(id:)), CMUXSidebarExtensionSession (init, refreshSnapshot(), perform(_:),
extensionManifest, cachedSnapshot()), CMUXInstalledSidebarExtension (and its
init), CMUXSidebarExtensionDiscovery (init,
installedExtensions(extensionPointIdentifier:)), and
CMUXSidebarExtensionHostView (init(identity:sceneID:),
makeNSViewController(context:), updateNSViewController(_:context:)). Ensure each
doc comment is triple-slash (///) and includes a one-line summary plus
parameter/return/throws descriptions where relevant to satisfy the package DocC
requirement.

In
`@Packages/CMUXExtensionClient/Tests/CMUXExtensionClientTests/CMUXExtensionClientTests.swift`:
- Around line 1-71: Replace XCTest with Swift Testing: remove import XCTest and
add import Testing, convert the XCTestCase subclass CMUXExtensionClientTests
into a `@Suite` (e.g., `@Suite` struct CMUXExtensionClientTests) and change each
test method into an `@Test` func; replace XCTAssertEqual, XCTAssertThrowsError,
XCTAssertEqual(..., ...) and async assertions with the Testing macros (`#expect`,
try `#require`, etc.) and adapt the throwing/async assertions (e.g., the
duplicate-extension check and async refresh/perform flow) to use try
`#require/try` `#requireThrows` and `#expect`(...).toEqual(...) semantics; keep
references to the same symbols (CMUXSidebarExtensionRegistry initializer,
CMUXSidebarExtensionPoint.identifier/defaultSceneID,
CMUXSidebarExtensionSession.refreshSnapshot/perform/cachedSnapshot,
ActionRecorder actor) so tests map directly to the new Swift Testing APIs.

In `@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift`:
- Around line 175-179: The current check only compares
manifest.minimumAPIVersion.major to supportedAPIVersion.major and throws
CMUXExtensionValidationError.unsupportedMajorVersion; change the validation to
compare the full CMUXExtensionAPIVersion (major and minor) between
manifest.minimumAPIVersion and supportedAPIVersion (e.g., ensure requested <=
supported or otherwise incompatible), and throw an error variant that preserves
both the requested and supported full versions (or update
CMUXExtensionValidationError to include both CMUXExtensionAPIVersion values)
instead of only passing major numbers; update the validation logic where
manifest.minimumAPIVersion and supportedAPIVersion are used to perform the
full-version comparison and return the new error with both versions populated.

In
`@Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift`:
- Around line 1-59: Replace XCTest with the Swift Testing framework: change
"import XCTest" to "import Testing", convert the test case class "final class
CMUXExtensionKitTests: XCTestCase" into a test suite annotated with "`@Suite`"
(e.g., "struct CMUXExtensionKitTests"), and annotate each test function
(testSidebarSnapshotRoundTripsStableContract,
testManifestValidationAcceptsSidebarV1,
testManifestValidationRejectsUnsupportedMajorVersion) with "`@Test`". Replace
XCTest assertions with Testing assertions: use "try `#require`" for operations
that must not throw (e.g., encoding/decoding and validateSidebarManifest) and
use "`#expect`(...).toEqual(...)" for equality checks on CMUXSidebarSnapshot and
apiVersion, and use the Testing pattern for expected throws to assert
CMUXExtensionValidator.validateSidebarManifest throws
CMUXExtensionValidationError(.unsupportedMajorVersion(requested:2,supported:1))
when using CMUXExtensionAPIVersion(major:2, minor:0); keep references to
CMUXSidebarSnapshot, CMUXSidebarWorkspace, CMUXExtensionManifest,
CMUXExtensionValidator, CMUXExtensionValidationError, and
CMUXExtensionAPIVersion to locate the code.

In `@Sources/ContentView.swift`:
- Around line 13933-13998: The CMUXInstalledExtensionSidebarHostView struct is
making ContentView.swift too large; move CMUXInstalledExtensionSidebarHostView
into its own Swift file under Sources: create a new file, import SwiftUI, paste
the CMUXInstalledExtensionSidebarHostView struct (including its private
loadExtension() method) and keep references to CMUXSidebarExtensionHostView,
AppExtensionIdentity, CMUXSidebarExtensionPoint and SidebarWorkspaceScrollInsets
intact; ensure the new file is added to the same target in the project and
update any access control if needed (e.g., make the struct internal/public if
other files reference it).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f72560fe-38e2-4196-8084-67524b18af73

📥 Commits

Reviewing files that changed from the base of the PR and between 0c4539f and 1cf0071.

📒 Files selected for processing (13)
  • Packages/CMUXExtensionClient/Package.swift
  • Packages/CMUXExtensionClient/README.md
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXExtensionClient.swift
  • Packages/CMUXExtensionClient/Tests/CMUXExtensionClientTests/CMUXExtensionClientTests.swift
  • Packages/CmuxExtensionKit/README.md
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionCompatibility.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionPathFormatter.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionSidebarReducer.swift
  • Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift
  • Resources/Localizable.xcstrings
  • Sources/ContentView.swift
  • cmux.xcodeproj/project.pbxproj
💤 Files with no reviewable changes (2)
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionSidebarReducer.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionPathFormatter.swift

Comment thread Packages/CMUXExtensionClient/README.md Outdated
Comment thread Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift Outdated
Comment thread Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift Outdated
Comment thread Sources/ContentView.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXExtensionClient.swift`:
- Around line 151-153: The triple-slash DocC comments are placed between the
`@available` attribute and the declarations so DocC/SourceKit won't associate
them; move each leading /// comment block so it appears immediately above the
`@available`(...) attribute for both CMUXSidebarExtensionDiscovery and
CMUXSidebarExtensionHostView, ensuring the comment is directly adjacent to the
attribute before the public struct/class declaration so DocC correctly attaches
the documentation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: eb59a1b3-cc04-4c95-84b6-24faa6fbbf9d

📥 Commits

Reviewing files that changed from the base of the PR and between 1cf0071 and f69d418.

📒 Files selected for processing (9)
  • Packages/CMUXExtensionClient/README.md
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXExtensionClient.swift
  • Packages/CMUXExtensionClient/Tests/CMUXExtensionClientTests/CMUXExtensionClientTests.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
  • Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift
  • Resources/Localizable.xcstrings
  • Sources/CMUXInstalledExtensionSidebarHostView.swift
  • Sources/ContentView.swift
  • cmux.xcodeproj/project.pbxproj
💤 Files with no reviewable changes (1)
  • Sources/ContentView.swift

Comment on lines +151 to +153
@available(macOS 14.0, *)
/// Discovers installed sidebar extensions that match CMUX's ExtensionKit point.
public struct CMUXSidebarExtensionDiscovery {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

In Swift, does DocC / SourceKit recognize a documentation comment placed between an @available attribute and the declaration (attribute on the line above the doc comment)?

💡 Result:

No. Swift-DocC (and the underlying SourceKit-based doc-comment extraction) associates a documentation comment with the declaration immediately following it; therefore, a documentation comment placed between an @available attribute and the declaration will not be recognized as the symbol’s documentation comment. Apple’s WWDC guidance states that a doc comment “associate[s] the comment with the declaration immediately below it” [1]. Apple’s DocC documentation explains that documentation comments are “add[ed] … to the symbols” in source and then “DocC compiles those comments” into formatted documentation for those symbols [2]. Because an @available attribute is a token between the doc comment and the declaration, the “immediately below it” association does not hold [1], so the comment is not attached to the declaration for DocC. Recommended fix: place the doc comment directly above the declaration so it is the immediate leading trivia for that declaration (i.e., don’t insert @available between the doc comment and the declaration).

Citations:


Move Swift DocC triple-slash comments above @available attributes (both symbols)

The /// comments currently sit between @available(macOS 14.0, *) and the public struct, so Swift-DocC/SourceKit won’t associate them with the following declaration for DocC. Reorder for CMUXSidebarExtensionDiscovery and CMUXSidebarExtensionHostView (Line ~178).

♻️ Suggested reorder
-@available(macOS 14.0, *)
-/// Discovers installed sidebar extensions that match CMUX's ExtensionKit point.
-public struct CMUXSidebarExtensionDiscovery {
+/// Discovers installed sidebar extensions that match CMUX's ExtensionKit point.
+@available(macOS 14.0, *)
+public struct CMUXSidebarExtensionDiscovery {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@available(macOS 14.0, *)
/// Discovers installed sidebar extensions that match CMUX's ExtensionKit point.
public struct CMUXSidebarExtensionDiscovery {
/// Discovers installed sidebar extensions that match CMUX's ExtensionKit point.
`@available`(macOS 14.0, *)
public struct CMUXSidebarExtensionDiscovery {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXExtensionClient.swift`
around lines 151 - 153, The triple-slash DocC comments are placed between the
`@available` attribute and the declarations so DocC/SourceKit won't associate
them; move each leading /// comment block so it appears immediately above the
`@available`(...) attribute for both CMUXSidebarExtensionDiscovery and
CMUXSidebarExtensionHostView, ensuring the comment is directly adjacent to the
attribute before the public struct/class declaration so DocC correctly attaches
the documentation.

coderabbitai[bot]
coderabbitai Bot previously requested changes May 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXInstalledSidebarExtension.swift`:
- Around line 6-12: The identity `id` is computed from the mutable property
`bundleIdentifier`, which can change the identity at runtime; make the identity
source immutable by changing `bundleIdentifier` to an immutable property (e.g.,
declare it as `let bundleIdentifier`) or alternatively make `id` a stored
constant set once in the initializer (e.g., `let id: String`) and stop deriving
it from a mutable property; update the type's initializer accordingly and apply
the same change for the other similar properties referenced (the occurrences
around the localizedName/extensionPointIdentifier area) so the identity cannot
change after initialization.

In
`@Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionRecord.swift`:
- Around line 7-11: The Identifiable identity currently delegates to a mutable
property manifest.id so CMUXSidebarExtensionRecord.identity can drift; change
manifest from a mutable var to an immutable let (or at minimum private(set) if
internal mutation is required) on the CMUXSidebarExtensionRecord type and update
any initializers (e.g., the record's init) to accept and store the manifest
immutably; also apply the same change to the other occurrences referenced (the
other manifest properties on the record) so id remains stable after
initialization.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionAPIVersion.swift`:
- Around line 3-18: Add Swift-DocC triple-slash comments to the new public API:
document the CMUXExtensionAPIVersion type with a short summary of its purpose,
add comments for the public stored properties `major` and `minor` describing
their meaning, document the public initializer `init(major:minor:)` explaining
parameters, add a comment for the `sidebarV1` constant describing that it
represents API version 1.0, and add a brief doc comment for the Comparable
conformance/operator `static func <` that explains the comparison semantics
(major before minor).

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionManifest.swift`:
- Around line 3-35: The public API lacks DocC comments: add triple-slash (///)
documentation for the public symbols CMUXExtensionKind, CMUXExtensionScope and
CMUXExtensionManifest (including its public properties id, displayName, kind,
minimumAPIVersion, requestedScopes and the public init) describing their
purpose, expected values and any stability/compatibility guarantees; also add
short docs for each enum case (sidebar, workspaceMetadata, workspacePaths,
notifications, networkPorts, pullRequests) and for CMUXExtensionAPIVersion if
exposed so extension authors have a clear manifest contract before publishing.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionValidator.swift`:
- Around line 3-31: Add Swift-DocC triple-slash comments for the public symbols:
document the CMUXExtensionValidationError enum (describe each case:
unsupportedKind(_ : CMUXExtensionKind),
unsupportedAPIVersion(requested:supported:), emptyIdentifier, emptyDisplayName)
and document the CMUXExtensionValidator type and its public static method
validateSidebarManifest(_:supportedAPIVersion:) including parameters (manifest
and supportedAPIVersion), thrown errors (list the CMUXExtensionValidationError
cases that can be thrown and under what conditions), and brief description of
the validation behavior (what constitutes a valid id/displayName, kind must be
.sidebar, and minimumAPIVersion must be <= supportedAPIVersion).
- Around line 15-29: Update CMUXExtensionValidator's ID validation so
identifiers with surrounding whitespace are rejected (or normalized) instead of
only checking for emptiness: in the validation block that checks manifest.id (in
CMUXExtensionValidator.swift) compare manifest.id to
manifest.id.trimmingCharacters(in: .whitespacesAndNewlines) and if they differ
throw a validation error (e.g. add/throw
CMUXExtensionValidationError.invalidIdentifierWhitespace or reuse an appropriate
existing error), or alternatively trim and persist the normalized id before any
downstream use; ensure you reference manifest.id where the guard currently
checks emptiness and enforce the trim-equality rule.

In `@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarActions.swift`:
- Around line 3-19: Add Swift-DocC triple-slash comments for all public symbols:
document the CMUXSidebarAction enum (describe purpose and when each case is
used) and each case (selectWorkspace(UUID): selects given workspace,
closeWorkspace(UUID): closes given workspace, openURL(String): opens the
provided URL), and document the CMUXExtensionActionResult struct (describe
meaning of accepted and message), the public properties accepted and message,
the public init(accepted:message:) (explain parameters and defaults), and the
static let accepted constant (explain it represents a successful result). Ensure
the comments are clear, concise, and placed immediately above CMUXSidebarAction,
each case, CMUXExtensionActionResult, its properties, its initializer, and the
static accepted symbol using triple-slash DocC style.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarExtension.swift`:
- Around line 3-21: Add Swift-DocC triple-slash comments for the public API
surface: document the CMUXSidebarExtension protocol and each requirement
(manifest, makeInitialSnapshot(), handle(_:)) describing purpose, return types,
possible errors and concurrency behavior; document the CMUXSidebarHostClient
struct and its public properties snapshot and dispatch describing what each
closure does and their async/throws contract; and document the public init(...)
explaining parameters and usage. Ensure each /// comment precedes the
corresponding symbol (CMUXSidebarExtension, manifest, makeInitialSnapshot,
handle, CMUXSidebarHostClient, snapshot, dispatch, init) and follows our DocC
style guidelines.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarSnapshot.swift`:
- Around line 3-63: Add Swift-DocC triple-slash comments to document the public
API for CMUXSidebarSnapshot and CMUXSidebarWorkspace: add /// comments above the
CMUXSidebarSnapshot type and its initializer and document each public property
(apiVersion, sequence, windowID, selectedWorkspaceID, workspaces) describing
purpose and optional/default behavior; likewise add /// comments above
CMUXSidebarWorkspace and its init and document all properties (id, title,
detail, isPinned, rootPath, projectRootPath, gitBranch, unreadCount,
latestNotification, listeningPorts, pullRequestURLs) noting which are optional
or have defaults so third-party implementers can rely on the wire format.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1b5b1a29-dd6d-468f-9895-7b6624289733

📥 Commits

Reviewing files that changed from the base of the PR and between f69d418 and 2fc7dd9.

📒 Files selected for processing (15)
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXInstalledSidebarExtension.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionDiscovery.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionHostView.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionPoint.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionRecord.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionRegistry.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionSession.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionAPIVersion.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionManifest.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionValidator.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarActions.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarExtension.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarSnapshot.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionSidebarProvider.swift
💤 Files with no reviewable changes (1)
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift

Comment on lines +6 to +12
public var id: String { bundleIdentifier }
/// Extension bundle identifier.
public var bundleIdentifier: String
/// Localized extension display name.
public var localizedName: String
/// Extension point identifier declared by the extension.
public var extensionPointIdentifier: String

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Keep Identifiable identity source immutable.

id is derived from bundleIdentifier, but bundleIdentifier is mutable. Mutating it changes identity at runtime and can break SwiftUI diffing assumptions.

Suggested fix
 public struct CMUXInstalledSidebarExtension: Identifiable, Equatable, Sendable {
     /// Stable bundle identifier used for SwiftUI identity.
     public var id: String { bundleIdentifier }
     /// Extension bundle identifier.
-    public var bundleIdentifier: String
+    public let bundleIdentifier: String
     /// Localized extension display name.
-    public var localizedName: String
+    public let localizedName: String
     /// Extension point identifier declared by the extension.
-    public var extensionPointIdentifier: String
+    public let extensionPointIdentifier: String

Also applies to: 24-26

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXInstalledSidebarExtension.swift`
around lines 6 - 12, The identity `id` is computed from the mutable property
`bundleIdentifier`, which can change the identity at runtime; make the identity
source immutable by changing `bundleIdentifier` to an immutable property (e.g.,
declare it as `let bundleIdentifier`) or alternatively make `id` a stored
constant set once in the initializer (e.g., `let id: String`) and stop deriving
it from a mutable property; update the type's initializer accordingly and apply
the same change for the other similar properties referenced (the occurrences
around the localizedName/extensionPointIdentifier area) so the identity cannot
change after initialization.

Comment on lines +7 to +11
public var id: String { manifest.id }
/// Manifest describing the extension contract and requested scopes.
public var manifest: CMUXExtensionManifest
/// Whether the extension is provided by cmux rather than a third party.
public var isHostProvided: Bool

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make record identity stable by freezing manifest.

Because id is manifest.id, keeping manifest mutable allows post-init identity drift for an Identifiable model.

Suggested fix
 public struct CMUXSidebarExtensionRecord: Equatable, Identifiable, Sendable {
     /// Stable extension identifier from the manifest.
     public var id: String { manifest.id }
     /// Manifest describing the extension contract and requested scopes.
-    public var manifest: CMUXExtensionManifest
+    public let manifest: CMUXExtensionManifest
     /// Whether the extension is provided by cmux rather than a third party.
-    public var isHostProvided: Bool
+    public let isHostProvided: Bool

Also applies to: 18-19

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/CMUXSidebarExtensionRecord.swift`
around lines 7 - 11, The Identifiable identity currently delegates to a mutable
property manifest.id so CMUXSidebarExtensionRecord.identity can drift; change
manifest from a mutable var to an immutable let (or at minimum private(set) if
internal mutation is required) on the CMUXSidebarExtensionRecord type and update
any initializers (e.g., the record's init) to accept and store the manifest
immutably; also apply the same change to the other occurrences referenced (the
other manifest properties on the record) so id remains stable after
initialization.

Comment on lines +3 to +18
public struct CMUXExtensionAPIVersion: Codable, Comparable, Equatable, Sendable {
public var major: Int
public var minor: Int

public init(major: Int, minor: Int) {
self.major = major
self.minor = minor
}

public static let sidebarV1 = CMUXExtensionAPIVersion(major: 1, minor: 0)

public static func < (lhs: CMUXExtensionAPIVersion, rhs: CMUXExtensionAPIVersion) -> Bool {
if lhs.major != rhs.major { return lhs.major < rhs.major }
return lhs.minor < rhs.minor
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add DocC comments for the new public API.

This package file introduces a public type plus public members, but none of them are documented. Please add /// comments for the type, stored properties, initializer, and the version constant while the API is still small.

As per coding guidelines, “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionAPIVersion.swift`
around lines 3 - 18, Add Swift-DocC triple-slash comments to the new public API:
document the CMUXExtensionAPIVersion type with a short summary of its purpose,
add comments for the public stored properties `major` and `minor` describing
their meaning, document the public initializer `init(major:minor:)` explaining
parameters, add a comment for the `sidebarV1` constant describing that it
represents API version 1.0, and add a brief doc comment for the Comparable
conformance/operator `static func <` that explains the comparison semantics
(major before minor).

Comment on lines +3 to +35
public enum CMUXExtensionKind: String, Codable, CaseIterable, Equatable, Sendable {
case sidebar
}

public struct CMUXExtensionManifest: Codable, Equatable, Identifiable, Sendable {
public var id: String
public var displayName: String
public var kind: CMUXExtensionKind
public var minimumAPIVersion: CMUXExtensionAPIVersion
public var requestedScopes: [CMUXExtensionScope]

public init(
id: String,
displayName: String,
kind: CMUXExtensionKind = .sidebar,
minimumAPIVersion: CMUXExtensionAPIVersion = .sidebarV1,
requestedScopes: [CMUXExtensionScope] = [.workspaceMetadata]
) {
self.id = id
self.displayName = displayName
self.kind = kind
self.minimumAPIVersion = minimumAPIVersion
self.requestedScopes = requestedScopes
}
}

public enum CMUXExtensionScope: String, Codable, CaseIterable, Equatable, Sendable {
case workspaceMetadata
case workspacePaths
case notifications
case networkPorts
case pullRequests
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document the manifest contract before publishing it.

CMUXExtensionManifest, CMUXExtensionKind, and CMUXExtensionScope are all new public package API, but the file has no DocC coverage. Please add /// summaries and member docs now so extension authors have a stable contract to read.

As per coding guidelines, “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionManifest.swift`
around lines 3 - 35, The public API lacks DocC comments: add triple-slash (///)
documentation for the public symbols CMUXExtensionKind, CMUXExtensionScope and
CMUXExtensionManifest (including its public properties id, displayName, kind,
minimumAPIVersion, requestedScopes and the public init) describing their
purpose, expected values and any stability/compatibility guarantees; also add
short docs for each enum case (sidebar, workspaceMetadata, workspacePaths,
notifications, networkPorts, pullRequests) and for CMUXExtensionAPIVersion if
exposed so extension authors have a clear manifest contract before publishing.

Comment on lines +3 to +31
public enum CMUXExtensionValidationError: Error, Equatable, Sendable {
case unsupportedKind(CMUXExtensionKind)
case unsupportedAPIVersion(requested: CMUXExtensionAPIVersion, supported: CMUXExtensionAPIVersion)
case emptyIdentifier
case emptyDisplayName
}

public enum CMUXExtensionValidator {
public static func validateSidebarManifest(
_ manifest: CMUXExtensionManifest,
supportedAPIVersion: CMUXExtensionAPIVersion = .sidebarV1
) throws {
guard manifest.id.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false else {
throw CMUXExtensionValidationError.emptyIdentifier
}
guard manifest.displayName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false else {
throw CMUXExtensionValidationError.emptyDisplayName
}
guard manifest.kind == .sidebar else {
throw CMUXExtensionValidationError.unsupportedKind(manifest.kind)
}
guard manifest.minimumAPIVersion <= supportedAPIVersion else {
throw CMUXExtensionValidationError.unsupportedAPIVersion(
requested: manifest.minimumAPIVersion,
supported: supportedAPIVersion
)
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add DocC for the validator API.

The validator and its public error type are part of the new package contract, but the file has no /// documentation. Please document the error cases and the validation behavior/inputs now, before external callers depend on it.

As per coding guidelines, “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionValidator.swift`
around lines 3 - 31, Add Swift-DocC triple-slash comments for the public
symbols: document the CMUXExtensionValidationError enum (describe each case:
unsupportedKind(_ : CMUXExtensionKind),
unsupportedAPIVersion(requested:supported:), emptyIdentifier, emptyDisplayName)
and document the CMUXExtensionValidator type and its public static method
validateSidebarManifest(_:supportedAPIVersion:) including parameters (manifest
and supportedAPIVersion), thrown errors (list the CMUXExtensionValidationError
cases that can be thrown and under what conditions), and brief description of
the validation behavior (what constitutes a valid id/displayName, kind must be
.sidebar, and minimumAPIVersion must be <= supportedAPIVersion).

Comment on lines +15 to +29
guard manifest.id.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false else {
throw CMUXExtensionValidationError.emptyIdentifier
}
guard manifest.displayName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false else {
throw CMUXExtensionValidationError.emptyDisplayName
}
guard manifest.kind == .sidebar else {
throw CMUXExtensionValidationError.unsupportedKind(manifest.kind)
}
guard manifest.minimumAPIVersion <= supportedAPIVersion else {
throw CMUXExtensionValidationError.unsupportedAPIVersion(
requested: manifest.minimumAPIVersion,
supported: supportedAPIVersion
)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reject identifiers with surrounding whitespace.

Right now "dev.example.sidebar" and " dev.example.sidebar " both validate, because trimming is only used for the empty check. Since registry identity/deduplication is keyed by manifest.id, this lets visually identical extensions bypass duplicate protection and makes lookups brittle. Either normalize id before any downstream use or fail validation when trimming changes it.

💡 Possible fix
 public enum CMUXExtensionValidationError: Error, Equatable, Sendable {
     case unsupportedKind(CMUXExtensionKind)
     case unsupportedAPIVersion(requested: CMUXExtensionAPIVersion, supported: CMUXExtensionAPIVersion)
     case emptyIdentifier
+    case invalidIdentifierWhitespace
     case emptyDisplayName
 }
@@
     ) throws {
-        guard manifest.id.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false else {
+        let trimmedID = manifest.id.trimmingCharacters(in: .whitespacesAndNewlines)
+        guard trimmedID.isEmpty == false else {
             throw CMUXExtensionValidationError.emptyIdentifier
         }
+        guard trimmedID == manifest.id else {
+            throw CMUXExtensionValidationError.invalidIdentifierWhitespace
+        }
         guard manifest.displayName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false else {
             throw CMUXExtensionValidationError.emptyDisplayName
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXExtensionValidator.swift`
around lines 15 - 29, Update CMUXExtensionValidator's ID validation so
identifiers with surrounding whitespace are rejected (or normalized) instead of
only checking for emptiness: in the validation block that checks manifest.id (in
CMUXExtensionValidator.swift) compare manifest.id to
manifest.id.trimmingCharacters(in: .whitespacesAndNewlines) and if they differ
throw a validation error (e.g. add/throw
CMUXExtensionValidationError.invalidIdentifierWhitespace or reuse an appropriate
existing error), or alternatively trim and persist the normalized id before any
downstream use; ensure you reference manifest.id where the guard currently
checks emptiness and enforce the trim-equality rule.

Comment on lines +3 to +19
public enum CMUXSidebarAction: Codable, Equatable, Sendable {
case selectWorkspace(UUID)
case closeWorkspace(UUID)
case openURL(String)
}

public struct CMUXExtensionActionResult: Codable, Equatable, Sendable {
public var accepted: Bool
public var message: String?

public init(accepted: Bool, message: String? = nil) {
self.accepted = accepted
self.message = message
}

public static let accepted = CMUXExtensionActionResult(accepted: true)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document the public action/result types.

This file adds public command and result types for the extension protocol, but there are no DocC comments on the enum, struct, members, or initializer. Please document the payload semantics before consumers start depending on them.

As per coding guidelines, “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarActions.swift`
around lines 3 - 19, Add Swift-DocC triple-slash comments for all public
symbols: document the CMUXSidebarAction enum (describe purpose and when each
case is used) and each case (selectWorkspace(UUID): selects given workspace,
closeWorkspace(UUID): closes given workspace, openURL(String): opens the
provided URL), and document the CMUXExtensionActionResult struct (describe
meaning of accepted and message), the public properties accepted and message,
the public init(accepted:message:) (explain parameters and defaults), and the
static let accepted constant (explain it represents a successful result). Ensure
the comments are clear, concise, and placed immediately above CMUXSidebarAction,
each case, CMUXExtensionActionResult, its properties, its initializer, and the
static accepted symbol using triple-slash DocC style.

Comment on lines +3 to +21
public protocol CMUXSidebarExtension: Sendable {
var manifest: CMUXExtensionManifest { get }

func makeInitialSnapshot() async throws -> CMUXSidebarSnapshot
func handle(_ action: CMUXSidebarAction) async throws -> CMUXExtensionActionResult
}

public struct CMUXSidebarHostClient: Sendable {
public var snapshot: @Sendable () async throws -> CMUXSidebarSnapshot
public var dispatch: @Sendable (CMUXSidebarAction) async throws -> CMUXExtensionActionResult

public init(
snapshot: @escaping @Sendable () async throws -> CMUXSidebarSnapshot,
dispatch: @escaping @Sendable (CMUXSidebarAction) async throws -> CMUXExtensionActionResult
) {
self.snapshot = snapshot
self.dispatch = dispatch
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

DocC is missing on the extension protocol and host client.

This is the primary public integration surface for extension authors, so shipping it undocumented will make the contract hard to adopt correctly. Please add /// comments for the protocol requirements, closure properties, and initializer.

As per coding guidelines, “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarExtension.swift`
around lines 3 - 21, Add Swift-DocC triple-slash comments for the public API
surface: document the CMUXSidebarExtension protocol and each requirement
(manifest, makeInitialSnapshot(), handle(_:)) describing purpose, return types,
possible errors and concurrency behavior; document the CMUXSidebarHostClient
struct and its public properties snapshot and dispatch describing what each
closure does and their async/throws contract; and document the public init(...)
explaining parameters and usage. Ensure each /// comment precedes the
corresponding symbol (CMUXSidebarExtension, manifest, makeInitialSnapshot,
handle, CMUXSidebarHostClient, snapshot, dispatch, init) and follows our DocC
style guidelines.

Comment on lines +3 to +63
public struct CMUXSidebarSnapshot: Codable, Equatable, Sendable {
public var apiVersion: CMUXExtensionAPIVersion
public var sequence: UInt64
public var windowID: UUID?
public var selectedWorkspaceID: UUID?
public var workspaces: [CMUXSidebarWorkspace]

public init(
apiVersion: CMUXExtensionAPIVersion = .sidebarV1,
sequence: UInt64,
windowID: UUID? = nil,
selectedWorkspaceID: UUID?,
workspaces: [CMUXSidebarWorkspace]
) {
self.apiVersion = apiVersion
self.sequence = sequence
self.windowID = windowID
self.selectedWorkspaceID = selectedWorkspaceID
self.workspaces = workspaces
}
}

public struct CMUXSidebarWorkspace: Codable, Equatable, Identifiable, Sendable {
public var id: UUID
public var title: String
public var detail: String?
public var isPinned: Bool
public var rootPath: String?
public var projectRootPath: String?
public var gitBranch: String?
public var unreadCount: Int
public var latestNotification: String?
public var listeningPorts: [Int]
public var pullRequestURLs: [String]

public init(
id: UUID,
title: String,
detail: String? = nil,
isPinned: Bool = false,
rootPath: String? = nil,
projectRootPath: String? = nil,
gitBranch: String? = nil,
unreadCount: Int = 0,
latestNotification: String? = nil,
listeningPorts: [Int] = [],
pullRequestURLs: [String] = []
) {
self.id = id
self.title = title
self.detail = detail
self.isPinned = isPinned
self.rootPath = rootPath
self.projectRootPath = projectRootPath
self.gitBranch = gitBranch
self.unreadCount = unreadCount
self.latestNotification = latestNotification
self.listeningPorts = listeningPorts
self.pullRequestURLs = pullRequestURLs
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add DocC coverage for the snapshot models.

These two structs define the core wire format for sidebar extensions, but none of the public symbols are documented. Please add /// docs for the types, initializers, and fields so third-party implementers know what each field means and which ones are optional/defaulted.

As per coding guidelines, “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CMUXSidebarSnapshot.swift`
around lines 3 - 63, Add Swift-DocC triple-slash comments to document the public
API for CMUXSidebarSnapshot and CMUXSidebarWorkspace: add /// comments above the
CMUXSidebarSnapshot type and its initializer and document each public property
(apiVersion, sequence, windowID, selectedWorkspaceID, workspaces) describing
purpose and optional/default behavior; likewise add /// comments above
CMUXSidebarWorkspace and its init and document all properties (id, title,
detail, isPinned, rootPath, projectRootPath, gitBranch, unreadCount,
latestNotification, listeningPorts, pullRequestURLs) noting which are optional
or have defaults so third-party implementers can rely on the wire format.

coderabbitai[bot]
coderabbitai Bot previously requested changes May 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionLocalizedText.swift`:
- Around line 3-10: Add Swift-DocC triple-slash comments for the public API in
CmuxExtensionLocalizedText: document the struct CmuxExtensionLocalizedText with
a brief purpose/usage summary, add triple‑slash comments for the two public
properties key and defaultValue describing their meanings, and document the
public initializer init(key:defaultValue:) explaining parameters; ensure each
comment is above the corresponding declaration and follows DocC style (short
summary and parameter descriptions where appropriate).

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProvider.swift`:
- Around line 3-4: Add Swift-DocC triple-slash comments to the public protocol
CmuxExtensionSidebarProvider and its requirement property descriptor: document
the protocol's purpose and concurrency guarantees (e.g., that conformers are
Sendable and what sidebar providers do) and document the descriptor property
describing what it represents and any important usage or lifecycle details;
ensure both the protocol declaration (public protocol
CmuxExtensionSidebarProvider: Sendable) and the var descriptor:
CmuxExtensionSidebarProviderDescriptor { get } requirement have concise /// DocC
comments above them.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProviderID.swift`:
- Around line 5-6: Add Swift-DocC triple-slash documentation for the public enum
CmuxExtensionSidebarProviderID and its public constant defaultWorkspaces:
replace or supplement the existing // comments with /// comments above the enum
declaration and above the static let to describe their purpose, intended usage,
and any compatibility notes; ensure the docstrings are concise, use proper DocC
formatting (summary and any parameters/remarks as needed), and cover both
CmuxExtensionSidebarProviderID and
CmuxExtensionSidebarProviderID.defaultWorkspaces so the public API is fully
documented.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionKind.swift`:
- Around line 3-5: Add a Swift-DocC triple-slash comment above the public enum
CMUXExtensionKind describing its purpose and usage in the CMUX extension
manifest, and document the available case(s) (e.g., `sidebar`) and any important
behavioral notes (thread-safety/Sendable conformance or Codable encoding
expectations) so the public symbol is properly documented for consumers and DocC
generation.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionScope.swift`:
- Around line 3-9: Add Swift-DocC triple-slash documentation for the public enum
CMUXExtensionScope and each of its cases: workspaceMetadata, workspacePaths,
notifications, networkPorts, and pullRequests; provide a one-line summary for
the enum describing its purpose (e.g., "Represents permission scopes available
to CMUX extensions") and one-line summaries for each case explaining what
permission or data access that scope grants (e.g., "Allows access to workspace
metadata"), ensuring the comments appear immediately above the enum declaration
and each case.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarAction.swift`:
- Around line 3-7: Add Swift-DocC documentation for the public enum
CMUXSidebarAction and its public cases so the symbol is documented per package
guidelines: add a triple-slash comment above the CMUXSidebarAction declaration
describing its purpose and usage, and add brief triple-slash comments for each
case (selectWorkspace(_:), closeWorkspace(_:), openURL(_:)) explaining the
associated value and when to use each action. Ensure the comments are written in
Swift-DocC style (summary sentence, optional parameters/details) and placed
immediately before the enum and each case.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarExtension.swift`:
- Around line 3-8: Add Swift-DocC triple-slash documentation to the public
protocol CMUXSidebarExtension and each requirement: document the protocol
purpose and the manifest property, and annotate concurrency/threading
expectations (Sendable and async behavior). For makeInitialSnapshot() and
handle(_:) add concise descriptions plus - Returns: and - Throws: callouts
describing their return types (CMUXSidebarSnapshot and CMUXExtensionActionResult
respectively) and what errors may be thrown, and note that both are asynchronous
and should be called from asynchronous contexts; ensure the manifest property
has a brief doc comment describing its role.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarSnapshot.swift`:
- Around line 3-23: Public type CMUXSidebarSnapshot and its initializer lack
Swift-DocC comments; add triple-slash documentation for the struct and for its
public init describing the type's purpose and usage, and include - Parameter
callouts for apiVersion (note the default .sidebarV1), sequence (explain what
the sequence number represents and how it should be used), windowID,
selectedWorkspaceID, and workspaces so users understand each field and their
semantics; ensure the doc comments appear immediately above the
CMUXSidebarSnapshot declaration and the init signature so DocC picks them up.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Validation/CMUXExtensionValidationError.swift`:
- Around line 3-8: Add Swift-DocC triple-slash documentation for the public enum
CMUXExtensionValidationError and for each case: document the enum with a
one-line purpose summary and for unsupportedAPIVersion explain the associated
values (which is the requested and supported CMUXExtensionAPIVersion) and what
the error indicates; add brief comments for unsupportedKind (include that it
carries the CMUXExtensionKind that is not supported), emptyIdentifier, and
emptyDisplayName describing the validation failure they represent. Ensure all
doc comments use /// and are placed immediately above
CMUXExtensionValidationError and each case name (unsupportedKind,
unsupportedAPIVersion(requested:supported:), emptyIdentifier, emptyDisplayName).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4084c1dc-8e5f-4ff7-8dc9-588bd5097e7b

📥 Commits

Reviewing files that changed from the base of the PR and between 2fc7dd9 and 6764a3a.

📒 Files selected for processing (24)
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Discovery/CMUXInstalledSidebarExtension.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Discovery/CMUXSidebarExtensionDiscovery.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/ExtensionPoint/CMUXSidebarExtensionPoint.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Hosting/CMUXSidebarExtensionHostView.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXExtensionClientError.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXSidebarExtensionRecord.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXSidebarExtensionRegistry.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Session/CMUXSidebarExtensionSession.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Common/CMUXExtensionAPIVersion.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionLocalizedText.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProvider.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProviderDescriptor.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProviderID.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionKind.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionManifest.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionScope.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXExtensionActionResult.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarAction.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarExtension.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarHostClient.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarSnapshot.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarWorkspace.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Validation/CMUXExtensionValidationError.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Validation/CMUXExtensionValidator.swift
💤 Files with no reviewable changes (14)
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/ExtensionPoint/CMUXSidebarExtensionPoint.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXExtensionActionResult.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionManifest.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarHostClient.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Discovery/CMUXInstalledSidebarExtension.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Common/CMUXExtensionAPIVersion.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXSidebarExtensionRecord.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarWorkspace.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProviderDescriptor.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Discovery/CMUXSidebarExtensionDiscovery.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Registry/CMUXSidebarExtensionRegistry.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Validation/CMUXExtensionValidator.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Hosting/CMUXSidebarExtensionHostView.swift
  • Packages/CMUXExtensionClient/Sources/CMUXExtensionClient/Session/CMUXSidebarExtensionSession.swift

Comment on lines +3 to +10
public struct CmuxExtensionLocalizedText: Codable, Equatable, Hashable, Sendable {
public var key: String
public var defaultValue: String

public init(key: String, defaultValue: String) {
self.key = key
self.defaultValue = defaultValue
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add DocC comments for public API symbols in this new package file.

This introduces public API without required /// documentation (type + initializer + public properties), which violates package documentation rules.

Proposed fix
+/// Localized text descriptor used by extension-host compatibility APIs.
 public struct CmuxExtensionLocalizedText: Codable, Equatable, Hashable, Sendable {
+    /// Localization key looked up by the host application.
     public var key: String
+    /// Fallback text used when no localized value is available.
     public var defaultValue: String
 
+    /// Creates a localized text descriptor.
+    /// - Parameters:
+    ///   - key: Localization key.
+    ///   - defaultValue: Fallback user-visible text.
     public init(key: String, defaultValue: String) {
         self.key = key
         self.defaultValue = defaultValue
     }
 }

As per coding guidelines: Packages/**/Sources/**/*.swift: “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment…”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionLocalizedText.swift`
around lines 3 - 10, Add Swift-DocC triple-slash comments for the public API in
CmuxExtensionLocalizedText: document the struct CmuxExtensionLocalizedText with
a brief purpose/usage summary, add triple‑slash comments for the two public
properties key and defaultValue describing their meanings, and document the
public initializer init(key:defaultValue:) explaining parameters; ensure each
comment is above the corresponding declaration and follows DocC style (short
summary and parameter descriptions where appropriate).

Comment on lines +3 to +4
public protocol CmuxExtensionSidebarProvider: Sendable {
var descriptor: CmuxExtensionSidebarProviderDescriptor { get }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Document the public protocol and requirement with DocC comments.

Public package API is missing required /// documentation for both the protocol and its property requirement.

Proposed fix
+/// Describes a sidebar provider exposed through the extension host-compatibility layer.
 public protocol CmuxExtensionSidebarProvider: Sendable {
+    /// Metadata used by the host to present this provider in UI.
     var descriptor: CmuxExtensionSidebarProviderDescriptor { get }
 }

As per coding guidelines: Packages/**/Sources/**/*.swift: “Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment…”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/HostCompatibility/CmuxExtensionSidebarProvider.swift`
around lines 3 - 4, Add Swift-DocC triple-slash comments to the public protocol
CmuxExtensionSidebarProvider and its requirement property descriptor: document
the protocol's purpose and concurrency guarantees (e.g., that conformers are
Sendable and what sidebar providers do) and document the descriptor property
describing what it represents and any important usage or lifecycle details;
ensure both the protocol declaration (public protocol
CmuxExtensionSidebarProvider: Sendable) and the var descriptor:
CmuxExtensionSidebarProviderDescriptor { get } requirement have concise /// DocC
comments above them.

Comment on lines +3 to +5
public enum CMUXExtensionKind: String, Codable, CaseIterable, Equatable, Sendable {
case sidebar
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document this public symbol with Swift-DocC.

This is a new public enum in a Packages/ package but has no doc comment. As per coding guidelines, "Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing."

📝 Proposed docs
+/// The category of UI surface a CMUX extension contributes to.
 public enum CMUXExtensionKind: String, Codable, CaseIterable, Equatable, Sendable {
+    /// An extension that renders content in the workspace sidebar.
     case sidebar
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionKind.swift`
around lines 3 - 5, Add a Swift-DocC triple-slash comment above the public enum
CMUXExtensionKind describing its purpose and usage in the CMUX extension
manifest, and document the available case(s) (e.g., `sidebar`) and any important
behavioral notes (thread-safety/Sendable conformance or Codable encoding
expectations) so the public symbol is properly documented for consumers and DocC
generation.

Comment on lines +3 to +9
public enum CMUXExtensionScope: String, Codable, CaseIterable, Equatable, Sendable {
case workspaceMetadata
case workspacePaths
case notifications
case networkPorts
case pullRequests
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document this public symbol with Swift-DocC.

New public enum in a Packages/ package without a doc comment. As per coding guidelines, "Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing." Each scope case is part of the security/permission surface, so a one-line summary per case is worthwhile.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Manifest/CMUXExtensionScope.swift`
around lines 3 - 9, Add Swift-DocC triple-slash documentation for the public
enum CMUXExtensionScope and each of its cases: workspaceMetadata,
workspacePaths, notifications, networkPorts, and pullRequests; provide a
one-line summary for the enum describing its purpose (e.g., "Represents
permission scopes available to CMUX extensions") and one-line summaries for each
case explaining what permission or data access that scope grants (e.g., "Allows
access to workspace metadata"), ensuring the comments appear immediately above
the enum declaration and each case.

Comment on lines +3 to +7
public enum CMUXSidebarAction: Codable, Equatable, Sendable {
case selectWorkspace(UUID)
case closeWorkspace(UUID)
case openURL(String)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document this public symbol with Swift-DocC.

New public enum in a Packages/ package without doc comments. As per coding guidelines, "Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarAction.swift`
around lines 3 - 7, Add Swift-DocC documentation for the public enum
CMUXSidebarAction and its public cases so the symbol is documented per package
guidelines: add a triple-slash comment above the CMUXSidebarAction declaration
describing its purpose and usage, and add brief triple-slash comments for each
case (selectWorkspace(_:), closeWorkspace(_:), openURL(_:)) explaining the
associated value and when to use each action. Ensure the comments are written in
Swift-DocC style (summary sentence, optional parameters/details) and placed
immediately before the enum and each case.

Comment on lines +3 to +23
public struct CMUXSidebarSnapshot: Codable, Equatable, Sendable {
public var apiVersion: CMUXExtensionAPIVersion
public var sequence: UInt64
public var windowID: UUID?
public var selectedWorkspaceID: UUID?
public var workspaces: [CMUXSidebarWorkspace]

public init(
apiVersion: CMUXExtensionAPIVersion = .sidebarV1,
sequence: UInt64,
windowID: UUID? = nil,
selectedWorkspaceID: UUID?,
workspaces: [CMUXSidebarWorkspace]
) {
self.apiVersion = apiVersion
self.sequence = sequence
self.windowID = windowID
self.selectedWorkspaceID = selectedWorkspaceID
self.workspaces = workspaces
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document this public type and its initializer with Swift-DocC.

New public struct, stored properties, and memberwise init in a Packages/ package with no doc comments. As per coding guidelines, "Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing." Include a summary plus - Parameter callouts on the initializer (e.g. clarify the meaning of sequence and the apiVersion default).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Sidebar/CMUXSidebarSnapshot.swift`
around lines 3 - 23, Public type CMUXSidebarSnapshot and its initializer lack
Swift-DocC comments; add triple-slash documentation for the struct and for its
public init describing the type's purpose and usage, and include - Parameter
callouts for apiVersion (note the default .sidebarV1), sequence (explain what
the sequence number represents and how it should be used), windowID,
selectedWorkspaceID, and workspaces so users understand each field and their
semantics; ensure the doc comments appear immediately above the
CMUXSidebarSnapshot declaration and the init signature so DocC picks them up.

Comment on lines +3 to +8
public enum CMUXExtensionValidationError: Error, Equatable, Sendable {
case unsupportedKind(CMUXExtensionKind)
case unsupportedAPIVersion(requested: CMUXExtensionAPIVersion, supported: CMUXExtensionAPIVersion)
case emptyIdentifier
case emptyDisplayName
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Document this public error type with Swift-DocC.

New public error enum in a Packages/ package without doc comments. As per coding guidelines, "Every public symbol in any new Swift package under Packages/ must be documented with a Swift-DocC triple-slash comment at the time of writing." A brief summary per case (especially the associated-value semantics of unsupportedAPIVersion) aids API consumers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/Validation/CMUXExtensionValidationError.swift`
around lines 3 - 8, Add Swift-DocC triple-slash documentation for the public
enum CMUXExtensionValidationError and for each case: document the enum with a
one-line purpose summary and for unsupportedAPIVersion explain the associated
values (which is the requested and supported CMUXExtensionAPIVersion) and what
the error indicates; add brief comments for unsupportedKind (include that it
carries the CMUXExtensionKind that is not supported), emptyIdentifier, and
emptyDisplayName describing the validation failure they represent. Ensure all
doc comments use /// and are placed immediately above
CMUXExtensionValidationError and each case name (unsupportedKind,
unsupportedAPIVersion(requested:supported:), emptyIdentifier, emptyDisplayName).

coderabbitai[bot]
coderabbitai Bot previously requested changes May 29, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSampleSidebarExtension.swift`:
- Around line 27-30: The rejection message returned from
CMUXExtensionActionResult is user-facing and must be localized: replace the
hardcoded string in CMUXSampleSidebarExtension.swift with a localized lookup
(e.g., NSLocalizedString or a String localized key) and add the corresponding
key/value to the app’s Localizable.strings (and any other locale catalogs used)
with translations for all supported locales; ensure the lookup key is
descriptive (e.g., "sample_sidebar_does_not_close_workspaces_message") and use
that key in the CMUXExtensionActionResult initializer so the message is served
via localization APIs.

In
`@Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSampleWorkspaceRow.swift`:
- Around line 48-50: The literal Text("Ports ...") is user-facing and must be
localized: replace the hard-coded string in the UI (the Text call that uses
workspace.listeningPorts) with a localized format string (e.g. use
NSLocalizedString("PortsLabel", comment: "") or LocalizedStringKey with a "%@"
placeholder) and pass the joined ports string as the format argument (compute
portsString = workspace.listeningPorts.map(String.init).joined(separator: ",
")), then call Text(String(format: NSLocalizedString("PortsLabel", comment: ""),
portsString)). Also add the "PortsLabel" entry (e.g. "PortsLabel" = "Ports %@";)
to the Localizable.strings/catalog for each supported locale and update the
localization catalog entries accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a6df20c3-3cff-48ab-922f-66a8ecc35421

📥 Commits

Reviewing files that changed from the base of the PR and between 6764a3a and de4a77e.

📒 Files selected for processing (9)
  • Examples/CMUXSampleSidebarExtension/Package.swift
  • Examples/CMUXSampleSidebarExtension/README.md
  • Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXExtensionManifest+Sample.swift
  • Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSampleSidebarExtension.swift
  • Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSampleSidebarView.swift
  • Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSampleWorkspaceRow.swift
  • Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSidebarSnapshot+Sample.swift
  • Examples/CMUXSampleSidebarExtension/Tests/CMUXSampleSidebarExtensionTests/CMUXSampleSidebarExtensionTests.swift
  • cmux.xcworkspace/contents.xcworkspacedata

Comment on lines +27 to +30
return CMUXExtensionActionResult(
accepted: false,
message: "The sample sidebar does not close workspaces."
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the action rejection message.

The message is user-facing but hardcoded in English. Route it through localization and add matching entries for all supported locales in the touched catalog.

Suggested fix
         case .closeWorkspace:
             return CMUXExtensionActionResult(
                 accepted: false,
-                message: "The sample sidebar does not close workspaces."
+                message: String(
+                    localized: "sampleSidebar.action.closeWorkspace.unsupported",
+                    defaultValue: "The sample sidebar does not close workspaces."
+                )
             )

As per coding guidelines: “Any new or materially changed Swift UI/user-facing text … must use localization.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSampleSidebarExtension.swift`
around lines 27 - 30, The rejection message returned from
CMUXExtensionActionResult is user-facing and must be localized: replace the
hardcoded string in CMUXSampleSidebarExtension.swift with a localized lookup
(e.g., NSLocalizedString or a String localized key) and add the corresponding
key/value to the app’s Localizable.strings (and any other locale catalogs used)
with translations for all supported locales; ensure the lookup key is
descriptive (e.g., "sample_sidebar_does_not_close_workspaces_message") and use
that key in the CMUXExtensionActionResult initializer so the message is served
via localization APIs.

Comment on lines +48 to +50
if !workspace.listeningPorts.isEmpty {
Text("Ports \(workspace.listeningPorts.map(String.init).joined(separator: ", "))")
.font(.system(size: 10))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localize the ports label text.

"Ports ..." is user-facing copy in a SwiftUI production path and should use localized API plus catalog entries for supported locales.

Suggested fix
                 if !workspace.listeningPorts.isEmpty {
-                    Text("Ports \(workspace.listeningPorts.map(String.init).joined(separator: ", "))")
+                    Text(
+                        String(
+                            localized: "sampleSidebar.workspace.ports",
+                            defaultValue: "Ports \(workspace.listeningPorts.map(String.init).joined(separator: ", "))"
+                        )
+                    )
                         .font(.system(size: 10))
                         .foregroundStyle(.secondary)
                         .lineLimit(1)
                 }

As per coding guidelines: “Any new or materially changed Swift UI/user-facing text … must use localization.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Examples/CMUXSampleSidebarExtension/Sources/CMUXSampleSidebarExtension/CMUXSampleWorkspaceRow.swift`
around lines 48 - 50, The literal Text("Ports ...") is user-facing and must be
localized: replace the hard-coded string in the UI (the Text call that uses
workspace.listeningPorts) with a localized format string (e.g. use
NSLocalizedString("PortsLabel", comment: "") or LocalizedStringKey with a "%@"
placeholder) and pass the joined ports string as the format argument (compute
portsString = workspace.listeningPorts.map(String.init).joined(separator: ",
")), then call Text(String(format: NSLocalizedString("PortsLabel", comment: ""),
portsString)). Also add the "PortsLabel" entry (e.g. "PortsLabel" = "Ports %@";)
to the Localizable.strings/catalog for each supported locale and update the
localization catalog entries accordingly.

@azooz2003-bit
azooz2003-bit dismissed stale reviews from coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], and coderabbitai[bot] May 30, 2026 06:37

Ignoring stale CodeRabbit review per maintainer instruction; deterministic CI remains the merge gate.

@azooz2003-bit
azooz2003-bit merged commit a086dd1 into main May 30, 2026
17 of 18 checks passed
@azooz2003-bit
azooz2003-bit deleted the feature-sidebar-extension-kit branch May 30, 2026 06:52
austinywang added a commit that referenced this pull request Jun 2, 2026
The built-in views rendered empty even with workspaces present: the host
renders each view through an `any CmuxExtensionSidebarProvider` existential
(`provider(for:)?.render(snapshot:)`), and #4994 left `render(snapshot:)` only
as a protocol-extension default — so the call static-dispatched to the empty
default instead of the concrete view.

These tests exercise that exact path and fail without the fix:
- cmuxTests: the host's `provider(for:)?.render(snapshot:)` returns 0 rows.
- CmuxExtensionSidebarExamples: rendering a provider through the existential
  diverges from the concrete call (empty vs populated).

Failing test only — fix follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
austinywang added a commit that referenced this pull request Jun 2, 2026
#4994 demoted CmuxExtensionSidebarProvider.render(snapshot:) from a protocol
requirement to a protocol-extension default returning no sections. Because the
host renders views through an `any CmuxExtensionSidebarProvider` existential, a
method defined only in the extension static-dispatches to that empty default —
so every built-in view (Project Worktrees, Attention Queue, Dev Servers, Last
Prompt, Super Compact, Browser Stack) rendered an empty sidebar.

Restore it as a protocol requirement (keeping the extension default) so the
call dynamic-dispatches to the concrete view via the witness table — matching
v0.64.10. Verified live: Super Compact now renders all 51 workspaces
(sections=1 rows=[51]); the contextual/mutable default render(snapshot:context:)
also routes correctly since it forwards to render(snapshot:).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull Bot pushed a commit to jasonkneen/cmux that referenced this pull request Jun 2, 2026
…-ai#5173)

manaflow-ai#4994 ("Replace sidebar extension kit contract") replaced the old in-process
sidebar-provider contract with an XPC-based ExtensionKit host. It kept the
in-process compatibility render layer (CmuxExtensionCompatibility.swift) and
ContentView's render pipeline, but it:

  - stubbed CmuxExtensionSidebarSelection.providers to `[]` (was
    SidebarExamples.providers — the six built-in preset views) and unlinked
    the CmuxExtensionSidebarExamples package from the app target;
  - gated the sidebar-button right-click menu behind the experimental
    Extensions beta flag (`guard isEnabled` in showMenu, and
    effectiveExtensionSidebarProviderId forcing Default Workspaces whenever
    the flag was off);
  - dropped the BrowserStackSidebar.stateDidLoadNotification refresh.

Net effect on a default install (beta off): the right-click menu and all of
its built-in views (Default Workspaces, Project Worktrees, Attention Queue,
Dev Servers, Last Prompt, Super Compact, Browser Stack) disappeared.

This restores them on top of manaflow-ai#4994's new contract rather than reverting it.
The experimental flag now gates only the new XPC surface (the hosted
"Extension Sidebar" entry, the puzzle button, the extensions browser); the
built-in views are always available again:

  - re-link CmuxExtensionSidebarExamples into the cmux target and restore
    `providers`/import (the examples compile unchanged against the kept
    compatibility layer);
  - split builtInDescriptors (always) from descriptors (adds the hosted
    entry only when the beta is on) and allDescriptors (handler superset);
  - add the pure effectiveProviderId(_:extensionsEnabled:) so the menu
    checkmark and the rendered provider track the selection, downgrading
    only a hosted selection to default while the beta is off;
  - drop the `guard isEnabled` in showMenu and un-gate the command-palette
    "Sidebar: <view>" contributions;
  - restore the BrowserStackSidebar live-refresh subscription.

Closes manaflow-ai#5173

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview – cmux — 67e62a10 Deployed May 30, 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