Skip to content

Add CmuxExtensionKit sidebar prototypes - #4309

Merged
lawrencecchen merged 37 commits into
mainfrom
feat-extensionkit-sidebars-events
May 23, 2026
Merged

lawrencecchen merged 37 commits into
mainfrom
feat-extensionkit-sidebars-events

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented May 18, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add CmuxExtensionKit as a Swift package for sidebar snapshots, events, reducers, render models, and built-in example providers.
  • Add custom sidebar switching from the sidebar button context menu and command palette.
  • Add project-tree, last-message, browser-oriented, server/attention, thin, and super-compact sidebar prototypes.
  • Publish workspace.prompt.submitted and expose extension.sidebar.snapshot so custom sidebars can hydrate from snapshots and stay current from events.
  • Add workspace inspector popovers with notes and a free-form browser omnibar, plus a prototype worktree/dev-server action.

Verification

  • swift test --package-path Packages/CmuxExtensionKit
  • git diff --check
  • jq empty Resources/Localizable.xcstrings
  • ./scripts/reload.sh --tag extkit

Demo videos

  • /tmp/cloud-extkit-project-tree-live/recording.mov | TLDR: Project-tree sidebar groups workspaces by repo with open/closed folder icons, icon-only plus buttons, and thin row text.
  • /tmp/cloud-extkit-last-message-live/recording.mov | TLDR: Last-message sidebar updates from prompt-submit events while the sidebar is open and reorders recent workspaces.
  • /tmp/cloud-extkit-super-compact/recording.mov | TLDR: Super-compact sidebar shows a dense workspace list with thin text and stable virtualized rows.

Note

Medium Risk
Introduces a new extension-facing API surface and changes workspace event publishing/mapping (workspace.prompt.submitted, reorder handling), which can affect sidebar state sync and ordering if regressions slip in.

Overview
Adds a new Swift package, CmuxExtensionKit, defining the extension sidebar contract (snapshots, render models, mutations, event frames, and a reducer for applying events to snapshots), plus a small CmuxExtensionPathFormatter utility.

Introduces CmuxExtensionSidebarExamples with several sample sidebar providers (project/worktree grouping, attention queue, dev server detection, last prompt recency, super-compact list) and a mutable BrowserStackSidebar that supports drag-and-drop grouping with per-window JSON state persistence and async state hydration.

Updates host event publishing to emit redacted workspace.prompt.submitted frames and a structured workspace.reordered payload (including pinned IDs), and stops mirroring workspace.reorder* socket-v2 calls into domain reorder events. Expands Localizable.xcstrings with new sidebar/provider strings and adds unit tests covering sidebar rendering, persistence/reconciliation, and reducer/event decoding behavior.

Reviewed by Cursor Bugbot for commit cafedc2. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Adds CmuxExtensionKit and CmuxExtensionSidebarExamples for custom, switchable sidebars driven by snapshots and live events. Finalizes sidebar snapshot RPC, publishes redacted workspace.prompt.submitted, unifies workspace.reordered (with pinned state), hardens reducers/replay, and scopes BrowserStack state per window so sidebars stay accurate across replays, restarts, and multiple windows.

  • New Features

    • CmuxExtensionKit with snapshot/reducer/render APIs, path formatter, and provider descriptors.
    • CmuxExtensionSidebarExamples: attention queue, dev servers, last prompt, project worktrees, super-compact, and a mutable BrowserStack (per-window persisted groups, drag-and-drop, preserved boundary inserts).
    • Switch providers from the sidebar button (right-click) and command palette; inspector popover/window; animated section disclosure.
    • Snapshots auto-refresh project root on directory changes; prompt submissions set latestSubmittedAt even when iMessage mode is off.
  • Bug Fixes

    • Productionized extension.sidebar.snapshot RPC/serialization; tightened event sync and out-of-order handling; request snapshot replacement when needed; reduced noisy logs.
    • Publish workspace.prompt.submitted only on submissions with redacted payloads; gated remote attention rows.
    • Unified workspace.reordered publishing across prompt, drag-and-drop, pin toggles, and lifecycle; include pinned_workspace_ids; removed socket mirroring to avoid duplicates; isolated reorder side effects; added tests for reorder paths and BrowserStack DnD.
    • BrowserStack provider now returns state scoped to the requesting window to prevent cross-window bleed; UI polish and stability: squared full-width selection highlight, hardened inspector interactions, cleared drag warning budget.

Written for commit cafedc2. Summary will update on new commits. Review in cubic

Summary by CodeRabbit

  • New Features
    • Extension sidebar with multiple view modes, example providers, provider switching (menu + command palette), per-section collapse, workspace inspector (notes + embedded browser), worktree creation flow, prompt-submission tracking with timestamps, and live snapshot/event updates.
  • Documentation
    • Added extension sidebar README and updated event docs with snapshot/events guidance.
  • Localization
    • Expanded sidebar and relative-time strings (en/ja).
  • Tests
    • Unit tests for providers, rendering, reducer behavior, and serialization.
  • Chores
    • Added local extension package and project wiring; titlebar right-click opens sidebar menu.

Review Change Stack

@vercel

vercel Bot commented May 18, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment May 23, 2026 12:53am
cmux-staging Building Building Preview, Comment May 23, 2026 12:53am

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented May 18, 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

Adds CmuxExtensionKit and integrates an extension-sidebar system: new package with models/reducer/renderers, V2 snapshot API, prompt-submitted event publishing and submission timestamps, UI integration (selection, inspector, worktree prototype), example providers, runtime init fixes, tests, localization, and project wiring.

Changes

Extension Sidebar Architecture & Integration

Layer / File(s) Summary
CmuxExtensionKit Package & Core Type Contracts
Packages/CmuxExtensionKit/Package.swift, Packages/CmuxExtensionKit/README.md, Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
New Swift package manifest and README; core codable models for localized text, generic JSON values with typed accessors, event/frame/command types, CmuxClient abstraction, and workspace snapshot shape.
Sidebar State Management & Event Reduction
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
CmuxExtensionSidebarReducer processes high-level sidebar events and V2 event frames to evolve projected snapshot state, handling upsert/remove/reorder/select and prompt-submitted normalization.
Provider & Rendering Contracts
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
Provider IDs, customization modes, built-in provider descriptors, render text/icon/row/section models, presentation/mutation enums, provider protocols, and contextual render contract.
Workspace Tree Provider & Builder Implementations
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
CmuxExtensionWorkspaceTreeProvider renders snapshots into CmuxExtensionSidebarRenderModel; CmuxExtensionWorkspaceTreeBuilder provides strategies for multiple modes (thin/project-tree/attention/servers/last-message/browser/super-compact/browser-stack) and path formatting helpers.
CmuxExtensionKit Test Suite
Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift
Tests assert built-in provider stability, project-tree rendering (sections/rows/accessories), JSON Codable round-trips and legacy decoding, browser-stack and last-message rendering behavior, and reducer-driven snapshot updates for prompt submission and workspace selection/closure.
Workspace Submission State & Event Publishing
Sources/Workspace.swift, Sources/WorkspacePromptSubmit.swift, Sources/CmuxEventPublishing.swift, cmuxTests/WorkspacePromptSubmitTests.swift
Workspace gains latestSubmittedAt; TabManager distinguishes message kinds and records/publishes prompt submissions; CmuxEventBus.publishWorkspacePromptSubmitted(...) added; tests updated to check timestamp behavior.
Extension Snapshot V2 Socket API & Payloads
Sources/TerminalController.swift
Adds extension.sidebar.snapshot V2 command and advertises capability; extends workspace summary payload with latest message fields and implements helpers to construct per-workspace snapshot payloads (paths, git info, remote/display state, messages/timestamps, ports, PR URLs).
Extension Sidebar UI Components & Integration
Sources/ContentView.swift, Sources/Update/UpdateTitlebarAccessory.swift
Adds CmuxExtensionSidebarSelection (persistence, descriptors, menu), command-palette entries per provider, VerticalTabsSidebar conditional rendering of extension sidebar, Timeline-driven snapshot→model refresh (immediate + debounced observation), browserStack and generic section UIs, per-section collapse, optional create-worktree actions, inspector popover with notes/browser, inspector window controller, and worktree prototype that initializes git worktrees; titlebar toggle adds right-click provider menu.
Runtime Instance Routing & Initialization Fixes
Sources/GhosttyTerminalView.swift
GhosttyApp adds initializingInstance and runtimeCallbackApp() to route runtime callbacks to the initializing instance during initializeGhostty(); replaces some shared-instance callback uses and avoids synchronous color-scheme sync during init.
Build Configuration & Localization
cmux.xcodeproj/project.pbxproj, Resources/Localizable.xcstrings, docs/events.md
Wires CmuxExtensionKit as a local Swift package in Xcode; expands localization with relative-time units and sidebar/provider/section labels (en/ja); documents extension.sidebar.snapshot and workspace.prompt.submitted and bootstrap/subscription flow.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 I stitched a sidebar, rows aligned in rows,
Snapshots and events in tidy little flows,
Providers bloom, reducers keep time,
Worktrees spin up with a git-made rhyme,
Hooray — an extension where the sidebar grows!


Caution

Pre-merge checks failed

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

  • Ignore

❌ Failed checks (5 errors, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Cmux Swift Concurrency ❌ Error PR introduces new @Published property (latestSubmittedAt) in Workspace for app state tracking. Modernization rules require using Observation framework instead of Combine for new code. Replace @Published latestSubmittedAt with @Observable pattern or equivalent Observation-based state management in Workspace.swift
Cmux Swift @Concurrent ❌ Error CmuxExtensionWorktreePrototype.createWorktree() performs heavy file I/O and subprocess operations but is called from @MainActor context without @concurrent annotation or proper isolation boundary. Add @concurrent annotation to createWorktree(), or wrap the call in Task.detached() to explicitly hop off the main actor before awaiting the result.
Cmux Swift File And Package Boundaries ❌ Error ContentView.swift violated 250-line limit: +1102 lines to 15956-line file. No extraction exception (grew instead of shrinking by 200+). Mixed UI/state/persistence/networking/subprocess. Extract sidebar views and subprocess logic to separate files/packages. Shrink ContentView.swift >200 lines by moving inspector and worktree components.
Cmux Architecture Rethink ❌ Error Adds mutable observer flag extensionSidebarUpdateToken creating duplicate ownership with TimelineView timer. Also adds GhosttyApp conditional callback routing that switches instances. Remove extensionSidebarUpdateToken flag pattern. Simplify GhosttyApp callback routing to deterministic instance selection.
Cmux Swift Auxiliary Window Close Shortcuts ❌ Error Inspector window controller creates NSWindow without cmux.* identifier or cmuxAuxiliaryWindowIdentifiers registration, violating close-shortcut rules. Add cmux.* identifier to window and register in cmuxAuxiliaryWindowIdentifiers set in cmuxApp.swift.
Docstring Coverage ⚠️ Warning Docstring coverage is 1.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Cmux Swift Actor Isolation ❓ Inconclusive No result was produced after verification. Marking as INCONCLUSIVE. Re-run the check or adjust instructions to produce a final result.
✅ Passed checks (9 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add CmuxExtensionKit sidebar prototypes' clearly summarizes the main change: introducing a new package and multiple sidebar prototypes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Blocking Runtime ✅ Passed No new blocking patterns introduced. CmuxExtensionKit and production changes contain no flagged synchronization violations.
Cmux No Hacky Sleeps ✅ Passed This PR is Swift/docs/config only. Custom check applies to TypeScript, JavaScript, shell, and non-Swift runtime scripts. Check is not applicable.
Cmux Swift Logging ✅ Passed No Swift logging violations found. PR adds no print(), debugPrint(), dump(), or NSLog() statements in app/runtime code. Existing diagnostics are pre-existing and not modified by this PR.
Cmux User-Facing Error Privacy ✅ Passed No privacy violations found. User-facing strings do not expose credentials, internal names, database details, or raw upstream messages.
Cmux Swiftui State Layout ✅ Passed @Published added to existing legacy Workspace class (allowed exception); new @State for local UI values; row views receive value snapshots not stores; no improper mutations.
Description check ✅ Passed PR description includes summary, verification steps, demo videos, and checklist; however, several checklist items are unchecked and testing/documentation sections could be more detailed.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-extensionkit-sidebars-events

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.

Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/Workspace.swift Outdated
Comment thread Sources/TerminalController.swift Outdated
@greptile-apps

greptile-apps Bot commented May 18, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces CmuxExtensionKit and CmuxExtensionSidebarExamples as the public extension sidebar API surface, wiring snapshot/event delivery, six prototype providers, per-window-scoped drag-and-drop state persistence, and a command-palette switcher. It also refactors prompt-submission tracking so latestSubmittedMessage/latestSubmittedAt are recorded independently of iMessage mode, unifies workspace.reordered publishing, and removes V2 socket reorder mirroring to eliminate duplicate events.

  • CmuxExtensionKit package defines the core snapshot, reducer, render model, and provider protocol types; CmuxExtensionSidebarExamples ships six providers (project-tree, attention-queue, dev-server, last-prompt, super-compact, and a per-window-scoped BrowserStack with async background persistence).
  • Host changes cache extensionSidebarProjectRootPath in the workspace model (eliminating the previously flagged on-render .git walk), fix latestSubmittedMessage to use the new dedicated property, gate publishWorkspacePromptSubmitted on messageRecorded, and clean up inspector window controllers on close.
  • Tests cover new reducer behavior, reorder event payloads, provider rendering, and the blank-submit guard.

Confidence Score: 5/5

Safe to merge — all previously flagged blocking, memory, state, and serialization issues have been addressed; no new defects found in the changed paths.

Every concrete defect from prior review rounds has a matching fix: the .git directory walk is now cached in extensionSidebarProjectRootPath; Process.waitUntilExit is replaced with a termination-handler continuation; the BrowserStack state cache moves disk I/O to a background queue; inspector window controllers are pruned on close via willCloseNotification; publishWorkspacePromptSubmitted is gated on messageRecorded; latest_submitted_message correctly maps to the new dedicated property; Dictionary(uniqueKeysWithValues:) traps have been removed; and ensureGitRepository throws instead of silently creating a repo. The reducer correctly guards normalizedPrompt before mutating snapshot state, and the per-window BrowserStack scoping is well-tested. No new defects were found in the new code paths.

No files require special attention. The BrowserStackSidebarStateCache.statesByScope dictionary accumulates one entry per window UUID over the app lifetime, but entries are small structs and growth is bounded by windows opened in a session.

Important Files Changed

Filename Overview
Sources/WorkspacePromptSubmit.swift Refactors prompt-submission dispatch to use a kind enum: .promptSubmission now always calls recordSubmittedMessage (setting latestSubmittedMessage/latestSubmittedAt regardless of iMessage mode) and gates publishWorkspacePromptSubmitted on messageRecorded; .assistantFinal retains the prior iMessage-mode guard. Tests were updated to reflect the intentional behavior change.
Sources/Workspace.swift Adds latestSubmittedMessage, latestSubmittedAt, and extensionSidebarProjectRootPath (all @Published); caches the .git tree-walk asynchronously via scheduleExtensionSidebarProjectRootRefresh on directory change, eliminating the previously flagged on-render blocking filesystem walk.
Sources/ExtensionWorktreePrototype.swift New helper for creating git worktrees; uses termination handler + Task.detached pipe collector (fixing the prior waitUntilExit blocking issue); ensureGitRepository now throws instead of silently running git init; error payloads use a clean NSLocalizedDescriptionKey with raw output in a separate CmuxExtensionWorktreePrototypeDetails key.
Sources/ExtensionSidebarWorkspaceRowView.swift New file with row view, inspector popover/window controller (with proper willCloseNotification cleanup), browser view (Coordinator pattern prevents nav resets), and relative-time formatter; inspector draft state lives outside the popover, surviving re-opens.
Sources/ContentView.swift +~1400 lines adding extension sidebar scroll area, BrowserStack tile/row/group rendering, section disclosure, worktree creation flow, command-palette provider switching, and snapshot building; uses cached extensionSidebarProjectRootPath; mutation handler delegates blocking I/O to provider's background queue.
Sources/CmuxEventPublishing.swift Adds publishWorkspacePromptSubmitted (always redacts message body, includes preview and length) and publishWorkspaceReordered (includes full ordered workspace IDs and pinned IDs) event publishers.
Sources/CmuxSocketEventMapper.swift Removes V2 socket mirroring of workspace.reorder/workspace.reorder_many results into workspace.reordered events (replaced with lifecycle-side publishWorkspaceReordered); eliminates duplicate event emission.
Sources/TerminalController.swift Adds extension.sidebar.snapshot RPC handler; uses pre-cached workspace.extensionSidebarProjectRootPath (no per-call .git walk); separates latest_conversation_message and latest_submitted_message into distinct payload keys.
Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/BrowserStackSidebar.swift BrowserStack provider with per-window state scoping; BrowserStackSidebarStateCache loads state asynchronously via Task.detached and persists on a serial DispatchQueue, fixing the prior blocking-I/O-in-render and blocking-I/O-in-mutation issues; scope keys are never pruned when windows close (minor in-memory accumulation).
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionSidebarReducer.swift New reducer handling snapshot replacement and incremental events (workspace.created, workspace.closed, workspace.reordered, workspace.prompt.submitted, notification.*); correctly guards normalizedPrompt before updating latestSubmittedMessage.
Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift Core snapshot and render model types; dual-format Codable decoding (internal camelCase + socket snake_case); thread-local ISO8601 formatter cache; JSONValue.intValue uses Int(exactly:) (confirmed safe for boundary values).

Sequence Diagram

sequenceDiagram
    participant UI as VerticalTabsSidebar (MainActor)
    participant TM as TabManager
    participant WS as Workspace
    participant Bus as CmuxEventBus
    participant Reducer as CmuxExtensionSidebarReducer
    participant Provider as SidebarProvider (e.g. BrowserStack)
    participant TC as TerminalController (socket)

    UI->>TM: handlePromptSubmit(workspaceId:message:)
    TM->>WS: recordSubmittedMessage(message)
    WS->>WS: conversationMessagePreview(from:)
    WS->>WS: recordConversationMessage(preview)
    WS-->>TM: true (messageRecorded)
    TM->>Bus: publishWorkspacePromptSubmitted(workspaceId:preview:)
    TM->>Bus: publishWorkspaceReordered(workspaceIds:movedIds:pinnedIds:)
    Bus-->>UI: extensionSidebarUpdateToken increments (via .onReceive)
    UI->>UI: extensionSidebarRenderModel(renderContext:now:)
    UI->>Provider: render(snapshot:)
    Provider-->>UI: CmuxExtensionSidebarRenderModel

    TC->>TC: v2ExtensionSidebarSnapshot (RPC)
    TC->>WS: extensionSidebarProjectRootPath (cached, no .git walk)
    TC-->>TC: build payload with latestSubmittedMessage/latestSubmittedAt
    TC-->>Bus: .ok([...])

    note over Reducer: External consumers use Reducer to apply live events
    Bus-->>Reducer: CmuxExtensionEventFrame(workspace.prompt.submitted)
    Reducer->>Reducer: "guard normalizedPrompt(message_preview) != nil"
    Reducer->>Reducer: update latestSubmittedMessage, latestSubmittedAt
Loading

Reviews (33): Last reviewed commit: "fix: return browser stack scoped state" | Re-trigger Greptile

Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 18, 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: 8

🤖 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 `@docs/events.md`:
- Line 246: The doc uses the term `sequence` in the event-reduction guidance
while the rest of the stream/event schema uses `seq`; update the wording to use
`seq` consistently (replace `sequence` with `seq` in the guidance referring to
the returned sequence/seq) and verify related references (e.g., the snapshot
that returns `selected_workspace_id`) mention `seq` so clients implement the
correct field name.

In `@Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift`:
- Around line 1-1268: The file is too large and mixes multiple responsibilities;
split it into focused Swift files: 1) data models & simple types (move
CmuxExtensionLocalizedText, CmuxExtensionJSONValue, CmuxExtensionEventFrame,
CmuxExtensionCommandResult, CmuxClient, CmuxExtensionWorkspaceSnapshot,
CmuxExtensionSidebarSnapshot, CmuxExtensionSidebarEvent,
CmuxExtensionSidebarMutation, CmuxExtensionSidebarRenderText,
CmuxExtensionSidebarRenderModel, CmuxExtensionSidebarRenderSection,
CmuxExtensionSidebarRenderRow, CmuxExtensionSidebarRenderContext,
CmuxExtensionPathFormatter and related small enums/structs), 2) provider
descriptors and provider protocols (move CmuxExtensionSidebarProviderDescriptor,
CmuxExtensionSidebarProviderID, CmuxExtensionSidebarCustomizationMode,
CmuxExtensionSidebarProvider, CmuxExtensionSidebarContextualProvider,
CmuxExtensionWorkspaceRowAccessory/Kind, CmuxExtensionWorkspacePopoverTab), 3)
reducer logic (move CmuxExtensionSidebarReducer and its helpers like
resolvedWorkspaceId and normalizedPrompt), and 4) tree building & rendering
helpers (move CmuxExtensionWorkspaceTreeBuilder,
CmuxExtensionWorkspaceTreeSection, CmuxExtensionWorkspaceTreeProvider and helper
functions like groupSectionTemplate, appendSection, needsAttention,
hasServerSignal, trimmedNonEmpty and the private CmuxExtensionJSONValue uuid
helpers). Ensure each new file keeps original access levels (public) and
imports, update module visibility, preserve Codable/Sendable conformance, run
build/tests, and adjust any internal references/imports if needed so symbols
like CmuxExtensionSidebarReducer.reduce,
CmuxExtensionWorkspaceTreeBuilder.sections,
CmuxExtensionSidebarProviderDescriptor, CmuxClient, and
CmuxExtensionPathFormatter continue to resolve.
- Around line 86-93: The intValue getter currently converts a rounded Double to
Int without bounds checking (in the .number case); add a range check against
Int.min and Int.max (or use Int64 ranges if needed) before calling Int(rounded)
and return nil if the rounded value is outside the representable Int range,
preserving the existing guard behavior for non-integer doubles; update the
.number branch in intValue to validate rounded is finite and within
Int.min...Int.max prior to the Int(rounded) conversion.

In `@Sources/CmuxEventPublishing.swift`:
- Around line 95-99: The event currently emits full prompt text under the
"message" key and reports no redactions; change the payload so the raw "message"
is not published (replace with NSNull() or a constant like "[REDACTED]"),
continue to publish "message_preview" and "message_length" as appropriate, and
update "redacted_fields" to include "message" so consumers know it was redacted;
locate the dictionary construction that sets "message", "message_preview",
"message_length", and "redacted_fields" and modify those entries accordingly.

In `@Sources/ContentView.swift`:
- Around line 10565-10572: Set a stable cmux.* identifier on the newly created
NSWindow and register that identifier with the shared close-shortcut routing so
Cmd+W is handled by the inspector instead of falling through; specifically,
after creating the NSWindow (the variable named window created with
hostingController and stored via controllers[workspace.id]) assign
window.identifier = NSUserInterfaceItemIdentifier("cmux.inspector.<stable-id>")
(use a stable token such as workspace.id) and ensure this identifier is included
in whatever registry/function backs cmuxWindowShouldOwnCloseShortcut so the
inspector window owns the close shortcut when it becomes key.

In `@Sources/GhosttyTerminalView.swift`:
- Around line 2172-2175: Remove the immediate seeding of
lastAppearanceColorScheme so the initial launch scheme isn't treated as
"unchanged"; instead defer syncing the runtime by either (A) leaving
lastAppearanceColorScheme nil/empty so the first call to
synchronizeThemeWithAppearance(...) sees a change and performs a sync, or (B)
explicitly schedule a deferred call (e.g. dispatch to main queue / next runloop)
that invokes ghostty_app_set_color_scheme(initialColorScheme) or calls
synchronizeThemeWithAppearance(initialColorScheme, force: true) after the
singleton's dispatch_once completes; update the code around
lastAppearanceColorScheme, synchronizeThemeWithAppearance(...), and
ghostty_app_set_color_scheme accordingly.

In `@Sources/TerminalController.swift`:
- Around line 4350-4359: The loop calling
FileManager.default.fileExists(atPath:) inside v2MainSync (via
v2ExtensionSidebarProjectRootPath) blocks the main thread; move the project-root
detection off the main thread and/or cache results. Compute project-root paths
asynchronously (e.g., DispatchQueue.global or Task.detached) for each workspace
path or maintain a cache keyed by workspace.path, then build
v2ExtensionSidebarWorkspacePayloads using the precomputed project-root values
and only call v2MainSync to set selectedWorkspaceId and assign the
already-prepared workspaces array; apply the same change for the similar code
referenced around v2MainSync usage at the 4414-4425 region.
- Around line 4393-4396: The sidebar workspace payload mistakenly sets the
"latest_submitted_message" field to workspace.latestConversationMessage
(copy-paste error); update the payload to use the submitted-message property
(e.g., workspace.latestSubmittedMessage) instead, keeping the same v2OrNull
wrapper and timestamp handling pattern used for "latest_conversation_message"
and "latest_submitted_at" so the keys "latest_conversation_message",
"latest_submitted_message", and "latest_submitted_at" reference the correct
workspace properties in TerminalController.swift where the payload is
constructed.
🪄 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: eb60ae81-393c-4091-b46c-fc2d551b0917

📥 Commits

Reviewing files that changed from the base of the PR and between e83bfb1 and be877a9.

📒 Files selected for processing (15)
  • Packages/CmuxExtensionKit/Package.swift
  • Packages/CmuxExtensionKit/README.md
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
  • Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift
  • Resources/Localizable.xcstrings
  • Sources/CmuxEventPublishing.swift
  • Sources/ContentView.swift
  • Sources/GhosttyTerminalView.swift
  • Sources/TerminalController.swift
  • Sources/Update/UpdateTitlebarAccessory.swift
  • Sources/Workspace.swift
  • Sources/WorkspacePromptSubmit.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/WorkspacePromptSubmitTests.swift
  • docs/events.md

Comment thread docs/events.md Outdated
Comment thread Sources/CmuxEventPublishing.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/GhosttyTerminalView.swift Outdated
Comment thread Sources/TerminalController.swift Outdated
Comment thread Sources/TerminalController.swift

@cubic-dev-ai cubic-dev-ai 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.

7 issues found across 15 files

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Comment thread Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift Outdated
Comment thread Sources/CmuxEventPublishing.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift Outdated
Comment thread Sources/TerminalController.swift Outdated
Comment thread Sources/ContentView.swift Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 19, 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: 3

🤖 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 `@Sources/ContentView.swift`:
- Around line 10582-10669: CmuxExtensionWorktreePrototype and its helpers
(createWorktree, ensureGitRepository, writeSampleDevServerFiles, run,
shellEscaped) are pure Foundation/subprocess logic and should be extracted out
of the UI file; move this enum into a new dedicated Swift source (e.g.,
WorktreeCreation.swift) or into the CmuxExtensionKit package, update any
module/import references and access control as needed, and keep the
public/internal API (createWorktree signature and
CmuxExtensionWorktreeCreationResult) unchanged so callers in the UI continue to
work and the logic becomes independently testable.
- Around line 10087-10099: The ForEach body is calling
extensionWorkspaceSnapshot(for:) per row which causes repeated recomputation on
every render; move snapshot creation to the render/model preparation phase
(e.g., build a [UUID: WorkspaceSnapshot] map keyed by workspaceId from
section.rows) and pass the precomputed snapshot into
CmuxExtensionSidebarWorkspaceRowView instead of calling
extensionWorkspaceSnapshot(for:) inline; update the ForEach to use the map
lookup (using row.workspaceId) and keep other parameters (providerId,
relativeNow, isSelected, onSelect, onOpenWindow) unchanged so the view receives
a precomputed snapshot rather than recalculating each render.
- Around line 10550-10574: controllers never get removed so inspectors leak;
after creating the NSWindow/NSWindowController in
CmuxExtensionSidebarInspectorWindowController.show(workspace:), register a
one-shot observer for NSWindow.willCloseNotification (object: window) that
removes controllers[workspace.id] when the window closes and also removes the
observer token inside the handler to avoid leaking the observer; place the
addObserver call immediately after controller/window creation so the handler can
reference workspace.id and controllers to clean up.
🪄 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: 16080cd9-a56b-46b7-9820-f549a54805a9

📥 Commits

Reviewing files that changed from the base of the PR and between be877a9 and 877e3ab.

📒 Files selected for processing (1)
  • Sources/ContentView.swift

Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/TerminalController.swift
coderabbitai[bot]
coderabbitai Bot previously requested changes May 19, 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: 4

🤖 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 `@Sources/ContentView.swift`:
- Around line 10562-10580: The fast path in show(workspace:) reuses
controllers[workspace.id] but doesn't refresh the window title or hosted SwiftUI
view, causing stale inspector content; update the existing
NSWindowController/NSWindow by setting controller.window?.title =
workspace.title and either replace the contentViewController with a new
NSHostingController(rootView:
CmuxExtensionWorkspaceInspectorView(...).frame(width:620,height:440)) or, if the
current contentViewController is an NSHostingController, set its rootView to the
new CmuxExtensionWorkspaceInspectorView instance and call
window?.setContentSize(NSSize(width:620,height:440)) before making key and
ordering front so the inspector reflects the latest workspace snapshot.
- Around line 10022-10033: extensionSidebarProjectRootPath currently returns the
original rootPath when no .git is found, which lets the UI show “Create
worktree” for non-git folders; change the function
(extensionSidebarProjectRootPath) to return nil when no .git directory is
discovered so the UI will not offer worktree creation for non-repositories, and
mirror the same change in the duplicate implementation around the other
occurrence (lines referenced in review: the second copy at 10616-10631) to
ensure both code paths stop exposing worktree creation for non-git directories.
- Around line 10445-10457: The formatter
CmuxExtensionRelativeTimeFormatter.string(from:to:) uses single keys for
count-based units; change each unit branch (minutes, hours, days, weeks) to use
pluralized localization keys (ICU/.one and .other variants) and pass the numeric
count into the localized formatter instead of embedding the number in the
defaultValue. For example, replace building "\(minutes)m" with a call that looks
up "relativeTime.minutes" as a pluralized key and supplies minutes as the count
(using String.localizedStringWithFormat(NSLocalizedString(...)) or the Swift
String(localized:_) API that accepts arguments) and do the same for hours, days
and weeks in the string(from:to:) function.
- Around line 9390-9400: The menu currently reads only
UserDefaults.standard.string(forKey: defaultsKey) to set each NSMenuItem.state,
which ignores the AppStorage defaultProviderId on first run; update the
comparison in showMenu (where item.state is set) to use the stored value or
fallback to defaultProviderId (e.g. use UserDefaults.standard.string(forKey:
defaultsKey) ?? defaultProviderId) so the provider whose id equals the
AppStorage defaultProviderId is marked .on; keep the rest of the item setup
(title via localizedTitle(for:), action selectProvider(_:), target
CmuxExtensionSidebarMenuTarget.shared, representedObject = descriptor.id)
unchanged.
🪄 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: 18359cf7-0c42-48a7-bbf1-99c79b760259

📥 Commits

Reviewing files that changed from the base of the PR and between 877e3ab and 699ba0a.

📒 Files selected for processing (1)
  • Sources/ContentView.swift

Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/Workspace.swift
coderabbitai[bot]
coderabbitai Bot previously requested changes May 19, 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: 3

🤖 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/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/DevServerSidebar.swift`:
- Around line 54-62: The hasServerSignal function currently treats any ":" in
workspace.customDescription as a server signal, causing false positives (e.g.,
"feat: ..."); change the detection so a colon only counts when it looks like a
host:port or port indicator — e.g., check description for "server" OR a pattern
like ":\d+" (colon followed by digits) or common URL schemes ("http://",
"https://") or numeric port tokens; update hasServerSignal to use these stricter
checks against trimmed(workspace.customDescription)?.lowercased() so ordinary
labels with colons are not classified as live servers.

In
`@Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/LastPromptSidebar.swift`:
- Around line 46-51: The subtitle fallback in
promptSubtitle(_:CmuxExtensionWorkspaceSnapshot) uses a hardcoded English
string; replace the plain("No prompts yet") with a localized lookup (for example
NSLocalizedString("No prompts yet", comment: "Last prompt sidebar subtitle") or
String(localized: "No prompts yet")) so the UI localizes correctly, and add the
corresponding key/value to your Localizable.strings file; keep the existing
trimmed(workspace.latestSubmittedMessage) behavior and return type
CmuxExtensionSidebarRenderText.plain.

In
`@Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/ProjectWorktreeSidebar.swift`:
- Around line 43-48: The localization key must be stable instead of using the
runtime folder name; update the ExampleSidebarSection creation so the title uses
a constant key like "example.sidebar.group.project" (not
"example.sidebar.group.project.\(title)") and pass the folder display name
(computed by displayName(for:)) as the localized argument; adjust the
ExampleSidebarSection initializer call where id is "project:\(root)" and the
title currently uses localized("example.sidebar.group.project.\(title)", title)
to use localized("example.sidebar.group.project", title) so translation catalogs
remain deterministic.
🪄 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: 7b0d8e6e-5e08-49ff-82a8-3c4c54b61f84

📥 Commits

Reviewing files that changed from the base of the PR and between 699ba0a and a22190d.

📒 Files selected for processing (7)
  • Examples/CmuxExtensionSidebarExamples/Package.swift
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/AttentionQueueSidebar.swift
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/DevServerSidebar.swift
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/LastPromptSidebar.swift
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/ProjectWorktreeSidebar.swift
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/SidebarExamples.swift
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/SuperCompactSidebar.swift

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 7 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

coderabbitai[bot]
coderabbitai Bot previously requested changes May 19, 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/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift`:
- Around line 590-620: The public enum CmuxExtensionWorkspacePopoverTab
currently exposes .pullRequest but treats it as a legacy alias (decodes
"pullRequest" as .browser and encodes .pullRequest as "browser"), which is
misleading; fix by either (A) making .pullRequest round-trippable: add
.pullRequest to the public allCases and update init(from:) and encode(to:) to
preserve and emit .pullRequest when appropriate, or (B) mark .pullRequest as
deprecated/internal and remove it from the public API while keeping a private
decoding fallback for the legacy "pullRequest" string; after choosing, add a
unit test (e.g., testWorkspacePopoverTabRoundTrips_activeCases) that asserts all
active (non-legacy) cases of CmuxExtensionWorkspacePopoverTab round-trip through
JSON encode/decode unchanged.
- Around line 266-270: Replace the unsafe Dictionary(uniqueKeysWithValues:)
build in the .workspacesReordered case with an explicit loop that records the
first appearance of each id (e.g., iterate ids.enumerated() and only set
indexById[id] if not already present) to avoid crashing on duplicates; also
compute originalIndexById from snapshot.workspaces.enumerated() and change the
sorted key to use indexById[id] ?? originalIndexById[id] ?? Int.max so omitted
IDs preserve their original relative order. Add a reducer unit test that
dispatches .workspacesReordered with duplicate IDs and with a partial payload
(omitting some workspace IDs) and asserts the resulting snapshot.workspaces
order matches the expected ordering (first reordered IDs in their first-seen
order, then the omitted workspaces in original order).

In `@Resources/Localizable.xcstrings`:
- Line 112670: The localization key "sidebar.browserStack.demoGroup" currently
contains placeholder text "lmao" for both en and ja; update the value for that
key to the correct user-facing copy (replace "lmao" with the intended English
string and the appropriate Japanese translation) in
Resources/Localizable.xcstrings so the UI does not show placeholder text, and
ensure the "stringUnit" entries for both "en" and "ja" are set to the finalized
translated values.

In `@Sources/ContentView.swift`:
- Around line 10079-10100: The demo group header uses a placeholder fallback
title and a no-op close button; replace the defaultValue "lmao" in the localized
Text (key "sidebar.browserStack.demoGroup") with the correct product copy and
wire the Button's empty action (the Button {} label: { ... } block) to the real
close/collapse behavior (e.g., call the view model method that removes or
collapses the group, such as closeGroup(groupID) or
toggleGroupExpansion(groupID)), or if that behavior isn't implemented yet,
remove or hide the Button (and its .safeHelp) until a proper handler exists so
the UI isn't misleading.
- Around line 10689-11023: Extract the sidebar-related types from
ContentView.swift into their own files: create separate Swift files for
CmuxExtensionSidebarWorkspaceRowView (View), CmuxExtensionRelativeTimeFormatter
(enum/helper), CmuxExtensionWorkspaceInspectorView (View),
CmuxExtensionWorkspaceInspectorBrowserView (NSViewRepresentable),
CmuxExtensionSidebarInspectorWindowController (class, keep `@MainActor`), and the
worktree helpers CmuxExtensionWorktreeCreationResult and
CmuxExtensionWorktreePrototype; preserve their existing access levels,
attributes (e.g., `@MainActor`, `@State`), and logic, add any required imports
(SwiftUI, WebKit, AppKit/Foundation) at the top of each new file, update
references in the project to the moved symbols, and then remove the
corresponding definitions from ContentView.swift so the file size is reduced
without changing behavior.
- Around line 10854-10860: The TextField is updating the bound `address` on
every keystroke which causes `updateNSView` to normalize and load the WKWebView
continuously; introduce a separate committed state (e.g., `committedAddress` or
`committedQuery`) and bind the TextField to the existing `address` while only
calling `CmuxExtensionWorkspaceInspectorBrowserView.normalizedAddress(...)` and
feeding that into the web view from `updateNSView` when the user submits (the
`.onSubmit` handler) or explicitly opens, and mirror that committed state to the
WKWebView load logic (and update any similar logic referenced around lines
10894-10900) so typing does not trigger navigation until commit.
🪄 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: 56945c2b-6c72-4065-8153-9a9ed7584b64

📥 Commits

Reviewing files that changed from the base of the PR and between a22190d and 845bd57.

📒 Files selected for processing (6)
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/BrowserStackSidebar.swift
  • Examples/CmuxExtensionSidebarExamples/Sources/CmuxExtensionSidebarExamples/SidebarExamples.swift
  • Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift
  • Packages/CmuxExtensionKit/Tests/CmuxExtensionKitTests/CmuxExtensionKitTests.swift
  • Resources/Localizable.xcstrings
  • Sources/ContentView.swift

Comment thread Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift Outdated
Comment thread Packages/CmuxExtensionKit/Sources/CmuxExtensionKit/CmuxExtensionKit.swift Outdated
Comment thread Resources/Localizable.xcstrings Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 6 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift Outdated

@cubic-dev-ai cubic-dev-ai 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.

2 issues found across 13 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread Sources/ContentView.swift Outdated
Comment thread Sources/ContentView.swift
Comment thread Sources/ContentView.swift Outdated
@austinywang austinywang mentioned this pull request Sep 25, 2026

This branch was successfully deployed

1 active deployment
Preview – cmux — cafedc2b Deployed May 23, 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