Skip to content

Fix notification Settings open path - #4456

Merged
lawrencecchen merged 9 commits into
mainfrom
task-fix-settings-open-lag
May 21, 2026
Merged

lawrencecchen merged 9 commits into
mainfrom
task-fix-settings-open-lag

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented May 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Open notification permissions with the modern app-specific System Settings URL.
  • Defer browser history/import work until Browser settings is selected, run browser detection off the main actor, and show a loading state while installed browsers are detected.
  • Keep Settings scroll content eager so section deep links/search jumps remain reliable.
  • Localize the new browser detection loading state across the string catalog locales.

Testing

  • jq empty Resources/Localizable.xcstrings
  • xcodebuildmcp macos test --project-path cmux.xcodeproj --scheme cmux-unit --configuration Debug --derived-data-path /tmp/cmux-settings-open-lag-loading-test --extra-args=-only-testing:cmuxTests/SettingsWindowPresenterTests --extra-args=-only-testing:cmuxTests/NotificationDockBadgeTests/testNotificationSettingsPromptUsesSheetAndNeverRunsModal --extra-args=-only-testing:cmuxTests/NotificationDockBadgeTests/testNotificationSettingsOpenFallsBackWhenPrimaryURLFails
  • xcodebuildmcp macos test --project-path cmux.xcodeproj --scheme cmux-unit --configuration Debug --derived-data-path /tmp/cmux-settings-iterate-test --extra-args=-only-testing:cmuxTests/SettingsWindowPresenterTests --extra-args=-only-testing:cmuxTests/NotificationDockBadgeTests/testNotificationSettingsPromptUsesSheetAndNeverRunsModal --extra-args=-only-testing:cmuxTests/NotificationDockBadgeTests/testNotificationSettingsPromptRetriesUntilWindowExists
  • ./scripts/reload.sh --tag setopen

Note

The first focused test command above was run before the review-fix commit that removed fallback-chain testing. The second focused test command covers the current notification and Settings presenter code.

Task

Plain-text task: opening in settings does not work and sometimes is very laggy.


Note

Medium Risk
Touches Settings navigation/rendering and moves browser detection to detached async work; mistakes could cause missing/incorrect UI state or stale results. Notification settings URL behavior changes but is localized to opening System Settings.

Overview
Fixes notification Settings opening by generating a modern, app-specific System Settings URL (with a safe fallback) via TerminalNotificationStore.notificationSettingsURL, and updates tests to validate the new URL and reset injected hooks.

Reduces Settings lag by lazy-loading browser history and installed-browser detection: history now loads only when the Browser History row is near-visible/targeted, and browser import detection runs off the main actor with a loading subtitle, disabled refresh while detecting, and generation-based result de-staling. Adds SettingsLazyLoadHelpers (preference/coordinate-space markers) and new localized strings for the loading states.

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

Summary by CodeRabbit

  • New Features

    • Settings now lazy-load browser history and browser-import detection (triggered by navigation or scroll proximity) with status indicators and disabled actions until ready.
    • Added localized strings for browser-import and history loading states.
  • Bug Fixes

    • Improved notification settings URL handling for more reliable opening.
  • Tests

    • Hardened notification-settings tests for isolation and less brittle URL expectations.

Review Change Stack

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

@vercel

vercel Bot commented May 21, 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 21, 2026 2:24am
cmux-staging Building Building Preview, Comment May 21, 2026 2:24am

@coderabbitai

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

TerminalNotificationStore computes & opens candidate notifications URLs; SettingsView adds lazy-load plumbing, one-time gating flags, and runs browser-import detection in a detached task with a generation guard; UI, tests, localization, and Sendable conformances updated.

Changes

Settings and Notification changes

Layer / File(s) Summary
Notification settings opener and debug hook
Sources/TerminalNotificationStore.swift
openNotificationSettings() uses notificationSettingsURL(bundleIdentifier:) and opens the first valid URL; debug/test reset uses NSWorkspace.shared.open(url) opener.
Notification settings tests
cmuxTests/NotificationAndMenuBarTests.swift
Tests add teardown blocks to reset notification hooks and derive expected URL from TerminalNotificationStore.notificationSettingsURL(bundleIdentifier:); one test supplies a failing urlOpener hook.
SwiftUI lazy-load helpers and project wiring
Sources/SettingsLazyLoadHelpers.swift, cmux.xcodeproj/project.pbxproj
Add named coordinate space, SettingsLazyLoadTrigger enum, SettingsLazyLoadFramePreferenceKey, SettingsLazyLoadMarker, View.settingsLazyLoadTrigger(_:), and wire the new source into the Xcode project.
Settings state, navigation prep, and lazy-load integration
Sources/cmuxApp.swift
Add one-time gating flags (didLoadBrowserHistoryForSettings, didRequestBrowserImportDetection), call prepareSettingsSectionIfNeeded before navigation effects, wrap the settings scroll in a coordinate-space + onPreferenceChange to drive lazy-load triggers, seed state from BrowserHistoryStore.shared.isLoaded, show checking/loading subtitles, disable buttons while loading, add accessibility identifiers, and run browser-import detection in a generation-guarded detached task.
Localization and Sendable model conformance
Resources/Localizable.xcstrings, Sources/Panels/BrowserPanel.swift
Add settings.browser.import.detecting and settings.browser.history.subtitleLoading localized strings; expose BrowserHistoryStore.isLoaded; mark browser-import model types as Sendable; add InstalledBrowserDetector.applicationBundleLookupSnapshot().

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped through candidates until one opened wide,
A tiny Bool decided which path I’d ride.
I wait once, I scan, I guard stale returns,
Detached I work while the main actor learns.
Joyful rabbit, async tidy — then hide.


Caution

Pre-merge checks failed

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

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error Two new xcstrings entries include 'km' locale unsupported elsewhere in the catalog (only in 2/2071 entries). Violates rule requiring new locales to update all affected entries. Remove 'km' from both new entries, keeping only the 19 standard locales, OR add 'km' to all 2069 other xcstrings entries if intentionally expanding catalog support.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (15 passed)
Check name Status Explanation
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 MainActor classes properly annotated, Sendable types immutable, background detection uses proper MainActor.run isolation for updates.
Cmux Swift Blocking Runtime ✅ Passed PR introduces no new blocking patterns. Browser detection uses Task.detached with proper async concurrency. Pre-existing timing patterns (asyncAfter) remain unchanged.
Cmux No Hacky Sleeps ✅ Passed PR contains only Swift files and Xcode project config. Check applies exclusively to TypeScript, JavaScript, shell, and non-Swift build/runtime scripts; Swift is out of scope per the rule definition.
Cmux Swift Concurrency ✅ Passed Proper Task.detached lifecycle via isDetectingImportBrowsers flag and generation counter. Added Sendable conformances. No new DispatchQueue.global, Combine state, or completion-handler APIs.
Cmux Swift @Concurrent ✅ Passed Task.detached provides explicit actor hops for file-I/O work, types are Sendable-conforming, @MainActor annotations are correct, and no @concurrent annotation violations exist.
Cmux Swift File And Package Boundaries ✅ Passed SettingsLazyLoadHelpers.swift (40 lines) is pure UI infrastructure. File additions are small: +7, +98, +15 lines respectively—all under 250-line threshold for oversized files.
Cmux Swift Logging ✅ Passed No Swift logging violations found. New code in TerminalNotificationStore, SettingsLazyLoadHelpers, and cmuxApp contains no print, debugPrint, dump, or improper NSLog statements.
Cmux User-Facing Error Privacy ✅ Passed No user-facing errors, alerts, or text expose sensitive information: new strings are generic loading indicators, notification URL is internal API use only, and logging is not user-visible.
Cmux Swiftui State Layout ✅ Passed Uses @State value snapshots not store refs, GeometryReader for measurement not layout, state mutations only in callbacks, concurrent types marked Sendable.
Cmux Architecture Rethink ✅ Passed Lazy-loaded settings with proper async work (Task.detached), Sendable conformances, clear ownership hierarchy. No timing repairs, split lifecycle, or new observers. Follows allowed patterns.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR introduces no new NSWindow, NSPanel, NSWindowController, SwiftUI Window, or WindowGroup declarations; only lazy-loading enhancements within the existing Settings window.
Title check ✅ Passed The title 'Fix notification Settings open path' directly addresses the primary change: fixing the notification settings deep-link URL opening mechanism to use the modern app-specific System Settings URL instead of a hardcoded endpoint.
Description check ✅ Passed The pull request description includes all required sections: a concise summary of changes, testing methodology with specific test commands and verification steps, and a complete checklist with items marked.
✨ 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 task-fix-settings-open-lag

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.

@greptile-apps

greptile-apps Bot commented May 21, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes notification Settings deep-linking by switching to the modern app-specific URL (x-apple.systempreferences:…?id=<bundle-id>) and reduces Settings UI lag by deferring browser history loading and browser import detection until the relevant section is navigated to or scrolled near.

  • Notification URL fix: notificationSettingsURL now builds an app-specific ?id=<percent-encoded-bundle-id> URL with a generic pane fallback when bundle ID is unavailable; the previously unreachable fallback chain is removed and tests are updated.
  • Scroll-proximity lazy loading: A new SettingsLazyLoadMarker + PreferenceKey system reports each section's frame relative to a named ScrollView coordinate space; onPreferenceChange triggers loadBrowserHistoryForSettingsIfNeeded() and refreshDetectedImportBrowsersIfNeeded() when the section enters the preload window. Navigation deep-links call the same helpers eagerly via prepareSettingsDestinationIfNeeded.
  • Async browser detection: refreshDetectedImportBrowsers now runs InstalledBrowserDetector.detectInstalledBrowsers in Task.detached (after snapshotting NSWorkspace bundle lookups on the main actor), writing results back via MainActor.run with a generation guard; four cross-actor value types gain Sendable; VStack is deliberately kept over LazyVStack so all scrollTo anchors remain immediately registered.

Confidence Score: 5/5

Safe to merge — the notification URL change is narrow and tested, lazy-load deferred state is correctly guarded, and async browser detection uses Task.detached with proper MainActor hand-off.

All previously flagged concerns have been resolved in this revision: the DispatchQueue-based detection was replaced with Task.detached, the unreachable fallback chain was removed, missing locale translations were backfilled across all 20 supported locales, and scroll-proximity triggering was added for browser history so it is no longer navigation-only. No new correctness or concurrency issues were introduced.

No files require special attention.

Important Files Changed

Filename Overview
Sources/cmuxApp.swift Wraps SettingsView body in GeometryReader to get viewport height, attaches onPreferenceChange scroll-proximity detector, defers browser history loading and browser import detection until the relevant section is navigated to or scrolled near, and moves InstalledBrowserDetector to Task.detached with a generation guard. VStack is intentionally kept to preserve eager scrollTo anchor registration.
Sources/SettingsLazyLoadHelpers.swift New 40-line helper: named coordinate space constant, SettingsLazyLoadTrigger enum, a PreferenceKey accumulating trigger→CGRect mappings, and a GeometryReader-backed marker view placed as .background. Clean and self-contained.
Sources/TerminalNotificationStore.swift Replaces the unreachable fallback-chain URL with a single modern x-apple.systempreferences:com.apple.Notifications-Settings.extension?id= URL; falls back to the pane root when bundle id is unavailable. Correctly URL-encodes the bundle identifier with .urlQueryAllowed.
Sources/Panels/BrowserPanel.swift Adds isLoaded accessor on BrowserHistoryStore, Sendable conformances on four value types that cross actor boundaries in Task.detached, and a @mainactor applicationBundleLookupSnapshot() helper that snapshots NSWorkspace bundle lookups before the detached task runs.
Resources/Localizable.xcstrings Adds settings.browser.import.detecting and settings.browser.history.subtitleLoading with translations for all 20 supported locales (including the new km/Khmer locale introduced in this PR). Previously-flagged missing-locale concern is fully resolved.
cmuxTests/NotificationAndMenuBarTests.swift Updates URL assertion to match the new ?id= format and adds addTeardownBlock to resetNotificationSettingsPromptHooksForTesting for better test isolation.
cmux.xcodeproj/project.pbxproj Adds SettingsLazyLoadHelpers.swift to both the file references and the app target's compile sources phase.

Sequence Diagram

sequenceDiagram
    participant User
    participant SettingsView
    participant ScrollProxy as ScrollView / GeometryReader
    participant LazyMarker as SettingsLazyLoadMarker
    participant BrowserHistoryStore
    participant InstalledBrowserDetector

    User->>SettingsView: Open Settings (any section)
    SettingsView->>ScrollProxy: coordinateSpace(.named("SettingsScrollCoordinateSpace"))
    Note over LazyMarker: .background(SettingsLazyLoadMarker) on history card and import card

    LazyMarker-->>ScrollProxy: preference(frames: [.browserHistory: rect, .browserImport: rect])
    ScrollProxy-->>SettingsView: onPreferenceChange fires
    SettingsView->>SettingsView: handleSettingsLazyLoadFrames(frames, viewportHeight)

    alt Section is near viewport
        SettingsView->>BrowserHistoryStore: loadIfNeeded()
        BrowserHistoryStore-->>SettingsView: "$entries published → didLoadBrowserHistoryForSettings = true"
        SettingsView->>InstalledBrowserDetector: "applicationBundleLookupSnapshot() @MainActor"
        SettingsView->>InstalledBrowserDetector: Task.detached detectInstalledBrowsers(snapshot)
        InstalledBrowserDetector-->>SettingsView: "MainActor.run { detectedImportBrowsers = result }"
    end

    User->>SettingsView: Navigate via deep link to .browserImport
    SettingsView->>SettingsView: prepareSettingsDestinationIfNeeded(destination)
    SettingsView->>InstalledBrowserDetector: refreshDetectedImportBrowsersIfNeeded()
Loading

Reviews (7): Last reviewed commit: "Keep Browser settings navigation lazy" | Re-trigger Greptile

Comment thread Sources/cmuxApp.swift Outdated
Comment thread Sources/TerminalNotificationStore.swift Outdated

@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 (1)
Sources/cmuxApp.swift (1)

5799-5804: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Don’t put AuthSettingsRow’s @ObservedObject under the new LazyVStack.

This container change now places AuthSettingsRow(authManager: authManager) inside a lazy stack even though that row owns @ObservedObject var authManager. In this repo, lazy containers should receive value snapshots and action closures rather than ObservableObject stores. Either keep this stack eager or refactor AuthSettingsRow to take immutable auth state plus callbacks.

Based on learnings: "In this repo’s SwiftUI views, any view placed under LazyVStack, LazyHStack, List, or ForEach must not capture or hold ObservableObject store instances..."

🤖 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 `@Sources/cmuxApp.swift` around lines 5799 - 5804, You moved
AuthSettingsRow(authManager: authManager) into a LazyVStack which incorrectly
lets that view retain an `@ObservedObject`; either revert to an eager container
(put AuthSettingsRow back outside LazyVStack) or refactor AuthSettingsRow to
accept immutable auth state plus action callbacks instead of an
ObservableObject. Specifically, change AuthSettingsRow to remove its
`@ObservedObject` authManager dependency (or create a new init that takes a
snapshot model and closures for actions), update call sites (the LazyVStack
location using AuthSettingsRow(authManager: authManager)) to pass a plain
snapshot struct and closures, or restore the previous non-lazy container so
AuthSettingsRow keeps using `@ObservedObject` as before. Ensure references to
AuthSettingsRow and the authManager store are the only symbols modified.
🤖 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 `@Sources/cmuxApp.swift`:
- Around line 5799-5804: You moved AuthSettingsRow(authManager: authManager)
into a LazyVStack which incorrectly lets that view retain an `@ObservedObject`;
either revert to an eager container (put AuthSettingsRow back outside
LazyVStack) or refactor AuthSettingsRow to accept immutable auth state plus
action callbacks instead of an ObservableObject. Specifically, change
AuthSettingsRow to remove its `@ObservedObject` authManager dependency (or create
a new init that takes a snapshot model and closures for actions), update call
sites (the LazyVStack location using AuthSettingsRow(authManager: authManager))
to pass a plain snapshot struct and closures, or restore the previous non-lazy
container so AuthSettingsRow keeps using `@ObservedObject` as before. Ensure
references to AuthSettingsRow and the authManager store are the only symbols
modified.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3c14da5f-3d2a-4cc6-926e-437fb6bcd332

📥 Commits

Reviewing files that changed from the base of the PR and between bf5bc8d and 2c4f90e.

📒 Files selected for processing (1)
  • Sources/cmuxApp.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.

No issues found across 3 files

Re-trigger cubic

Comment thread Sources/cmuxApp.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.

1 issue found across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread Sources/cmuxApp.swift Outdated
Comment thread Resources/Localizable.xcstrings
coderabbitai[bot]
coderabbitai Bot previously requested changes May 21, 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 `@Resources/Localizable.xcstrings`:
- Around line 8735-8763: The new localization key
settings.browser.import.detecting in Resources/Localizable.xcstrings only has
en/ja/uk/ko entries; add this key with translated stringUnit values for every
locale present in this catalog (i.e., all existing locale keys used elsewhere in
Resources/Localizable.xcstrings) following the repo’s fallback convention where
a translation is unavailable. Locate the block for
settings.browser.import.detecting and add matching "stringUnit" objects for each
supported locale, setting "state" consistent with other entries and using the
accepted fallback text when a translation isn’t provided.
🪄 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: c5b8b6d2-2745-4005-98d4-923c02ce4c03

📥 Commits

Reviewing files that changed from the base of the PR and between 2c4f90e and c6f31f4.

📒 Files selected for processing (3)
  • Resources/Localizable.xcstrings
  • Sources/Panels/BrowserPanel.swift
  • Sources/cmuxApp.swift

Comment thread Resources/Localizable.xcstrings
Comment thread Sources/cmuxApp.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.

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

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

Re-trigger cubic

Comment thread Sources/TerminalNotificationStore.swift
Comment thread Sources/cmuxApp.swift
coderabbitai[bot]
coderabbitai Bot previously requested changes May 21, 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

Caution

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

⚠️ Outside diff range comments (1)
Sources/cmuxApp.swift (1)

5787-5792: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Don't mark browser history as loaded before the store is actually loaded.

didLoadBrowserHistoryForSettings is set to true before BrowserHistoryStore.shared.isLoaded becomes the source of truth, so the loading subtitle and disabled state can disappear while history is still loading. It also trips the one-shot guard even if loadIfNeeded() doesn't complete immediately.

Proposed fix
 private func loadBrowserHistoryForSettingsIfNeeded() {
     guard !didLoadBrowserHistoryForSettings else { return }
-    didLoadBrowserHistoryForSettings = true
     BrowserHistoryStore.shared.loadIfNeeded()
-    browserHistoryEntryCount = BrowserHistoryStore.shared.entries.count
+    didLoadBrowserHistoryForSettings = BrowserHistoryStore.shared.isLoaded
+    if didLoadBrowserHistoryForSettings {
+        browserHistoryEntryCount = BrowserHistoryStore.shared.entries.count
+    }
 }
🤖 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 `@Sources/cmuxApp.swift` around lines 5787 - 5792, The guard in
loadBrowserHistoryForSettingsIfNeeded() sets didLoadBrowserHistoryForSettings =
true before the store actually finishes loading; change the flow so you call
BrowserHistoryStore.shared.loadIfNeeded() first and only set
didLoadBrowserHistoryForSettings after the store reports it's loaded (e.g., by
checking BrowserHistoryStore.shared.isLoaded after loadIfNeeded() returns or by
using the store's completion/notification callback), and update
browserHistoryEntryCount from BrowserHistoryStore.shared.entries only after the
store is confirmed loaded; keep the one-shot guard but move the flag assignment
to the post-load path so the subtitle/disabled state don't disappear
prematurely.
🤖 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 `@Resources/Localizable.xcstrings`:
- Around line 8737-8851: The two new localization keys
settings.browser.import.detecting and settings.browser.history.subtitleLoading
are missing a Khmer (km) entry in Resources/Localizable.xcstrings which breaks
the full-locale requirement; add a km localization block for each key matching
the existing per-locale structure (i.e., "km": { "stringUnit": { "state":
"translated", "value": "…" } }) and supply appropriate Khmer translations (or
approved placeholder translated text) for both keys so they mirror the other
locales' entries and satisfy the catalog's fallback convention.

In `@Sources/cmuxApp.swift`:
- Around line 5006-5043: Move the Settings lazy-load helpers into a new Swift
source file: create a new file (e.g., SettingsLazyLoadHelpers.swift), add import
SwiftUI, and paste the following types and extension with the same names so
callers remain unchanged: SettingsScrollCoordinateSpace,
SettingsLazyLoadTrigger, SettingsLazyLoadFramePreferenceKey,
SettingsLazyLoadMarker, and the View extension settingsLazyLoadTrigger(_:).
Ensure you preserve the existing access levels (internal/fileprivate) and API
surface so references in cmuxApp.swift compile, then remove these definitions
from cmuxApp.swift to reduce file size.

---

Outside diff comments:
In `@Sources/cmuxApp.swift`:
- Around line 5787-5792: The guard in loadBrowserHistoryForSettingsIfNeeded()
sets didLoadBrowserHistoryForSettings = true before the store actually finishes
loading; change the flow so you call BrowserHistoryStore.shared.loadIfNeeded()
first and only set didLoadBrowserHistoryForSettings after the store reports it's
loaded (e.g., by checking BrowserHistoryStore.shared.isLoaded after
loadIfNeeded() returns or by using the store's completion/notification
callback), and update browserHistoryEntryCount from
BrowserHistoryStore.shared.entries only after the store is confirmed loaded;
keep the one-shot guard but move the flag assignment to the post-load path so
the subtitle/disabled state don't disappear prematurely.
🪄 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: 9bc37765-fb0c-4076-8940-b87badff557b

📥 Commits

Reviewing files that changed from the base of the PR and between c6f31f4 and d9ccf33.

📒 Files selected for processing (5)
  • Resources/Localizable.xcstrings
  • Sources/Panels/BrowserPanel.swift
  • Sources/TerminalNotificationStore.swift
  • Sources/cmuxApp.swift
  • cmuxTests/NotificationAndMenuBarTests.swift

Comment thread Resources/Localizable.xcstrings
Comment thread Sources/cmuxApp.swift Outdated

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 134ccec. Configure here.

Comment thread cmuxTests/NotificationAndMenuBarTests.swift Outdated
Comment thread Sources/cmuxApp.swift
@lawrencecchen
lawrencecchen dismissed stale reviews from coderabbitai[bot] and coderabbitai[bot] May 21, 2026 03:02

Superseded by commits 134ccec, da554c8, and 4537321. Current CodeRabbit check is passing/skipped, related threads are resolved, hosted checks are green, and Codex review is clean.

@lawrencecchen
lawrencecchen merged commit 4e790a2 into main May 21, 2026
23 checks passed
@lawrencecchen
lawrencecchen deleted the task-fix-settings-open-lag branch May 21, 2026 07:48
@austinywang austinywang mentioned this pull request May 22, 2026

This branch was successfully deployed

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