Skip to content

Fix Cmd-W for Task Manager and auxiliary windows - #3734

Merged
lawrencecchen merged 8 commits into
mainfrom
task-fix-task-manager-cmd-w
May 8, 2026
Merged

lawrencecchen merged 8 commits into
mainfrom
task-fix-task-manager-cmd-w

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented May 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

  • Register Task Manager and other standalone cmux windows as close-shortcut owners.
  • Add a CI lint that requires cmux window identifiers to be listed in the auxiliary close-owner set.
  • Add an identifier for the Feed Text Editor debug window so it participates in the same rule.

Testing:

  • python3 scripts/lint_auxiliary_window_close_shortcuts.py
  • ./tests/test_ci_auxiliary_window_close_shortcuts.sh
  • CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag tmcmdw

Notes:

  • User dogfooding confirmed the Task Manager Cmd+W path is fixed.
  • The first commit adds the lint guard; the second commit registers the windows so the guard passes.

Note

Low Risk
Low risk: changes are limited to window identifier registration and adds a CI lint/test guard, with minimal runtime impact outside Cmd+W behavior for auxiliary windows.

Overview
Ensures standalone auxiliary cmux windows reliably own the standard close shortcut (Cmd+W) by expanding the cmuxAuxiliaryWindowIdentifiers registry (including Task Manager and several debug/lab windows).

Adds a new Python lint (lint_auxiliary_window_close_shortcuts.py) plus CI coverage to fail PRs when a Swift window.identifier = NSUserInterfaceItemIdentifier("cmux.*") assignment isn’t registered (with an explicit ignore for cmux.bootstrap).

Assigns a concrete window.identifier to the Feed Text Editor debug window so it participates in the same shortcut-ownership rule.

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


Summary by cubic

Fixes Cmd+W for Task Manager and other standalone cmux windows by registering them as close-shortcut owners. Adds a CI lint that enforces this rule, handles comments and multiline assignments, reports file:line, and ignores cmux.bootstrap.

  • Bug Fixes

    • Registered Task Manager and other auxiliary windows in cmuxAuxiliaryWindowIdentifiers so Cmd+W closes them; set cmux.feedTextEditorDebug on the Feed Text Editor debug window.
  • New Features

    • Added scripts/lint_auxiliary_window_close_shortcuts.py with file:line reporting; wired into CI via tests/test_ci_auxiliary_window_close_shortcuts.sh. Lint strips line and block comments, ignores commented-out owners, handles multiline window.identifier, and allows an explicit ignore for cmux.bootstrap.

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

Summary by CodeRabbit

  • Tests

    • Added a CI test that validates auxiliary window close-shortcut handling.
  • Chores

    • Added a linter to enforce which auxiliary windows may claim the standard close shortcut.
    • Added a CI validation step to run the new linter.
  • Bug Fixes

    • Improved auxiliary/debug window identification and initialization so close-key behavior (Cmd+W) is handled more consistently.

@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 8, 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 8, 2026 7:31pm
cmux-staging Building Building Preview, Comment May 8, 2026 7:31pm

@coderabbitai

coderabbitai Bot commented May 8, 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 Python CLI linter and Bash CI test that verify all Swift NSUserInterfaceItemIdentifier("cmux.*") assignments appear in cmuxAuxiliaryWindowIdentifiers; assigns a debug window identifier and runs the test in CI.

Changes

Window Identifier Linting System

Layer / File(s) Summary
Identifier Registry
Sources/cmuxApp.swift
cmuxAuxiliaryWindowIdentifiers expanded with additional auxiliary/debug/config window identifiers.
Window Identifier Assignment
Sources/Feed/FeedTextEditorDebugWindowController.swift
Debug window is assigned NSUserInterfaceItemIdentifier("cmux.feedTextEditorDebug") during initialization.
Linter Setup & Helpers
scripts/lint_auxiliary_window_close_shortcuts.py
Adds CLI script configuration, comment-stripping helpers, regexes, defaults, and ignore allowlist.
Linter Owner Identifier Loading
scripts/lint_auxiliary_window_close_shortcuts.py
Implements load_close_owner_identifiers() to parse Sources/cmuxApp.swift and extract the allowed identifier set.
Linter Identifier Collection
scripts/lint_auxiliary_window_close_shortcuts.py
Implements collect_window_identifier_assignments() to recursively scan Swift files and map identifiers to file:line locations.
Linter CLI Logic
scripts/lint_auxiliary_window_close_shortcuts.py
Implements main(argv) to orchestrate argument parsing, loading, collection, validation, and return appropriate exit codes (0/1/2).
Linter Module Entrypoint
scripts/lint_auxiliary_window_close_shortcuts.py
Adds the module execution entrypoint that invokes main(sys.argv[1:]) under SystemExit.
CI Validation Step
.github/workflows/ci.yml
Adds a workflow-guard-tests step to run ./tests/test_ci_auxiliary_window_close_shortcuts.sh.
Test Script Initialization
tests/test_ci_auxiliary_window_close_shortcuts.sh
Bash test enables strict mode, computes repo root, and runs the linter against the real repo as a baseline.
Test Temp Repo Setup
tests/test_ci_auxiliary_window_close_shortcuts.sh
Creates a temporary directory as isolated repo root and prepares Sources/ for fixtures.
Test Fixture: cmuxApp.swift
tests/test_ci_auxiliary_window_close_shortcuts.sh
Writes fixture Sources/cmuxApp.swift with cmuxAuxiliaryWindowIdentifiers initially containing only cmux.settings.
Test Fixture: NewWindow.swift
tests/test_ci_auxiliary_window_close_shortcuts.sh
Writes fixture Sources/NewWindow.swift assigning NSUserInterfaceItemIdentifier("cmux.newWindow").
Test Failure Case
tests/test_ci_auxiliary_window_close_shortcuts.sh
Runs the linter against the temp repo expecting failure and asserts output mentions cmux.newWindow.
Test Fixture: cmuxApp.swift (commented entry)
tests/test_ci_auxiliary_window_close_shortcuts.sh
Rewrites fixture so cmux.newWindow appears only commented out; reruns linter expecting failure.
Test Fixture: cmuxApp.swift (include newWindow)
tests/test_ci_auxiliary_window_close_shortcuts.sh
Rewrites fixture to include cmux.newWindow; reruns linter expecting success.
Test Fixture: NewWindow.swift (identifier commented)
tests/test_ci_auxiliary_window_close_shortcuts.sh
Rewrites NewWindow.swift with the identifier assignment commented out; reruns linter expecting success.
Test Fixture: NewWindow.swift (bootstrap)
tests/test_ci_auxiliary_window_close_shortcuts.sh
Rewrites NewWindow.swift to set the identifier to cmux.bootstrap (ignored); reruns linter expecting success.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

aardvark, codex

Poem

🐰 I hop through code with careful paws,
I check each window's tiny clause,
Registry neat, identifiers true,
Tests and CI nod — all checked through,
A joyful lint and one small applause.


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 Swift Concurrency ❌ Error Introduces DispatchQueue.global for ordinary async work and new @Published/@observableobject without using modern Observation pattern. Replace DispatchQueue.global with async throws. Replace @Published/@observableobject with @Observable for modern Swift concurrency.
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 (12 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main objective: fixing Cmd+W behavior for Task Manager and auxiliary windows, which aligns with the primary changes in the changeset.
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 Changes introduce only immutable data (Set identifiers) and DEBUG-only identifier assignment. No implicit MainActor values, Sendable violations, or mutable shared state.
Cmux Swift Blocking Runtime ✅ Passed PR introduces only declarative Swift changes: identifier assignment and string additions to a set. No blocking/timing synchronization primitives introduced in production Swift code.
Cmux No Hacky Sleeps ✅ Passed PR contains no hacky sleeps, delays, or timing workarounds. Adds deterministic linter, test scaffolding, window identifiers, and CI integration—all without timing code.
Cmux Swift @Concurrent ✅ Passed Swift changes introduce no async functions, @concurrent annotations, or concurrency-related code. Changes are synchronous: property assignment and set array extensions for window identifiers only.
Cmux Swift File And Package Boundaries ✅ Passed Small focused changes: +1 line FeedTextEditorDebugWindow, +10 cmuxApp window identifiers. Both within limits, no mixed responsibilities.
Cmux Swift Logging ✅ Passed No logging violations in Swift changes. FeedTextEditorDebugWindowController (#if DEBUG only) and cmuxApp.swift (configuration only) contain no print/debugPrint/dump/NSLog or sensitive data.
Cmux Swiftui State Layout ✅ Passed PR introduces no new SwiftUI state antipatterns. Changes are window identifier assignments and CI linting infrastructure. Existing debug-only @State usage is properly scoped in AppKit bridge views.
Cmux Architecture Rethink ✅ Passed Clean architectural fix with clear ownership of window close behavior. Standard AppKit patterns, single source of truth enforced via linter. No timing/lifecycle issues or bad state introduced.
Description check ✅ Passed The PR description covers the key sections (summary, testing, notes) and explains the changes comprehensively, though the template's optional Demo Video and Checklist items are not included.
✨ 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-task-manager-cmd-w

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.

coderabbitai[bot]
coderabbitai Bot previously requested changes May 8, 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 `@scripts/lint_auxiliary_window_close_shortcuts.py`:
- Around line 41-47: The current use of text.find("]", list_start) can stop at
the first ']' (e.g., inside comments), so replace that lookup with a
bracket-counting loop: start from list_start, iterate characters, increment a
counter on '[' and decrement on ']', and when the counter returns to zero record
that index as list_end; keep the same error behavior (raise ValueError
referencing OWNER_LIST_NAME and OWNER_LIST_PATH if no match found) and keep the
downstream logic that builds list_body and uses STRING_LITERAL_RE unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ea7ad054-a496-4fde-9094-c08d6c38f9f4

📥 Commits

Reviewing files that changed from the base of the PR and between 00dd7c3 and 066f398.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • Sources/Feed/FeedTextEditorDebugWindowController.swift
  • Sources/cmuxApp.swift
  • scripts/lint_auxiliary_window_close_shortcuts.py
  • tests/test_ci_auxiliary_window_close_shortcuts.sh

Comment thread scripts/lint_auxiliary_window_close_shortcuts.py Outdated
@greptile-apps

greptile-apps Bot commented May 8, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Registers Task Manager and other auxiliary cmux windows as close-shortcut owners so Cmd+W routes through window.performClose(nil) instead of the workspace panel-close path, and assigns an explicit identifier to the Feed Text Editor debug window.

  • cmuxAuxiliaryWindowIdentifiers expansion: Ten new identifiers added (including cmux.taskManager and cmux.feedTextEditorDebug), completing the registration of all user-visible standalone windows.
  • cmux.feedTextEditorDebug identifier: Assigned in FeedTextEditorDebugWindowController.init so the lint and runtime routing both recognize the window; the existing windowShouldClose delegate correctly hides the singleton instead of closing it.
  • Lint + CI guard: lint_auxiliary_window_close_shortcuts.py scans Swift sources for window.identifier assignments, strips line and block comments before matching, and fails CI if any cmux.* identifier is missing from the owner set.

Confidence Score: 5/5

Safe to merge — the change is limited to registering window identifiers and adding a CI guard; no production control flow is altered beyond Cmd+W routing for the listed windows.

All affected paths are additive: identifiers are appended to an existing set, and cmuxWindowShouldOwnCloseShortcut already handles the routing correctly once an identifier is registered. The lint script correctly strips both line and block comments before scanning, addressing the comment-handling concerns raised in prior review threads.

No files require special attention.

Important Files Changed

Filename Overview
scripts/lint_auxiliary_window_close_shortcuts.py New lint script that finds window.identifier assignments and fails if the identifier is absent from the owner set; correctly strips line and block comments before both the assignment scan and owner-set extraction.
tests/test_ci_auxiliary_window_close_shortcuts.sh Shell integration test covering block-comment stripping, line-comment stripping, multiline assignments, commented-out owner entries, and the cmux.bootstrap explicit ignore path.
Sources/cmuxApp.swift Adds ten identifiers to cmuxAuxiliaryWindowIdentifiers; cmuxWindowShouldOwnCloseShortcut then returns true for these windows, routing Cmd+W to performClose rather than workspace panel-close logic.
Sources/Feed/FeedTextEditorDebugWindowController.swift One-line addition of window.identifier so the debug window participates in close-shortcut routing; the existing windowShouldClose delegate (hides-not-closes) remains correct for the singleton lifecycle.
.github/workflows/ci.yml Wires the new shell test into the CI lint job; no changes to existing steps.

Reviews (5): Last reviewed commit: "Preserve window lint line numbers" | Re-trigger Greptile

Comment thread scripts/lint_auxiliary_window_close_shortcuts.py
Comment thread scripts/lint_auxiliary_window_close_shortcuts.py
coderabbitai[bot]
coderabbitai Bot previously requested changes May 8, 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 `@scripts/lint_auxiliary_window_close_shortcuts.py`:
- Around line 73-76: The current per-line loop using path.open(...) and
IDENTIFIER_ASSIGNMENT_RE.finditer(line) misses assignments split across lines;
instead read the entire file into a single string and run
IDENTIFIER_ASSIGNMENT_RE.finditer(content) so multi-line matches are found
(ensure the regex uses re.MULTILINE/ re.DOTALL as needed), and compute the
match's line number with content.count("\n", 0, match.start()) + 1; replace the
per-line enumerate/for loop that referenced handle, line_number and line with
this single-content approach using IDENTIFIER_ASSIGNMENT_RE.finditer(content).
🪄 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: b83fc5c4-b35f-4f64-82cc-d00bececb21a

📥 Commits

Reviewing files that changed from the base of the PR and between 066f398 and bd617d8.

📒 Files selected for processing (2)
  • scripts/lint_auxiliary_window_close_shortcuts.py
  • tests/test_ci_auxiliary_window_close_shortcuts.sh

Comment thread scripts/lint_auxiliary_window_close_shortcuts.py 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 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 0594219. Configure here.

Comment thread scripts/lint_auxiliary_window_close_shortcuts.py
coderabbitai[bot]
coderabbitai Bot previously requested changes May 8, 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

🤖 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 `@scripts/lint_auxiliary_window_close_shortcuts.py`:
- Around line 27-31: strip_line_comments currently only removes line comments
(LINE_COMMENT_RE) and ignores Swift block comments, causing false positives in
collect_window_identifier_assignments and STRING_LITERAL_RE matches; update
strip_line_comments to first remove block comments (e.g., a non-greedy regex for
/\*.*?\*/ applied before LINE_COMMENT_RE) so block-commented code is stripped
prior to line-comment stripping, leaving load_close_owner_identifiers' bracket
logic unchanged; use the existing LINE_COMMENT_RE and STRING_LITERAL_RE symbols
and ensure the block-comment removal runs at the start of strip_line_comments to
avoid leaving quoted literals inside block comments.

In `@tests/test_ci_auxiliary_window_close_shortcuts.sh`:
- Around line 59-86: Add a new fixture in the test script to ensure
block-commented assignments are ignored: modify one of the NewWindow.swift
snippets (the ones containing func makeWindow() and window.identifier) to
include a block comment that contains a forbidden assignment like /*
window.identifier = NSUserInterfaceItemIdentifier("cmux.oldWindow") */ and then
run python3 scripts/lint_auxiliary_window_close_shortcuts.py --repo-root
"$TMP_DIR" as the test already does; this verifies the linter
(strip_line_comments fix) does not surface assignments inside /* ... */ comments
while keeping the existing //-comment and cmuxAuxiliaryWindowIdentifiers cases
intact.
🪄 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: 0119dccb-7437-4504-92ab-7af816c489b3

📥 Commits

Reviewing files that changed from the base of the PR and between bd617d8 and 0594219.

📒 Files selected for processing (2)
  • scripts/lint_auxiliary_window_close_shortcuts.py
  • tests/test_ci_auxiliary_window_close_shortcuts.sh

Comment thread scripts/lint_auxiliary_window_close_shortcuts.py
Comment thread tests/test_ci_auxiliary_window_close_shortcuts.sh
coderabbitai[bot]
coderabbitai Bot previously requested changes May 8, 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 `@scripts/lint_auxiliary_window_close_shortcuts.py`:
- Around line 81-85: The reported line numbers are computed from the stripped
text (used by IDENTIFIER_ASSIGNMENT_RE and the line_number = text.count("\n", 0,
match.start()) + 1 calculation) but strip_line_comments currently removes block
comments and their newlines; update strip_line_comments so that when it removes
/* ... */ it replaces the entire block comment with the same number of '\n'
characters (preserving original line breaks) so subsequent line counting remains
accurate; ensure this change still removes comment content (so
load_close_owner_identifiers / IDENTIFIER_ASSIGNMENT_RE behavior is unchanged)
and keep LINE_COMMENT_RE handling as-is.
🪄 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: 4894c364-81d3-4117-a09e-13f975891248

📥 Commits

Reviewing files that changed from the base of the PR and between 0594219 and c150a48.

📒 Files selected for processing (2)
  • scripts/lint_auxiliary_window_close_shortcuts.py
  • tests/test_ci_auxiliary_window_close_shortcuts.sh

Comment thread scripts/lint_auxiliary_window_close_shortcuts.py
@lawrencecchen
lawrencecchen dismissed stale reviews from coderabbitai[bot], coderabbitai[bot], coderabbitai[bot], and coderabbitai[bot] May 8, 2026 19:40

Resolved by follow-up commits through d844e04; all CodeRabbit threads are resolved and the latest CodeRabbit review on the current head is non-blocking.

@lawrencecchen
lawrencecchen merged commit fbbd75e into main May 8, 2026
27 of 28 checks passed
@lawrencecchen
lawrencecchen deleted the task-fix-task-manager-cmd-w branch May 8, 2026 19:42
@coderabbitai coderabbitai Bot mentioned this pull request May 9, 2026
3 of 6 tasks

This branch was successfully deployed

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