Skip to content

Add quick terminal - #4830

Closed
austinywang wants to merge 21 commits into
mainfrom
issue-327-does-cmux-support-quick-terminal
Closed

austinywang wants to merge 21 commits into
mainfrom
issue-327-does-cmux-support-quick-terminal

Conversation

@austinywang

@austinywang austinywang commented May 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Adds a Ghostty-style Quick Terminal panel with configurable position, size, and auto-hide settings.
  • Wires the shared toggle through the system-wide Option-Command-backtick hotkey, View menu, command palette, socket API, and cmux quick-terminal CLI.
  • Documents the shortcut/config keys and updates the changelog.

Fixes #327
Related: #1523, #1712

Regression coverage

  • Commit 1 adds quick terminal settings/frame coverage before the implementation so the branch has the requested failing-test-first shape.
  • The implementation commit adds shortcut/settings-file coverage for the system-wide quick terminal hotkey.

Verification

  • git diff --check
  • JSON parse check for Resources/Localizable.xcstrings and web/data/cmux.schema.json

Local builds/tests were not run per task instructions; HQ should run:
CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag issue-327-does-cmux-support-quick-terminal --launch


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.


Note

Medium Risk
Introduces a system-wide hotkey, floating window focus/restore behavior, and a separate terminal surface with shared port allocation—moderate UX and integration risk, not security-critical.

Overview
Adds a Quick Terminal: a floating Ghostty terminal panel you can summon from anywhere on macOS, with slide-in animation, optional auto-hide on focus loss, and placement/size controlled via settings or cmux.json.

Controls: system-wide **⌥⌘** (registered like global search), in-app shortcut, View menu, command palette, socket methods quick_terminal.*, and **cmux quick-terminal** (toggle/show/hide/status`). New settings cover position (top/bottom/left/right/center), primary/secondary size ratios, and auto-hide; docs, schema, shortcuts page, and changelog are updated.

Implementation notes: QuickTerminalController hosts a dedicated TerminalSurface (CMUX_QUICK_TERMINAL=1) in a borderless panel; port ordinals use shared TabManager.allocatePortOrdinal() so quick terminal ports don’t collide with workspace ranges. Shortcut routing excludes quick terminal from bare-start/chord paths that would break global hotkeys.

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


Summary by cubic

Adds a Ghostty-style Quick Terminal you can drop over any app with a system-wide ⌥⌘` hotkey, View menu, command palette, CLI, or socket API. It’s configurable (position, size ratios, auto-hide) and wired into settings, docs, and tests. Fixes #327.

  • New Features

    • Floating Quick Terminal with positions (top/bottom/left/right/center), primary/secondary size ratios, and optional auto-hide.
    • Controls: system-wide ⌥⌘(configurable), View menu, command palette; CLIcmux quick-terminal [toggle|show|hide|status]with--json; socket API quick_terminal.toggle|show|hide|status`.
    • Settings and docs: quickTerminalPosition, quickTerminalPrimarySizeRatio, quickTerminalSecondarySizeRatio, quickTerminalAutoHide added to Settings UI, cmux.schema.json, README, examples, and localized shortcuts.
  • Bug Fixes

    • Hardened quick terminal focus/exit lifecycle and “restore previous app” behavior on focus changes and child exit.
    • Isolated terminal port ordinals via TabManager.allocatePortOrdinal() to prevent overlapping port ranges across windows.
    • Excluded .toggleQuickTerminal (and .globalSearch) from bare-start routing to keep system-wide hotkeys reliable; added localized settings search aliases; redacted CLI argument errors.

Written for commit eb674c3. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Quick Terminal—a floating terminal panel with system-wide keyboard shortcut (⌥⌘`).
    • Configurable position (top, bottom, left, right, center), sizing, and auto-hide on focus loss.
    • Accessible via command palette and new cmux quick-terminal CLI commands (toggle/show/hide/status).
  • Documentation

    • Updated keyboard shortcuts reference and configuration guide with Quick Terminal examples.
  • Tests

    • Added test coverage for Quick Terminal settings and shortcut handling.

@vercel

vercel Bot commented May 26, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cmux Canceled Canceled Jun 18, 2026 8:01pm
cmux-staging Building Building Preview, Comment Jun 18, 2026 8:01pm

@coderabbitai

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

Adds a Quick Terminal panel feature: a new QuickTerminalController manages an NSPanel-based terminal with configurable position, size ratios, and auto-hide, exposed via a system-wide keyboard shortcut (⌥⌘\``), command palette, main menu, and cmux quick-terminal` CLI/RPC commands. Settings are persisted and configurable via the Settings UI and settings file.

Changes

Quick Terminal Feature

Layer / File(s) Summary
Core Panel Controller & Geometry
Sources/QuickTerminalController.swift, cmuxTests/WorkspaceUnitTests.swift, cmux.xcodeproj/project.pbxproj
Introduces QuickTerminalSettings, QuickTerminalResolvedSettings, QuickTerminalPosition frame geometry, QuickTerminalPanel subclass, and QuickTerminalController with a visibility-phase state machine (hidden/showing/visible/hiding), animated transitions, auto-hide on key resignation, queued pending transitions, lazy panel/surface construction, and screen selection. Unit tests verify settings clamping and finalFrame/hiddenFrame geometry for top and left placements.
Keyboard Shortcut & System-wide Hotkey
Sources/KeyboardShortcutSettings.swift, Sources/App/ShortcutBareStartRouting.swift, cmuxTests/GlobalSearchShortcutSettingsTests.swift
Adds toggleQuickTerminal action case with default ⌘⌥\`` binding, UI label, normalization/persistence exclusion rules matching showHideAllWindows/globalSearch`, and system-wide hotkey registration/enablement/dispatch. Excludes the action from bare-start key caching. Tests cover default binding validity, modifier rejection, and settings-file parsing.
AppDelegate Ownership & Control Surface
Sources/AppDelegate.swift
AppDelegate lazily owns quickTerminalController and teardowns on termination. Exposes toggleQuickTerminalVisibility, showQuickTerminal, hideQuickTerminal, quickTerminalStatusPayload, and an @objc selector. Intercepts .toggleQuickTerminal in handleCustomShortcut before menu dispatch, excludes it from chord/menu-backed routing, and registers cmux.quick-terminal as an auxiliary window identifier.
Menu & Command Palette Entry Points
Sources/ContentView.swift, Sources/ContentView+RightSidebarCommandPalette.swift, Sources/cmuxApp.swift
Registers palette.toggleQuickTerminal as a command palette contribution with localized title/subtitle and search keywords, wires its handler and shortcut-action mapping, and inserts a "Toggle Quick Terminal" split command in the main window menu.
Settings Storage, File Parsing & UI
Sources/cmuxApp.swift, Sources/KeyboardShortcutSettingsFileStore.swift, Sources/KeyboardShortcutSettingsFileStore+Template.swift
Persists Quick Terminal config via @AppStorage (position, size ratios, auto-hide) with clamped bindings and percent-label helpers. Adds Terminal settings UI rows (position picker, size-ratio sliders, auto-hide toggle) and resets to defaults in "Reset All". Parses and validates the four quickTerminal* keys from the settings file with clamping, and includes them in the JSONC template.
CLI Command & RPC Interface
CLI/cmux.swift, Sources/TerminalController.swift
Adds cmux quick-terminal [toggle|show|hide|status] CLI command with socket routing, arg normalization, subcommand validation, and JSON/human-readable output. Registers V2 RPC handlers in TerminalController that call AppDelegate via v2MainSync, returning unavailable errors or status payloads. Updates command whitelists, dispatch switch, and help/index listings.
Documentation, Localization & Schema
Resources/Localizable.xcstrings, README.md, web/data/cmux-shortcuts.ts, web/data/cmux.schema.json, web/app/[locale]/docs/configuration/page.tsx, CHANGELOG.md
Adds Quick Terminal localization strings for all UI labels/settings with extractionState: needs_review for non-English/Japanese. Updates README shortcuts table, extends web JSON schema with four terminal.quickTerminal* fields and toggleQuickTerminal in allowed shortcut bindings, adds web shortcut catalog entry and config doc examples, and documents the feature in CHANGELOG.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant SystemWideHotkey as SystemWideHotkeyController
  participant AppDelegate
  participant QuickTerminalController
  participant TerminalSurface

  User->>SystemWideHotkey: ⌥⌘` pressed
  SystemWideHotkey->>AppDelegate: toggleQuickTerminalVisibility(activateApp: true)
  AppDelegate->>QuickTerminalController: toggle()
  alt currently hidden
    QuickTerminalController->>QuickTerminalController: ensurePanel() – lazy init
    QuickTerminalController->>TerminalSurface: setVisibility(true), becomeActive
    QuickTerminalController->>QuickTerminalController: animate frame + alpha to finalFrame
    QuickTerminalController-->>AppDelegate: visible
  else currently visible
    QuickTerminalController->>QuickTerminalController: animate frame + alpha to hiddenFrame
    QuickTerminalController->>TerminalSurface: setVisibility(false), resignActive
    QuickTerminalController->>QuickTerminalController: finishHide() – orderOut, restore app
    QuickTerminalController-->>AppDelegate: hidden
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • manaflow-ai/cmux#2389: Both PRs extend the shared system-wide hotkey infrastructure in KeyboardShortcutSettings and SystemWideHotkeyController to register and dispatch a new global action, following the same code pattern.
  • manaflow-ai/cmux#2528: Refactors the shortcut routing system (chorded two-stroke shortcuts) that this PR integrates into by explicitly excluding .toggleQuickTerminal from chord-capable actions.

Suggested reviewers

  • lawrencecchen

🐇 A panel slides down with a satisfying swoosh,
One backtick command and the terminal's loose!
Toggle it, show it, or hide it away,
`⌥⌘`` — the rabbit's new favorite key to play.
Quick Terminal's here, no more fuss or delay! 🎉

🚥 Pre-merge checks | ✅ 21 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (21 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add quick terminal' directly and concisely describes the main feature being implemented throughout the changeset.
Linked Issues check ✅ Passed The PR fully implements the requested quick terminal feature with multiple access methods (hotkey, menu, CLI, API), configurability, and documentation, directly addressing issue #327.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the quick terminal feature and its integration across the codebase; no unrelated modifications detected.
Cmux Swift Actor Isolation ✅ Passed QuickTerminalController is properly marked @MainActor. Module-scoped value types (QuickTerminalSettings, QuickTerminalResolvedSettings, QuickTerminalPosition) have no isolation marker, which is acc...
Cmux Swift Blocking Runtime ✅ Passed QuickTerminalController.swift (492 lines) contains no blocking patterns (no sleep, semaphore, mutex, or .sync calls). Animation uses NSAnimationContext.runAnimationGroup with proper completion hand...
Cmux Expensive Synchronous Load ✅ Passed No expensive synchronous loaders like RestorableAgentSessionIndex.load() added to main actor/interactive paths; Quick Terminal code only performs UI animations, UserDefaults reads, and lightweight...
Cmux Cache Substitution Correctness ✅ Passed QuickTerminal settings are always read fresh from UserDefaults via QuickTerminalSettings.resolved(), never cached; no persistence/undo/snapshot paths affected; follows proper fresh-read pattern.
Cmux No Hacky Sleeps ✅ Passed No hacky sleeps, delays, timers, polling, or wall-clock waits found in non-Swift production code. All TypeScript/JSON web files contain pure data or standard async React patterns without timing hacks.
Cmux Algorithmic Complexity ✅ Passed PR contains only fixed-size enum operations, no nested collection scans, and no per-target rescans on user-data collections; NSScreen.screens accessed only as last-resort fallback in user-triggered...
Cmux Swift Concurrency ✅ Passed PR introduces only NSAnimationContext.runAnimationGroup completionHandler usage (AppKit API boundary) with proper MainActor.assumeIsolated isolation; no DispatchQueue, Combine, fire-and-forget Task...
Cmux Swift @Concurrent ✅ Passed All Swift changes properly comply with @concurrent annotation rules: new classes (QuickTerminalController) and modified classes (TerminalController, AppDelegate) maintain @MainActor isolation, all...
Cmux Swift File And Package Boundaries ✅ Passed PR adds 492-line QuickTerminalController.swift (new file, under 800-line threshold with clear single responsibility) and makes targeted additions to existing files (AppDelegate +34, TerminalControl...
Cmux Swiftpm Lockfiles ✅ Passed PR does not modify SwiftPM package dependencies, Package.resolved lockfiles, .gitignore files, or Xcode project package references—only adds a Swift source file to the build phases.
Cmux Swift Logging ✅ Passed New Quick Terminal code follows Swift logging rules: no print/NSLog/debugPrint/dump in app/runtime code, only allowed CLI output via print() in CLI handlers. QuickTerminalController (492 lines) has...
Cmux User-Facing Error Privacy ✅ Passed All user-facing error messages, alerts, and output use generic product-level terms without exposing vendor names, provider details, environment variables, credentials, or other sensitive informatio...
Cmux Full Internationalization ✅ Passed All user-facing Swift text uses String(localized:defaultValue:) with matching Localizable.xcstrings entries for all supported locales. Web shortcuts have translations for all 20 routing.ts locales....
Cmux Swiftui State Layout ✅ Passed The PR's SwiftUI changes (command palette contributions, menu items) follow proper patterns with no state management violations; all new core logic is in pure AppKit QuickTerminalController with no...
Cmux Architecture Rethink ✅ Passed PR implements QuickTerminalController with clean architecture: @MainActor-isolated controller with explicit VisibilityPhase state machine, zero timing patches/polling/locks, single AppDelegate entr...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed QuickTerminalPanel has stable identifier 'cmux.quick-terminal', registered in cmuxAuxiliaryWindowIdentifiers, with close-shortcut routed through cmuxWindowShouldOwnCloseShortcut; no custom Cmd+W wo...
Cmux Source Artifacts ✅ Passed All 20 PR files are hand-written source, tests, configs, localization catalogs, or documentation—no artifacts, caches, build output, or generated files found.
Description check ✅ Passed The PR description comprehensively covers the feature summary, testing approach, regression coverage, and verification steps, closely matching the required template structure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 issue-327-does-cmux-support-quick-terminal

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/AppDelegate.swift Outdated
Comment thread Sources/AppDelegate.swift Outdated
@greptile-apps

greptile-apps Bot commented May 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a Ghostty-style Quick Terminal floating panel (QuickTerminalController) with configurable position, size ratios, and auto-hide, wired through a system-wide ⌥⌘ hotkey, View menu, command palette, socket API (quick_terminal.*), and cmux quick-terminalCLI. Port ordinals are isolated via a newTabManager.allocatePortOrdinal()` helper so the quick terminal doesn't collide with workspace ranges.

  • Sources/QuickTerminalController.swift (new, 501 lines): @MainActor-isolated phase state machine (hidden → showing → visible → hiding) with slide animation, MainActor.assumeIsolated completion handlers, optional screen(for:) returning nil instead of crashing, and a PendingTransitionAction queue for back-to-back toggle calls during animation.
  • Sources/KeyboardShortcutSettings.swift: toggleQuickTerminal registered as a system-wide Carbon hotkey (ID 3), excluded from bare-start chord routing and menu-backed shortcut paths to match the globalSearch treatment.
  • Resources/Localizable.xcstrings / web/messages/*.json: All 19 new string keys carry full 20-locale coverage for main user-facing text; 4 settings search alias keys (settings.search.alias.setting.terminal.quick-terminal-*) have only en+ja entries where 20 are expected.

Confidence Score: 4/5

Safe to merge with one small localization gap to resolve before shipping to non-English/Japanese users.

The core implementation — actor isolation, animation lifecycle, screen-safety, port ordinal allocation, hotkey routing — is solid and the previous-thread concerns have all been addressed. The only remaining gap is that the four settings search alias keys (settings.search.alias.setting.terminal.quick-terminal-*) landed with only en+ja translations while every adjacent key in the same catalog section carries 20 locales. This doesn't break functionality, but it means users in 18 other locales won't find the quick terminal settings via locale-specific search terms.

Resources/Localizable.xcstrings — the four settings.search.alias.setting.terminal.quick-terminal-* entries need the remaining 18 locale translations added.

Important Files Changed

Filename Overview
Sources/QuickTerminalController.swift New 501-line file implementing the Quick Terminal panel lifecycle, animation, and focus handoff. @MainActor-isolated throughout; animation completion handlers use MainActor.assumeIsolated; screen(for:) returns optional instead of preconditionFailure. Phase state machine correctly guards transitions.
Sources/SettingsSearchAliases.swift Adds 4 new quick-terminal search alias entries. All 4 keys are present in Localizable.xcstrings but only with en+ja translations; the existing adjacent key has 20 locale entries. Affects settings discoverability for 18 locales.
Sources/TabManager.swift Introduces allocatePortOrdinal() static method and makes nextPortOrdinal private(set). All allocation sites updated. TabManager is @mainactor so the static method inherits actor isolation correctly.
Sources/TerminalController.swift Adds socket API for quick_terminal.toggle/show/hide/status using the pre-existing v2MainSync pattern. Error messages are cmux-term opaque without internal details.
Sources/KeyboardShortcutSettings.swift Adds toggleQuickTerminal to the Action enum, wires it as a system-wide Carbon hotkey (ID 3), excludes it from bare-start chord routing and menu-backed shortcut paths matching the globalSearch pattern.
Resources/Localizable.xcstrings Adds 19 new quick-terminal string keys. All main user-facing strings have full 20-locale coverage. The 4 settings.search.alias keys have only en+ja.
Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/TerminalCatalogSection.swift Adds four new DefaultsKey entries for quick terminal settings. UserDefaults keys intentionally match the quickTerminal.* namespace used by the runtime.
CLI/cmux.swift Adds cmux quick-terminal [toggle

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[⌥⌘` Global Hotkey] --> T[toggleQuickTerminalVisibility]
    B[View Menu] --> T
    C[Command Palette] --> T
    D[Socket: quick_terminal.toggle] --> T
    E[CLI: cmux quick-terminal] --> D

    T --> QTC[QuickTerminalController.toggle]

    QTC -->|isTransitioning| PQ[pendingTransitionAction queue]
    QTC -->|not visible| SHOW[show]
    QTC -->|visible| HIDE[hide]

    SHOW --> EP[ensurePanel / TerminalSurface]
    EP --> PO[TabManager.allocatePortOrdinal]
    SHOW --> ANIM_IN[NSAnimationContext slide-in]
    ANIM_IN --> VIS[phase = .visible]
    VIS --> FOCUS[makeFirstResponder terminalSurface]

    HIDE --> ANIM_OUT[NSAnimationContext slide-out]
    ANIM_OUT --> FH[finishHide]
    FH --> RESTORE[activate previousFrontmostApp?]
    FH --> PR[replayPendingTransitionAction]

    VIS -->|windowDidResignKey + autoHide| HIDE
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[⌥⌘` Global Hotkey] --> T[toggleQuickTerminalVisibility]
    B[View Menu] --> T
    C[Command Palette] --> T
    D[Socket: quick_terminal.toggle] --> T
    E[CLI: cmux quick-terminal] --> D

    T --> QTC[QuickTerminalController.toggle]

    QTC -->|isTransitioning| PQ[pendingTransitionAction queue]
    QTC -->|not visible| SHOW[show]
    QTC -->|visible| HIDE[hide]

    SHOW --> EP[ensurePanel / TerminalSurface]
    EP --> PO[TabManager.allocatePortOrdinal]
    SHOW --> ANIM_IN[NSAnimationContext slide-in]
    ANIM_IN --> VIS[phase = .visible]
    VIS --> FOCUS[makeFirstResponder terminalSurface]

    HIDE --> ANIM_OUT[NSAnimationContext slide-out]
    ANIM_OUT --> FH[finishHide]
    FH --> RESTORE[activate previousFrontmostApp?]
    FH --> PR[replayPendingTransitionAction]

    VIS -->|windowDidResignKey + autoHide| HIDE
Loading

Reviews (13): Last reviewed commit: "fix: redact CLI argument errors" | Re-trigger Greptile

Comment thread Sources/AppDelegate.swift Outdated
Comment thread Sources/AppDelegate.swift Outdated
Comment thread Sources/AppDelegate.swift Outdated
@austinywang

Copy link
Copy Markdown
Contributor Author

Addressed the Greptile summary localization note in f12cc86: the 19 new Quick Terminal string-catalog keys now include the full supported locale set, with English fallbacks marked needs_review for non-English/Japanese locales and the Japanese strings preserved.

Comment thread Sources/AppDelegate.swift Outdated
Comment thread Sources/QuickTerminalController.swift

@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 `@CHANGELOG.md`:
- Line 8: The new Quick Terminal bullet was added to CHANGELOG.md but you must
also add matching localized changelog entries for every locale defined in
web/i18n/routing.ts; update each locale's localized changelog file (or
localization mapping) with a translated/identical entry for "Quick Terminal
panel with a configurable position/size, Option-Command-backtick shortcut,
command palette action, and `cmux quick-terminal` CLI controls" so the localized
changelog coverage matches the CHANGELOG.md addition and the locales referenced
in web/i18n/routing.ts.

In `@CLI/cmux.swift`:
- Around line 4767-4769: The error currently interpolates and prints the raw
unexpected argument value from remaining.first into CLIError (the string
"quick-terminal \(subcommand): unexpected argument '\(unknown)'"), which can
leak secrets; change this to avoid echoing the raw value by using a sanitized
placeholder or redaction (e.g., "<redacted>" or show only a safe,
truncated/sanitized preview), or report the presence/count of unexpected
arguments instead; update the code that constructs the CLIError message (the
branch that checks remaining.first and creates CLIError) to use the
redacted/safe text rather than the raw unknown variable.

In `@Sources/TerminalController.swift`:
- Around line 11006-11030: The RPC error leaks the internal symbol "AppDelegate"
and conflates a missing delegate with an action failure; update
v2QuickTerminalShow, v2QuickTerminalHide (and the toggle handler if present) to
first check whether AppDelegate.shared is nil and return a
non-implementation-specific error (e.g., code "unavailable" or
"service_unavailable" with a generic message like "service not available") when
the delegate is nil, and otherwise, when the delegate exists but the action
returns false, return a distinct error (e.g., code "action_failed" with message
like "could not show/hide quick terminal") so clients can distinguish
availability from action failure without seeing internal class names. Ensure the
returned messages do not reference "AppDelegate" and use v2QuickTerminalStatus()
only on success.

In `@web/data/cmux.schema.json`:
- Around line 378-402: The new schema properties quickTerminalPosition,
quickTerminalPrimarySizeRatio, quickTerminalSecondarySizeRatio, and
quickTerminalAutoHide currently use English-only description strings; replace
each "description" value with a "descriptionKey" (unique message keys, e.g.
schema.quickTerminal.position, schema.quickTerminal.primarySizeRatio,
schema.quickTerminal.secondarySizeRatio, schema.quickTerminal.autoHide) and add
corresponding translated messages for those keys into every locale file listed
in web/i18n/routing.ts so all docs locales have coverage.
🪄 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: 6d60e8b7-aa9f-46bc-b3f0-bfa3701ffeb0

📥 Commits

Reviewing files that changed from the base of the PR and between 7a688ba and f12cc86.

📒 Files selected for processing (20)
  • CHANGELOG.md
  • CLI/cmux.swift
  • README.md
  • Resources/Localizable.xcstrings
  • Sources/App/ShortcutBareStartRouting.swift
  • Sources/AppDelegate.swift
  • Sources/ContentView+RightSidebarCommandPalette.swift
  • Sources/ContentView.swift
  • Sources/KeyboardShortcutSettings.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/QuickTerminalController.swift
  • Sources/TerminalController.swift
  • Sources/cmuxApp.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/GlobalSearchShortcutSettingsTests.swift
  • cmuxTests/WorkspaceUnitTests.swift
  • web/app/[locale]/docs/configuration/page.tsx
  • web/data/cmux-shortcuts.ts
  • web/data/cmux.schema.json

Comment thread CHANGELOG.md
Comment thread CLI/cmux.swift Outdated
Comment thread Sources/TerminalController.swift Outdated
Comment thread web/data/cmux.schema.json

@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 1 potential issue.

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 0b9e4ec. Configure here.

Comment thread Sources/QuickTerminalController.swift
Comment thread Sources/TabManager.swift
hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request May 28, 2026
PR manaflow-ai#4828 main-window visibility controller renamed to
MainWindowQuickTerminalController/Position to avoid name collision
with PR manaflow-ai#4830's QuickTerminalController (the floating panel with
the global hotkey). AppDelegate now hosts both controllers via
separate lazy vars; teardown/toggle/statusPayload route to the
PR manaflow-ai#4830 controller, while restoreSession/snapshot/closeShortcut
route to the PR manaflow-ai#4828 controller.

Default Quick Terminal hotkey: Option+Cmd+\`

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In
`@Packages/CmuxSettings/Sources/CmuxSettings/Keys/TerminalCatalogSection.swift`:
- Around line 53-75: Add Swift-DocC triple-slash comments for the four new
public DefaultsKey properties (quickTerminalPosition,
quickTerminalPrimarySizeRatio, quickTerminalSecondarySizeRatio,
quickTerminalAutoHide); each comment should include a one-line summary, valid
values/ranges (e.g., allowed position strings, 0.0–1.0 ranges for ratios,
boolean behavior), any relevant notes about interaction (which ratio is
primary/secondary and when secondary is ignored), and a brief example/usage
line. Place the comments immediately above the declarations of
quickTerminalPosition, quickTerminalPrimarySizeRatio,
quickTerminalSecondarySizeRatio, and quickTerminalAutoHide following the
project's DocC style (triple-slash ///) and include defaults where appropriate.
- Around line 53-75: The catalog ids for quickTerminalPosition,
quickTerminalPrimarySizeRatio, quickTerminalSecondarySizeRatio, and
quickTerminalAutoHide use the "terminal.quickTerminal*" namespace but their
userDefaultsKey values drop the "terminal." prefix, causing an inconsistent
mapping; update each DefaultsKey's userDefaultsKey to exactly match its id
(e.g., change "quickTerminal.position" to "terminal.quickTerminalPosition",
"quickTerminal.primarySizeRatio" to "terminal.quickTerminalPrimarySizeRatio",
etc.), or if the differing namespace was intentional, add a brief inline comment
above these four keys explaining why the userDefaultsKey intentionally differs
from the catalog id.
🪄 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: a9d2c8b5-c5d5-4902-92b2-ed1e36f575a2

📥 Commits

Reviewing files that changed from the base of the PR and between f12cc86 and 2f0f0f1.

📒 Files selected for processing (5)
  • CHANGELOG.md
  • CLI/cmux.swift
  • Packages/CmuxSettings/Sources/CmuxSettings/Keys/TerminalCatalogSection.swift
  • Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
  • Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/TerminalSection.swift
💤 Files with no reviewable changes (3)
  • Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swift
  • Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/TerminalSection.swift
  • CLI/cmux.swift

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 4, 2026

@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 50 files

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

Re-trigger cubic

Comment thread Sources/SettingsSearchAliases.swift
…upport-quick-terminal

# Conflicts:
#	Sources/CmuxSettingsJSONPathSupport.swift
#	Sources/TabManager.swift
#	Sources/TerminalController.swift

@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

Caution

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

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

171-178: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Document or extract the magic offset constant.

The + 18 offset for the center position's hidden frame is unexplained. Consider extracting to a named constant or adding a comment explaining its purpose (e.g., if it relates to menu bar clearance or visual aesthetics).

 case .center:
+    // Small offset above screen to ensure panel is fully off-screen during hide
+    let centerHiddenOffset: CGFloat = 18
     return NSRect(
         x: finalFrame.origin.x,
-        y: visibleFrame.maxY + 18,
+        y: visibleFrame.maxY + centerHiddenOffset,
         width: finalFrame.width,
         height: finalFrame.height
     )
🤖 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/QuickTerminalController.swift` around lines 171 - 178, The magic
number 18 in the y-position calculation for the center case position is
unexplained and makes the code harder to understand. Extract this constant to a
named property at the class or file level with a descriptive name that explains
its purpose (such as an offset for menu bar clearance or spacing), and then
replace the hardcoded 18 with a reference to that named constant. Alternatively,
if a constant is not appropriate, add an inline comment above or next to the +
18 offset explaining what it represents and why that specific value is used.
🤖 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 13304-13306: Add the `private` access modifier to the three `@State`
properties workspaceFinderDirectoryOpenRequest, metadataRowsExpanded, and
metadataBlocksExpanded in ContentView.swift to follow SwiftUI conventions and
resolve the SwiftLint warning. If these properties require access from external
code for testing or initialization purposes, you may keep them as
package-internal; otherwise, restore the private access modifier to each
declaration.

---

Outside diff comments:
In `@Sources/QuickTerminalController.swift`:
- Around line 171-178: The magic number 18 in the y-position calculation for the
center case position is unexplained and makes the code harder to understand.
Extract this constant to a named property at the class or file level with a
descriptive name that explains its purpose (such as an offset for menu bar
clearance or spacing), and then replace the hardcoded 18 with a reference to
that named constant. Alternatively, if a constant is not appropriate, add an
inline comment above or next to the + 18 offset explaining what it represents
and why that specific value is used.
🪄 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: 482b6440-aa8d-4206-98ec-a38ba82c8859

📥 Commits

Reviewing files that changed from the base of the PR and between 5af4c24 and 9c48ac0.

⛔ Files ignored due to path filters (1)
  • .github/swift-file-length-budget.tsv is excluded by !**/*.tsv
📒 Files selected for processing (3)
  • Sources/ContentView.swift
  • Sources/QuickTerminalController.swift
  • cmux.xcodeproj/project.pbxproj

@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

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

Caution

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

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

171-178: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Document or extract the magic offset constant.

The + 18 offset for the center position's hidden frame is unexplained. Consider extracting to a named constant or adding a comment explaining its purpose (e.g., if it relates to menu bar clearance or visual aesthetics).

 case .center:
+    // Small offset above screen to ensure panel is fully off-screen during hide
+    let centerHiddenOffset: CGFloat = 18
     return NSRect(
         x: finalFrame.origin.x,
-        y: visibleFrame.maxY + 18,
+        y: visibleFrame.maxY + centerHiddenOffset,
         width: finalFrame.width,
         height: finalFrame.height
     )
🤖 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/QuickTerminalController.swift` around lines 171 - 178, The magic
number 18 in the y-position calculation for the center case position is
unexplained and makes the code harder to understand. Extract this constant to a
named property at the class or file level with a descriptive name that explains
its purpose (such as an offset for menu bar clearance or spacing), and then
replace the hardcoded 18 with a reference to that named constant. Alternatively,
if a constant is not appropriate, add an inline comment above or next to the +
18 offset explaining what it represents and why that specific value is used.
🤖 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 13304-13306: Add the `private` access modifier to the three `@State`
properties workspaceFinderDirectoryOpenRequest, metadataRowsExpanded, and
metadataBlocksExpanded in ContentView.swift to follow SwiftUI conventions and
resolve the SwiftLint warning. If these properties require access from external
code for testing or initialization purposes, you may keep them as
package-internal; otherwise, restore the private access modifier to each
declaration.

---

Outside diff comments:
In `@Sources/QuickTerminalController.swift`:
- Around line 171-178: The magic number 18 in the y-position calculation for the
center case position is unexplained and makes the code harder to understand.
Extract this constant to a named property at the class or file level with a
descriptive name that explains its purpose (such as an offset for menu bar
clearance or spacing), and then replace the hardcoded 18 with a reference to
that named constant. Alternatively, if a constant is not appropriate, add an
inline comment above or next to the + 18 offset explaining what it represents
and why that specific value is used.
🪄 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: 482b6440-aa8d-4206-98ec-a38ba82c8859

📥 Commits

Reviewing files that changed from the base of the PR and between 5af4c24 and 9c48ac0.

⛔ Files ignored due to path filters (1)
  • .github/swift-file-length-budget.tsv is excluded by !**/*.tsv
📒 Files selected for processing (3)
  • Sources/ContentView.swift
  • Sources/QuickTerminalController.swift
  • cmux.xcodeproj/project.pbxproj
🛑 Comments failed to post (1)
Sources/ContentView.swift (1)

13304-13306: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

SwiftLint warns that @State properties should be private.

Three @State properties were changed from private to package-internal:

  • workspaceFinderDirectoryOpenRequest
  • metadataRowsExpanded
  • metadataBlocksExpanded

If these properties need broader access for testing or initialization, this is acceptable. Otherwise, restore private access to follow SwiftUI conventions.

🧰 Tools
🪛 SwiftLint (0.63.3)

[Warning] 13304-13304: SwiftUI state properties should be private

(private_swiftui_state)


[Warning] 13305-13305: SwiftUI state properties should be private

(private_swiftui_state)


[Warning] 13306-13306: SwiftUI state properties should be private

(private_swiftui_state)

🤖 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/ContentView.swift` around lines 13304 - 13306, Add the `private`
access modifier to the three `@State` properties
workspaceFinderDirectoryOpenRequest, metadataRowsExpanded, and
metadataBlocksExpanded in ContentView.swift to follow SwiftUI conventions and
resolve the SwiftLint warning. If these properties require access from external
code for testing or initialization purposes, you may keep them as
package-internal; otherwise, restore the private access modifier to each
declaration.

Source: Linters/SAST tools

@mrueg

mrueg commented Jun 18, 2026

Copy link
Copy Markdown

There's also #1523 and #1712 mentioning it for reference

@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

♻️ Duplicate comments (1)
CLI/cmux.swift (1)

7551-7560: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stop echoing raw user input in new CLI error messages.

Several new error paths include unredacted user-provided values (unknown args and KEY=VALUE entries). That can leak secrets into shell history/logs.

As per coding guidelines, user-facing errors must not expose credentials/tokens or unredacted payload-like values.

Suggested minimal hardening
-throw CLIError(message: String(
-    format: String(
-        localized: "cli.workspace.create.error.unknownFlag",
-        defaultValue: "%@: unknown flag '%@'. Known flags: ..."
-    ),
-    locale: .current,
-    commandName,
-    unknown
-))
+throw CLIError(message: String(
+    format: String(
+        localized: "cli.workspace.create.error.unknownFlag",
+        defaultValue: "%@: unknown flag. Known flags: ..."
+    ),
+    locale: .current,
+    commandName
+))

-throw CLIError(message: String(
-    format: String(
-        localized: "cli.workspace.env.error.invalidAssignment",
-        defaultValue: "%@: %@ entry '%@' must be in KEY=VALUE form"
-    ),
-    locale: .current,
-    commandName,
-    source,
-    raw
-))
+throw CLIError(message: String(
+    format: String(
+        localized: "cli.workspace.env.error.invalidAssignment",
+        defaultValue: "%@: %@ entry must be in KEY=VALUE form"
+    ),
+    locale: .current,
+    commandName,
+    source
+))

-throw CLIError(message: "ssh-tmux: unexpected extra argument '\(arg)'")
+throw CLIError(message: "ssh-tmux: unexpected extra argument")

Also applies to: 7698-7721, 7764-7772, 8837-8841

🤖 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 `@CLI/cmux.swift` around lines 7551 - 7560, The error message in the CLIError
being thrown is echoing back the unknown flag provided by the user, which can
leak sensitive information into shell history. Remove the reference to the
`unknown` variable from the error message and replace it with a generic
indicator (such as "unknown flag provided") that does not expose the actual user
input. Apply this same redaction approach to all other error paths mentioned in
the comment (7698-7721, 7764-7772, 8837-8841) where user-provided values like
unknown arguments or KEY=VALUE entries are being directly included in error
messages.

Source: Coding guidelines

🤖 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 `@CLI/cmux.swift`:
- Around line 7774-7781: The code currently extracts only the first positional
argument using first(where:) on rem1 while silently ignoring any additional
positional arguments that don't start with "--". This can lead to unexpected
behavior where users provide multiple positional arguments but only the first is
used. After extracting the positional argument from rem1, validate that there
are no additional positional arguments by checking if there are other elements
in rem1 that don't start with "--", and if extra positional arguments are found,
return an error rejecting them rather than silently ignoring them.

---

Duplicate comments:
In `@CLI/cmux.swift`:
- Around line 7551-7560: The error message in the CLIError being thrown is
echoing back the unknown flag provided by the user, which can leak sensitive
information into shell history. Remove the reference to the `unknown` variable
from the error message and replace it with a generic indicator (such as "unknown
flag provided") that does not expose the actual user input. Apply this same
redaction approach to all other error paths mentioned in the comment (7698-7721,
7764-7772, 8837-8841) where user-provided values like unknown arguments or
KEY=VALUE entries are being directly included in error messages.
🪄 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: 78667f2f-3927-49e8-8ff9-f8a003dd1243

📥 Commits

Reviewing files that changed from the base of the PR and between 9c48ac0 and 9ac9c55.

⛔ Files ignored due to path filters (1)
  • .github/swift-file-length-budget.tsv is excluded by !**/*.tsv
📒 Files selected for processing (2)
  • CHANGELOG.md
  • CLI/cmux.swift

@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

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

♻️ Duplicate comments (1)
CLI/cmux.swift (1)

7551-7560: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Stop echoing raw user input in new CLI error messages.

Several new error paths include unredacted user-provided values (unknown args and KEY=VALUE entries). That can leak secrets into shell history/logs.

As per coding guidelines, user-facing errors must not expose credentials/tokens or unredacted payload-like values.

Suggested minimal hardening
-throw CLIError(message: String(
-    format: String(
-        localized: "cli.workspace.create.error.unknownFlag",
-        defaultValue: "%@: unknown flag '%@'. Known flags: ..."
-    ),
-    locale: .current,
-    commandName,
-    unknown
-))
+throw CLIError(message: String(
+    format: String(
+        localized: "cli.workspace.create.error.unknownFlag",
+        defaultValue: "%@: unknown flag. Known flags: ..."
+    ),
+    locale: .current,
+    commandName
+))

-throw CLIError(message: String(
-    format: String(
-        localized: "cli.workspace.env.error.invalidAssignment",
-        defaultValue: "%@: %@ entry '%@' must be in KEY=VALUE form"
-    ),
-    locale: .current,
-    commandName,
-    source,
-    raw
-))
+throw CLIError(message: String(
+    format: String(
+        localized: "cli.workspace.env.error.invalidAssignment",
+        defaultValue: "%@: %@ entry must be in KEY=VALUE form"
+    ),
+    locale: .current,
+    commandName,
+    source
+))

-throw CLIError(message: "ssh-tmux: unexpected extra argument '\(arg)'")
+throw CLIError(message: "ssh-tmux: unexpected extra argument")

Also applies to: 7698-7721, 7764-7772, 8837-8841

🤖 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 `@CLI/cmux.swift` around lines 7551 - 7560, The error message in the CLIError
being thrown is echoing back the unknown flag provided by the user, which can
leak sensitive information into shell history. Remove the reference to the
`unknown` variable from the error message and replace it with a generic
indicator (such as "unknown flag provided") that does not expose the actual user
input. Apply this same redaction approach to all other error paths mentioned in
the comment (7698-7721, 7764-7772, 8837-8841) where user-provided values like
unknown arguments or KEY=VALUE entries are being directly included in error
messages.

Source: Coding guidelines

🤖 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 `@CLI/cmux.swift`:
- Around line 7774-7781: The code currently extracts only the first positional
argument using first(where:) on rem1 while silently ignoring any additional
positional arguments that don't start with "--". This can lead to unexpected
behavior where users provide multiple positional arguments but only the first is
used. After extracting the positional argument from rem1, validate that there
are no additional positional arguments by checking if there are other elements
in rem1 that don't start with "--", and if extra positional arguments are found,
return an error rejecting them rather than silently ignoring them.

---

Duplicate comments:
In `@CLI/cmux.swift`:
- Around line 7551-7560: The error message in the CLIError being thrown is
echoing back the unknown flag provided by the user, which can leak sensitive
information into shell history. Remove the reference to the `unknown` variable
from the error message and replace it with a generic indicator (such as "unknown
flag provided") that does not expose the actual user input. Apply this same
redaction approach to all other error paths mentioned in the comment (7698-7721,
7764-7772, 8837-8841) where user-provided values like unknown arguments or
KEY=VALUE entries are being directly included in error messages.
🪄 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: 78667f2f-3927-49e8-8ff9-f8a003dd1243

📥 Commits

Reviewing files that changed from the base of the PR and between 9c48ac0 and 9ac9c55.

⛔ Files ignored due to path filters (1)
  • .github/swift-file-length-budget.tsv is excluded by !**/*.tsv
📒 Files selected for processing (2)
  • CHANGELOG.md
  • CLI/cmux.swift
🛑 Comments failed to post (1)
CLI/cmux.swift (1)

7774-7781: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reject extra positional arguments in workspace env.

The command currently picks the first positional handle and silently ignores additional positional args, which can target the wrong workspace unexpectedly.

Suggested fix
- let positional = rem1.first(where: { !$0.hasPrefix("--") })
+ let positionals = rem1.filter { !$0.hasPrefix("--") }
+ if positionals.count > 1 {
+     throw CLIError(message: "workspace env: unexpected extra argument")
+ }
+ let positional = positionals.first
📝 Committable suggestion

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

        let positionals = rem1.filter { !$0.hasPrefix("--") }
        if positionals.count > 1 {
            throw CLIError(message: "workspace env: unexpected extra argument")
        }
        let positional = positionals.first
        let windowRaw = windowFromArgsOrOverride(commandArgs, windowOverride: windowOverride)
        // Match reconnect/disconnect: default to the caller's workspace
        // ($CMUX_WORKSPACE_ID) before the selected one, but only when no explicit
        // --window is given (the caller's workspace may live in another window).
        let target = workspaceArg
            ?? positional
            ?? (windowRaw == nil ? ProcessInfo.processInfo.environment["CMUX_WORKSPACE_ID"] : nil)
🤖 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 `@CLI/cmux.swift` around lines 7774 - 7781, The code currently extracts only
the first positional argument using first(where:) on rem1 while silently
ignoring any additional positional arguments that don't start with "--". This
can lead to unexpected behavior where users provide multiple positional
arguments but only the first is used. After extracting the positional argument
from rem1, validate that there are no additional positional arguments by
checking if there are other elements in rem1 that don't start with "--", and if
extra positional arguments are found, return an error rejecting them rather than
silently ignoring them.

@Caligone

Caligone commented Jul 8, 2026

Copy link
Copy Markdown

Chiming in from #4828 (I left a note there about the fullscreen-overlay gap) — this PR's dedicated QuickTerminalPanel: NSPanel with .nonactivatingPanel is exactly the right architecture for that, glad to see it.

I've been dogfooding a quick terminal built on the same non-activating-panel recipe for ~3 weeks, including over third-party native-fullscreen Spaces (branch for reference: https://github.com/Caligone/cmux/tree/quick-term-on-main). A few field notes that may save a round-trip, since I hit all of these empirically:

  1. visibleFrame.maxY anchoring leaves a menu-bar-height gap when overlaying a fullscreen Space. NSScreen.visibleFrame keeps reporting the desktop Space's menu-bar inset — it never updates for a third-party fullscreen Space — so a top-anchored panel floats ~25–37pt below the top edge there. I confirmed it by logging requested vs actual frames. What worked: anchor on frame.maxY - safeAreaInsets.top when overlaying fullscreen (the safe-area term keeps content from sliding under the notch on built-in displays), visibleFrame.maxY otherwise.

  2. Restoring previousFrontmostApp on hide can steal focus. Open the panel over Safari → click into a regular cmux window (panel still floating) → hide the panel: the stale reference reactivates Safari out from under the user. Invalidating the stored app whenever cmux becomes frontmost fixed it for me.

  3. Auto-hide vs sheets: if a confirmation sheet (close-tab / quit) can attach to the panel, presenting it resigns the panel's key status — worth guarding the windowDidResignKey auto-hide with an attachedSheet == nil check so a pending modal doesn't vanish with the panel.

Happy to share more from the branch if useful (per-display remembered height, the constrainFrameRect interaction with the #6305 sleep/wake fix). +1 to landing this — it supersedes what I tested on #4828.

@mrueg

mrueg commented Aug 3, 2026

Copy link
Copy Markdown

Is there any timeline when this would be available in cmux? This is currently the last feature keeping me from making cmux my daily driver. Thanks for your work!

@teamleaderleo

Copy link
Copy Markdown
Collaborator

cmux-reconcile: useful

Usefulness verdict: Use as the primary Quick Terminal reconciliation candidate; resolve overlap with #1996 before implementation review.

The inspected diff includes package settings/UI, shortcut/menu/CLI integration, and coverage, whereas the current inspected main CLI does not expose quick-terminal. The need in #327 remains distinct from showing a normal app window. Preserve #1996’s automation/focus behavior where missing, then validate one implementation on current main. “Primary candidate” here is a triage recommendation, not approval to merge.

Reviewed patch head: eb674c323ca815ba4b0516993dfdea1b54af5775. Source/diff triage on September 18, 2026; no new build or runtime validation. No issue state, label, or merge decision changed.

Older issue/PR tracking index — remaining scope and competing implementations are recorded there.

@lawrencecchen

Copy link
Copy Markdown
Contributor

Mac fleet instructions for head eb674c323ca815ba4b0516993dfdea1b54af5775. Planned tag: pr-4830-eb674c32; this is not yet a published build.

JOB_JSON=$(~/.local/bin/cmux-ci submit --kind cmux --command 'CMUX_FLEET_BUILD_TAG=pr-4830-eb674c32 /Users/Shared/cmux-build-fleet/recipes/cmux.sh https://github.com/manaflow-ai/cmux.git eb674c323ca815ba4b0516993dfdea1b54af5775' --artifact artifacts/cmux.app.zip --workspace https://github.com/manaflow-ai/cmux/pull/4830 --source-digest eb674c323ca815ba4b0516993dfdea1b54af5775 --cache-key cmux:pr-4830 --min-free-bytes 268435456000 --label cmux --label ram48)
JOB_ID=$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' <<<"$JOB_JSON")
~/.local/bin/cmux-ci wait "$JOB_ID" --receipt artifacts/fleet/$JOB_ID.json
~/.local/bin/cmux-ci publish-hq "$JOB_ID"

Use an existing campaign job ID if one is already posted; do not submit a duplicate. A wait timeout leaves the remote job running. Published results will include an exact-head artifact link and timing/disk receipt. This recipe validates the macOS app only, not iOS or tests. Never use maclease or put credentials in a PR comment.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Quick Terminal has continued through later main changes and this branch is superseded by the current implementation.

This branch was successfully deployed

1 active deployment
Preview – cmux — eb674c32 Deployed Jun 18, 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.

Does cmux support quick terminal?

5 participants