Skip to content

Redesign AppKit sidebar groups and live reordering - #9446

Closed
lawrencecchen wants to merge 33 commits into
mainfrom
feat-sidebar-appearance-markdown
Closed

lawrencecchen wants to merge 33 commits into
mainfrom
feat-sidebar-appearance-markdown

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

  • Use native AppKit Liquid Glass with a neutral gray default tint, rounded workspace rows, gray selection, and hover feedback.
  • Render Arc-style workspace groups with disclosure hierarchy, regular workspace-sized text, no folder icon, aligned pins, and trailing aggregate unread badges.
  • Animate reorder previews with stable AppKit row identities. Canonical workspace order changes only on drop, cancellation restores it, and expanded groups move as one block.
  • Keep unread badges sticky at the trailing edge. Single-digit counts use a circular 14 pt pill, regular-weight numerals, and outline-based optical centering.
  • Render Markdown in AppKit workspace titles, descriptions, and group names.
  • Add configurable sidebar.workspaceSpacing from 0 to 8 pt with a compact 1 pt default, Settings UI, schema documentation, and localization.

Implementation:

  • SidebarWorkspaceTableController owns transient reorder rows, native NSTableView.moveRow animation, rollback, and authoritative reconciliation.
  • Drag registration is identity-aware, and the source workspace ID is retained from pasteboard creation through preview rendering.
  • Simulated targets resolve through controller-owned displayed rows and geometry, avoiding side effects from drag-source pasteboard APIs.

Testing:

Preview:

@coderabbitai

coderabbitai Bot commented Aug 3, 2026 •

Copy link
Copy Markdown

Review Change Stack

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

The PR adds configurable sidebar workspace spacing with settings, persistence, JSON support, localization, and runtime layout updates. It also updates sidebar Markdown rendering, typography, unread badges, accessibility metadata, and related tests.

Changes

Sidebar rendering and presentation

Layer / File(s) Summary
Inline Markdown and row presentation
Packages/macOS/CmuxFoundation/..., Sources/Sidebar/..., Sources/SidebarWorkspaceGroupHeaderMetrics.swift, cmuxTests/SidebarAppKitRowCellTests.swift, cmuxTests/SidebarMarkdownRendererTests.swift, Resources/Localizable.xcstrings, Sources/App/MenuBarExtraController.swift
Sidebar titles and descriptions render inline Markdown. Group headers no longer use folder icons. Unread badges use measured sizing, localized accessibility labels, capped counts, and updated typography. Related rendering and localization tests were added.

Workspace spacing contract and settings surface

Layer / File(s) Summary
Workspace spacing configuration
Packages/macOS/CmuxSettings/..., Sources/CmuxSettingsJSONPathSupport.swift, Sources/KeyboardShortcutSettingsFileStore*.swift, web/data/cmux.schema.json, web/messages/*, web/tests/docs-search-index.test.ts
sidebar.workspaceSpacing accepts values from 0 through 8, defaults to 1, persists through UserDefaults, parses from JSON, and appears in generated templates. Localized schema descriptions and validation cover supported locales.
Settings UI and navigation
Packages/macOS/CmuxSettingsUI/..., Sources/SettingsNavigation.swift, Sources/SettingsSearchAliases.swift, Resources/Localizable.xcstrings
Sidebar Appearance includes a bounded Workspace Spacing stepper, localized labels, search aliases, accessibility metadata, and row-anchor mappings.

Sidebar spacing propagation

Layer / File(s) Summary
Runtime spacing updates
Sources/ContentView.swift, Sources/Sidebar/AppKitList/SidebarWorkspaceTable*.swift, cmuxTests/SidebarWorkspaceTableSuspensionTests.swift
ContentView reads and clamps the setting, then passes it through the sidebar table view and controller. The controller updates intercell spacing and requests layout when the value changes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • manaflow-ai/cmux-dev-artifacts#7740 — Covers the same sidebar row and group-header rendering and accessibility test area.
  • manaflow-ai/cmux-dev-artifacts#7731 — Covers compilation and tests in cmuxTests/SidebarAppKitRowCellTests.swift.
  • manaflow-ai/cmux-dev-artifacts#7745 — Covers sidebar Markdown rendering and appearance tests in the same test file.

Possibly related PRs

  • manaflow-ai/cmux#8612 — Shares sidebar Markdown description rendering and SidebarWorkspaceRowSlotViews.swift.
  • manaflow-ai/cmux#8663 — Shares Markdown metadata rendering in SidebarWorkspaceRowSupportViews.swift.
  • manaflow-ai/cmux#9189 — Shares SidebarWorkspaceTableController.flushApply layout-update behavior.

Suggested reviewers: austinywang, azooz2003-bit

Sequence Diagram(s)

sequenceDiagram
  participant ContentView
  participant SidebarWorkspaceTableView
  participant SidebarWorkspaceTableController
  participant NSTableView
  ContentView->>SidebarWorkspaceTableView: Pass configured rowSpacing
  SidebarWorkspaceTableView->>SidebarWorkspaceTableController: Apply rowSpacing
  SidebarWorkspaceTableController->>SidebarWorkspaceTableController: Clamp and stage value
  SidebarWorkspaceTableController->>NSTableView: Update intercell spacing and layout
Loading
🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (24 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed The diff adds no actor, Sendable, async, or protocol isolation changes; AppKit/settings UI paths remain explicitly @MainActor, and pure package settings types are not MainActor-default.
Cmux Swift Blocking Runtime ✅ Passed The complete PR diff adds no production Swift semaphore, blocking wait, sleep, delayed dispatch, main-queue sync, timer, polling loop, or manual lock.
Cmux Browser Automation Off-Main ✅ Passed The PR diff contains no browser socket automation changes; both policy target files and policy tests are unchanged, so this check is not applicable.
Cmux Expensive Synchronous Load ✅ Passed The PR's production Swift diff adds no agent-history loader, transcript/JSONL scan, directory walk, or per-record syscall; sidebar changes only render Markdown and apply cached settings/layout values.
Cmux Cache Substitution Correctness ✅ Passed The PR adds a new UserDefaults setting and live UI binding; it does not replace a fresh persistence, history, undo, or snapshot read with a cache.
Cmux No Hacky Sleeps ✅ Passed The full sidebar topic diff adds no sleep, timer, polling, or fixed-delay calls; its only TypeScript change is test-only localization assertions, and runtime changes are Swift.
Cmux Algorithmic Complexity ✅ Passed The diff adds only linear per-string Markdown-run traversal (titles/descriptions are bounded to 2048/4096 characters) and scalar spacing updates; it adds no nested workspace scans, sorting, or filt...
Cmux Swift Concurrency ✅ Passed Aggregate Swift diff adds no Dispatch queues/groups, Combine state, completion-handler APIs, or fire-and-forget Tasks; changes are synchronous settings, layout, rendering, and tests.
Cmux Swift @Concurrent ✅ Passed The full Swift diff adds no async, await, Task, actor, nonisolated, or @concurrent syntax; changed code is synchronous UI, settings, rendering, and test logic.
Cmux Swift Package Boundaries ✅ Passed Changed app-side production code is AppKit sidebar rendering and table-lifecycle glue; reusable Markdown and workspace-spacing APIs are already in CmuxFoundation and CmuxSettings package targets.
Cmux Swiftpm Lockfiles ✅ Passed The PR diff contains no Package.swift, Package.resolved, .gitignore, workflow, or Xcode project changes, so the SwiftPM lockfile policy is not triggered.
Cmux Swift Logging ✅ Passed The PR adds no print, debugPrint, dump, NSLog, or ad hoc production logging; its only changed log is #if DEBUG cmuxDebugLog with sanitized byte-count output, and the Logger declaration remains comp...
Cmux User-Facing Error Privacy ✅ Passed The production diff adds only generic sidebar labels, notification counts, and spacing documentation; invalid-setting logs hash path data, and scans found no banned provider, credential, payload, o...
Cmux Full Internationalization ✅ Passed All 5 changed catalog keys have translated values for all 20 existing locales; web workspaceSpacing entries cover all 20 routing locales; new Swift copy uses localized keys.
Cmux Swiftui State Layout ✅ Passed The new setting uses @Observable DefaultsValueModel with @State. The diff adds no GeometryReader, lazy/list row store, or render-time state write; the sidebar table is an NSViewRepresentable bridge.
Cmux Architecture Rethink ✅ Passed The diff adds no new timing, blocking, polling, lock, or observer repair path; workspaceSpacing has one catalog source and flows as a value snapshot to the MainActor table controller, which clamps...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The PR adds no standalone window or controller code. The auxiliary-window lint passed and checked 35 identifiers; changed sidebar views and test fixtures do not add window identifiers or close rout...
Cmux Source Artifacts ✅ Passed The 48 changed paths are source, test, configuration, schema, or localization files; no artifact-like paths or binary/log files were added.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The full PR diff adds no test/debug-named production members or test-only guards; existing DEBUG probes and ForTesting members are unchanged, while new APIs serve product layout, accessibility, and...
Cmux No Ambient Global State ✅ Passed Production Swift additions use instance-owned state and methods; new static members are constants or methods on constructable types, with no new file-scope functions, mutable globals, static-only n...
Title check ✅ Passed The title clearly identifies the AppKit sidebar redesign and live reordering covered by the pull request.
Description check ✅ Passed The description clearly covers the changes and testing, but it omits the template's Demo Video, Review Trigger, and Checklist sections.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-sidebar-appearance-markdown

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.

@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: 7

🤖 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 `@cmuxTests/SidebarAppKitRowCellTests.swift`:
- Around line 353-383: Extend workspaceTitleRendersMarkdownWithRegularBaseWeight
and workspaceDescriptionPreservesMarkdownFontTraits to assert both rendered
strings exclude Markdown delimiters and both fields use the required 12.5-point
base font. Reuse the existing font inspection helpers where applicable, while
preserving the current bold, italic, and regular-trait assertions.
- Around line 385-400: The test
unreadBadgeExpandsForLargeCountsAndKeepsFullAccessibleCount only covers the
plural unread-count branch. Add a separate count-1 case using
Self.configuredCell and assert the badge’s accessibilityLabel() uses the
singular ICU .one localization value, while retaining the existing 125-count
.other assertion.

In
`@Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/SidebarSection.swift`:
- Line 16: Make the `@State` property workspaceSpacing private to satisfy SwiftUI
state encapsulation. Update workspaceSpacingRow in
SidebarSection+WorkspaceSpacing.swift by moving it into SidebarSection.swift or
extracting a separate row view that receives a Binding, preserving its current
behavior while avoiding direct access to the private state.

In `@Resources/Localizable.xcstrings`:
- Around line 190620-190636: Complete localization coverage in
Resources/Localizable.xcstrings for the three workspace-spacing keys:
settings.search.alias.setting.sidebarAppearance.workspace-spacing at lines
190620-190636, settings.sidebarAppearance.workspaceSpacing at lines
194985-195018, and settings.sidebarAppearance.workspaceSpacing.subtitle. Add
translated values for every locale currently supported, preserving the existing
English and Japanese entries.

In `@Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowCellView.swift`:
- Around line 443-450: Remove the DEBUG-only diagnostic in the title-paint path
that logs displayTitle from the sidebar row cell. If retaining a diagnostic is
necessary, replace the raw workspace title with non-sensitive metadata such as
its byte count, while preserving the existing mismatch check and avoiding any
user-controlled title content.
- Around line 618-621: Update the unread accessibility label construction near
model.unreadCount to select explicit ICU-style .one and .other localization keys
based on whether the count equals one or not, instead of using
String.localizedStringWithFormat. Add matching catalog entries for both keys
with locale-appropriate singular and plural wording.

In `@web/data/cmux.schema.json`:
- Around line 1047-1054: Add non-empty localized entries for
schemaDescriptions.sidebar.workspaceSpacing in the sidebar sections of
web/messages/en.json and web/messages/ja.json, matching the existing message
structure so the referenced schema description resolves in both locales.
🪄 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 Plus

Run ID: c7e1f3f9-3811-4ee4-b863-938d11df85fb

📥 Commits

Reviewing files that changed from the base of the PR and between 1927f13 and 254f394.

📒 Files selected for processing (48)
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/SidebarMarkdownRenderer.swift
  • Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/SidebarCatalogSection.swift
  • Packages/macOS/CmuxSettings/Tests/CmuxSettingsTests/UserDefaultsSettingsClientTests.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/SidebarSection+WorkspaceSpacing.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/SidebarSection.swift
  • Packages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swift
  • Resources/Localizable.xcstrings
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/ContentView.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/SettingsNavigation.swift
  • Sources/SettingsSearchAliases.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarGroupHeaderRowView.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowCellView.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowSlotViews.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowSupportViews.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableApplyInput.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableController.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableView.swift
  • Sources/SidebarWorkspaceGroupHeaderMetrics.swift
  • cmuxTests/SidebarAppKitRowCellTests.swift
  • cmuxTests/SidebarMarkdownRendererTests.swift
  • cmuxTests/SidebarWidthPolicyTests.swift
  • cmuxTests/SidebarWorkspaceTableSuspensionTests.swift
  • web/data/cmux.schema.json
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json
  • web/tests/docs-search-index.test.ts

Comment thread cmuxTests/SidebarAppKitRowCellTests.swift
Comment thread cmuxTests/SidebarAppKitRowCellTests.swift
Comment thread Resources/Localizable.xcstrings
Comment thread Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowCellView.swift
Comment thread Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowCellView.swift Outdated
Comment thread web/data/cmux.schema.json
@lawrencecchen
lawrencecchen force-pushed the feat-sidebar-appearance-markdown branch from 254f394 to 64621da Compare August 3, 2026 10:18

@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.

♻️ Duplicate comments (1)
Resources/Localizable.xcstrings (1)

190620-190636: ⚠️ Potential issue | 🟠 Major

Complete localization coverage for the new workspace-spacing keys.

The three new keys contain only en and ja, while the catalog supports additional locales. Add translated entries for every supported locale.

  • Resources/Localizable.xcstrings#L190620-L190636: add translations for settings.search.alias.setting.sidebarAppearance.workspace-spacing.
  • Resources/Localizable.xcstrings#L194985-L195018: add translations for settings.sidebarAppearance.workspaceSpacing and settings.sidebarAppearance.workspaceSpacing.subtitle.

As per path instructions, changed catalog keys require complete coverage across supported locales. Based on learnings, this repository treats the full internationalization rule as authoritative.

🤖 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 `@Resources/Localizable.xcstrings` around lines 190620 - 190636, Complete
localization coverage for the three workspace-spacing keys:
Resources/Localizable.xcstrings lines 190620-190636 requires translated entries
for every supported locale for
settings.search.alias.setting.sidebarAppearance.workspace-spacing; lines
194985-195018 likewise require every supported locale for
settings.sidebarAppearance.workspaceSpacing and
settings.sidebarAppearance.workspaceSpacing.subtitle. Preserve the existing
English and Japanese entries while adding appropriate translations for all
remaining supported locales.

Sources: Path instructions, Learnings

🤖 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.

Duplicate comments:
In `@Resources/Localizable.xcstrings`:
- Around line 190620-190636: Complete localization coverage for the three
workspace-spacing keys: Resources/Localizable.xcstrings lines 190620-190636
requires translated entries for every supported locale for
settings.search.alias.setting.sidebarAppearance.workspace-spacing; lines
194985-195018 likewise require every supported locale for
settings.sidebarAppearance.workspaceSpacing and
settings.sidebarAppearance.workspaceSpacing.subtitle. Preserve the existing
English and Japanese entries while adding appropriate translations for all
remaining supported locales.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 08d929b8-35bf-4449-8029-0d3ef460f6b8

📥 Commits

Reviewing files that changed from the base of the PR and between 254f394 and 64621da.

📒 Files selected for processing (44)
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/SidebarMarkdownRenderer.swift
  • Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/SidebarCatalogSection.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/SidebarSection+WorkspaceSpacing.swift
  • Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/SidebarSection.swift
  • Packages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swift
  • Resources/Localizable.xcstrings
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/ContentView.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/SettingsNavigation.swift
  • Sources/SettingsSearchAliases.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarGroupHeaderRowView.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowCellView.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowSlotViews.swift
  • Sources/Sidebar/AppKitList/Cells/SidebarWorkspaceRowSupportViews.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableApplyInput.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableController.swift
  • Sources/Sidebar/AppKitList/SidebarWorkspaceTableView.swift
  • Sources/SidebarWorkspaceGroupHeaderMetrics.swift
  • cmuxTests/SidebarWidthPolicyTests.swift
  • web/data/cmux.schema.json
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json
  • web/tests/docs-search-index.test.ts

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
cmuxTests/SidebarAppKitRowCellTests.swift (2)

454-480: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Compare pin positions in a common coordinate space.

frame.minX is expressed in each pin view’s immediate superview coordinate space, so this comparison does not check alignment inside the workspace and group cells. Convert both pin origins to their enclosing cells before comparing them.

Proposed test change
-        `#expect`(groupPin.frame.minX == workspacePin.frame.minX)
+        let workspacePinX = workspacePin.convert(.zero, to: workspace).x
+        let groupPinX = groupPin.convert(.zero, to: group).x
+        `#expect`(abs(groupPinX - workspacePinX) < 0.5)
🤖 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 `@cmuxTests/SidebarAppKitRowCellTests.swift` around lines 454 - 480, Update
groupPinAlignsWithWorkspacePin to convert both pin origins into their enclosing
cell coordinate spaces before comparing horizontal positions; compare the
converted minX values rather than the raw frame.minX values, while preserving
the existing pin discovery and alignment assertion.

428-452: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Check every attributed font run in the group name.

Line [442] checks only NSTextField.font. SidebarMarkdownRenderer produces per-run fonts, so a bold or italic run can use the wrong point size while this assertion passes. Assert every group-name run is 12.5 points.

Proposed test change
-        `#expect`(name.font?.pointSize == 12.5)
+        `#expect`(Self.fontPointSizes(in: name).allSatisfy { abs($0 - 12.5) < 0.001 })
🤖 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 `@cmuxTests/SidebarAppKitRowCellTests.swift` around lines 428 - 452, Update
groupHeaderUsesMarkdownRegularWorkspaceSizedTextWithoutFolderIcon to inspect
every attributed font run in the group-name NSTextField, rather than relying
only on name.font. Assert that each run’s font has a 12.5-point size while
preserving the existing bold, italic, plain-run, text, and icon assertions.
🤖 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.

Outside diff comments:
In `@cmuxTests/SidebarAppKitRowCellTests.swift`:
- Around line 454-480: Update groupPinAlignsWithWorkspacePin to convert both pin
origins into their enclosing cell coordinate spaces before comparing horizontal
positions; compare the converted minX values rather than the raw frame.minX
values, while preserving the existing pin discovery and alignment assertion.
- Around line 428-452: Update
groupHeaderUsesMarkdownRegularWorkspaceSizedTextWithoutFolderIcon to inspect
every attributed font run in the group-name NSTextField, rather than relying
only on name.font. Assert that each run’s font has a 12.5-point size while
preserving the existing bold, italic, plain-run, text, and icon assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 030c0a60-dd33-48e4-a603-bec469b4ec15

📥 Commits

Reviewing files that changed from the base of the PR and between 64621da and 93816c7.

📒 Files selected for processing (1)
  • cmuxTests/SidebarAppKitRowCellTests.swift

@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@coderabbitai coderabbitai Bot mentioned this pull request Aug 4, 2026
6 tasks done
@lawrencecchen
lawrencecchen force-pushed the feat-sidebar-appearance-markdown branch from 782f5cd to 2b6a398 Compare August 4, 2026 04:59
@lawrencecchen
lawrencecchen force-pushed the feat-sidebar-appearance-markdown branch from 2b6a398 to 97fbbef Compare August 4, 2026 05:08
@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Optical unread badge follow-up for the third centering report.

Head: 48afd299ff8bd8e8f893cb6c05fd1d9e6229cc6b

Commits:

  • d1bbcd1de8a99b6450e5cb34053257ac23b3eba2 test-only: test(sidebar): require optical badge centering
  • 48afd299ff8bd8e8f893cb6c05fd1d9e6229cc6b fix: fix(sidebar): optically center unread badge ink

Hosted proof:

Dogfood/preflight:

  • Cloud reload tag: badge-optic-48.
  • Preflighted the AppKit left-sidebar unread row path in the tagged app by creating an unread workspace and capturing artifacts/badge-optic-48/sidebar-preflight.png.
  • Using one raw-pixel bright-ink centroid convention: supplied capture drift was about +1.20 px; tagged AppKit row screenshot drift is about +0.19 px.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Final gray Liquid Glass round

Head: 7ca67e3ccb1dc8b39920e37053560814d9a68167

  • New and untouched-default sidebars use native AppKit Liquid Glass, neutral #808080 tint at 18%, and within-window blending.
  • Workspace rows use 10-point continuous corners. Group headers use 8-point corners. Both render a semantic 7% label-color hover wash.
  • The version-2 migration updates only the exact previous Native Sidebar defaults and preserves customized appearance values.
  • Fresh tagged runtime confirmed liquidGlass, #808080, withinWindow, and migration version 2. Computer Use verified workspace and group hover, aligned pins, Markdown labels, right-sticky unread badge, and rounded selection.

Proof:

@lawrencecchen lawrencecchen changed the title Refine AppKit sidebar appearance Redesign AppKit sidebar groups and live reordering Aug 5, 2026
@cursor

cursor Bot commented Aug 5, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this from Todo to Done in cmux backlog Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants