Locale initialization on the main thread (os.locale.ensureLocale /
NSLocale._preferredLanguages) can race with Sentry's background
init thread calling posix.getenv, causing a SIGSEGV and leaving
the SDK disabled.
Related to #836
* Add i18n infrastructure with String Catalog and Japanese translations
Introduce String Catalog (.xcstrings) for localization support:
- Localizable.xcstrings: 195 UI string entries with en and ja translations
- InfoPlist.xcstrings: Info.plist strings (microphone usage, Finder menu items)
- project.pbxproj: add xcstrings to build phase and ja to knownRegions
* Replace hardcoded UI strings with String(localized:defaultValue:)
Migrate all user-facing strings across 11 source files to use
String(localized:defaultValue:) API (macOS 13+). Each string references
a key in Localizable.xcstrings, with the English text preserved as
defaultValue for fallback.
Files modified:
- KeyboardShortcutSettings: 28 shortcut labels
- SocketControlSettings: mode names and descriptions
- TabManager: placement labels, color names, close dialogs
- BrowserPanel/BrowserPanelView: error pages, context menus, tooltips
- UpdateViewModel/UpdatePopoverView/UpdatePill: update UI states
- NotificationsPage: notification panel labels
- SurfaceSearchOverlay: search bar placeholder and tooltips
- AppDelegate: menus, dialogs, command palette items
* Fix localization gaps from review feedback
Address review comments from CodeRabbit, Greptile, and Cubic Dev AI:
- Use interpolated String(localized:) instead of concatenation for
version/progress strings in UpdateViewModel
- Localize remaining hardcoded strings in AppDelegate: window labels,
rename dialog, status menu items, unread notification count
- Localize insecure HTTP alert body in BrowserPanel
- Add 12 new entries to Localizable.xcstrings with Japanese translations
* Fix String(localized:defaultValue:) keys to use StaticString
The localized: parameter requires StaticString when defaultValue: is
used. Move string interpolation from the key to defaultValue only,
and revert maxWidthText to plain strings since they are only used for
layout width calculation.
* Localize remaining UI strings across all source files
Add String(localized:defaultValue:) to all user-facing strings in:
- cmuxApp.swift: settings screen, menus, about panel, dialogs (~180 strings)
- ContentView.swift: command palette, sidebar context menu, dialogs (~200 strings)
- Workspace.swift: rename/move/close tab dialogs, tooltips (~20 strings)
- UpdateTitlebarAccessory.swift: titlebar tooltips, notifications popover (~10 strings)
- TerminalNotificationStore.swift: notification permission dialog (4 strings)
- CmuxWebView.swift: browser context menu items (2 strings)
- AppDelegate.swift: CLI install/uninstall alerts (6 strings)
Add 418 new entries to Localizable.xcstrings with Japanese translations.
Extract sidebar context menu into separate @ViewBuilder to fix Swift
type-checker timeout in large body.
Fix xcstrings format specifiers for interpolated strings (%lld, %@).
Total: 624 localization entries covering the full UI.
* Address review feedback: fix missing localizations and terminology
- Localize javaScriptDialogTitle URL branch in BrowserPanel
- Localize cantReach error message in BrowserPanel
- Localize close other tabs dialog message in TabManager
- Localize workspace accessibility label in ContentView
- Fix unread notification singular/plural (split into two keys)
- Fix insecure connection apostrophe inconsistency (unify to U+2019)
- Rename socketControl.fullOpen.description to socketControl.allowAll.description
- Remove dead code: renameTargetNoun function
- Fix terminology inconsistencies in xcstrings:
- Unify "Developer Tools" to デベロッパツール
- Unify "Jump to Latest Unread" phrasing
- Unify "Flash Focused Panel" terminology
- Fix dialog.enableNotifications.notNow translation
* fix: address remaining PR 819 review feedback
* fix: use a single localized key for close-other-tabs
* fix: avoid inflection markup in close-other-tabs message
* Address review feedback: localize tooltip, fix subtitle concat, unify keys
- Localize menubar tooltip unread count (hardcoded English -> localized)
- Replace subtitle string concatenation anti-pattern with single localized
keys containing interpolation placeholders
- Unify workspace fallback key to workspace.displayName.fallback
- Remove unused workspace.defaultName key from xcstrings
- Add Japanese translations for new tooltip and subtitle keys
* Add customizable notification sound setting
Adds a "Notification Sound" picker in Settings > App that lets users
choose from macOS system sounds (Default, Basso, Blow, Glass, etc.)
or silence notifications entirely with "None".
Closes https://github.com/manaflow-ai/cmux/issues/608
* Add custom notification command with env vars and sound preview
Users can set a shell command in Settings > App > Notification Command
that runs on every notification. CMUX_NOTIFICATION_TITLE,
CMUX_NOTIFICATION_SUBTITLE, and CMUX_NOTIFICATION_BODY env vars are
set. Also adds a play button to preview system sounds and docs.
* Add keyboard copy mode for terminal scrollback
* Show vim copy mode indicator in terminal
* Fix vi copy-mode symbol keys and pending yank handling
* Refine copy-mode badge wording and font
* Rename keyboard copy-mode badge to VI MODE
* Address PR feedback for copy-mode routing and keyup handling
* Refresh copy-mode viewport row after scrolling
* Add workspace-churn typing lag regression and fix
* Fix CI build for debug stress split calls
* Stabilize lag regression gate for low baseline latency
Set isTemplate = true on the menu bar icon image so macOS automatically
renders it black in light mode and white in dark mode. Changed the glyph
fill from white to black per template image convention.
Closes https://github.com/manaflow-ai/cmux/issues/737
* Add dark mode app icon variant for macOS Sequoia
Adds dark appearance entries to the AppIcon asset catalog so macOS 15+
automatically shows a dark-background icon when the system is in dark
mode. The chevron gradient and glow are preserved by recompositing the
foreground over a dark background (#1C1C1E).
Includes a generation script (scripts/generate_dark_icon.py) that
derives the dark PNGs from the light originals.
* Add icon picker in Settings and fix dark icon quality
Use the Figma chevron layer (design/cmux-icon-chevron.png) composited
over a dark background for pixel-perfect results, no white halo or
darkened gradient. Falls back to mathematical recomposition if the Figma
layer is missing.
Add an "App Icon" picker to Settings (under Theme) with three visual
options: Automatic (follows system appearance via asset catalog dark
variants on macOS 15+), Light, and Dark. The selection persists via
UserDefaults and is applied on launch in AppDelegate.ensureApplicationIcon.
* Fix dark icon chevron scale to match light icon
The Figma export was ~25% larger than the repo icon. Scale the Figma
chevron layer by 0.80x before compositing so the chevron size matches
exactly between light and dark variants.
* Use enhanced glow for dark icon
Add a soft blue bloom around the chevron on the dark background using
two Gaussian blur passes (wide at r=25 and tight at r=12) composited
at reduced opacity beneath the sharp chevron. Makes the icon pop more
against the dark squircle.
* Set cmux TestAction to Debug for UI tests
* Broaden XCTest detection for debug launch gate
* Fix AutomationSocketUITests launch hang in CI
* Stabilize CI Swift package resolution for test jobs
* Stabilize Xcode Cloud UI test focus and socket handling
* Add Xcode Cloud pre-xcodebuild submodule bootstrap
* Harden Xcode Cloud bonsplit bootstrap fallback
Adds CmuxCLIPathInstaller with symlink management at /usr/local/bin/cmux,
exposed via Cmd+Shift+P command palette (VS Code style). Install entry
shown when CLI is not in PATH, uninstall entry shown when it is.
Falls back to osascript admin privilege escalation when /usr/local/bin
is not user-writable. Uses attributesOfItem instead of fileExists to
correctly handle dangling symlinks from relocated app bundles.
Closes https://github.com/manaflow-ai/cmux/issues/618
Cmd+Shift+Enter toggles zoom on the focused pane, expanding it to fill
the workspace. Splitting or creating new tabs auto-unzooms. Zoom state
shown as icon in sidebar tab. Includes bonsplit zoom toggle support.
Closes https://github.com/manaflow-ai/cmux/issues/136
All four switch statements (case list, commandPaletteTitle,
commandPaletteKeywords, applicationBundlePathCandidates) are now
in consistent alphabetical order.
Adds a "Send anonymous telemetry" toggle in Settings that lets users
disable Sentry crash reporting and PostHog analytics. The setting is
frozen at launch so toggling mid-session shows a restart hint. The hint
correctly clears if the user toggles back to the launch-time value.
cmux_daily_active deduplicates by UTC date, so PostHog hourly retention
cohorts show 0s. Add a companion cmux_hourly_active event that fires at
most once per UTC hour, deduped via UserDefaults. No flush() after
hourly events (let them batch). The existing 30-minute timer provides
adequate hour-boundary coverage without changes.
Cmd-based keyboard shortcuts (Cmd+T, Cmd+Shift+L, etc.) were blocked
while an IME had active composition (marked text), affecting Chinese
Pinyin, Japanese, Korean, and all other input methods. Since Cmd is a
system modifier never consumed by IME input sequences, exempt
Cmd-modified events from the three IME bypass points in the key event
chain.
Fixes#440
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>