Skip to content

cmux-next: reopen closed workspace - #17794

Closed
azooz2003-bit wants to merge 2 commits into
feat-cmux-nextfrom
feat-cmux-next-reopen-workspace
Closed

azooz2003-bit wants to merge 2 commits into
feat-cmux-nextfrom
feat-cmux-next-reopen-workspace

Conversation

@azooz2003-bit

Copy link
Copy Markdown
Collaborator

Reopen Closed Workspace was registered as unavailable in cmux-next. It now reopens the newest closed workspace.

Part of the cmux-next parity work listed in #16174 (comment).

What it does

  • Reads the daemon's closed history (closed.list, resource API v2) and picks the newest item of kind workspace. Closed tabs and screens newer than it stay in the history, like the old app.
  • Calls closed.reopen with an idempotency key. If another press or client reopened that item first, it lists again and reopens the next newest, up to 3 attempts.
  • Waits up to 5 s for the new workspace to reach the app's mirror, then shows it in the active window.
  • With nothing to reopen, it refuses with "no recently closed workspace" (21 languages) and beeps like Reopen Closed Tab. Offline, it refuses up front. Keyboard, menu, palette and cmux workspace reopen-closed share this path.

What the daemon does not restore yet

The daemon's closed.reopen (on #16174's branch) recreates the name, screens and tabs. Compared with the old app it misses:

  • the split layout (a screen's tabs land in one pane)
  • the first terminal's directory (new_workspace gets no cwd)
  • group, color and custom title
  • the original window and position

Terminals start fresh shells, because a workspace close ends them. These are daemon follow-ups, listed in the plan row, not part of this app-only PR.

Why it is stacked

closed.list and closed.reopen are in the cmux-tui pinned on #16174's branch, not on feat-cmux-next's pin. So this PR targets feat-cmux-next-acpmux and stays open until #16174 merges and GitHub retargets it.

No daemon change here.

Design call for Lawrence

The daemon doesn't advertise a capability for closed history. The handler calls the operations directly, and an older daemon's error comes back to the caller. My proposal: advertise closed-history-v1 (the name the module docs already use) and gate this action with requires:. That would be a one-line daemon change, which I left out to keep this PR app-only.

reopenPreviousSession and recentlyClosed (the list submenu) stay unavailable.

Tests

  • ReopenClosedWorkspaceTests: picks the newest workspace and skips tabs, refuses when no workspace was closed, retries the next one after resource.not_found and not after other errors, waits for the mirror, gives up after the timeout.
  • ClosedHistoryTests: the request shapes (no key on the list, key and closed on the reopen), and decoding of both replies.
  • Plan: plans/cmux-next/REWRITE.md workspace row.

No screenshots: there is no visible UI beyond the existing menu item.

Inherited red checks

cmux-next swift test fails on this base for reasons outside this diff (ResourceControl.swift:21 on the base): #16174's base is behind feat-cmux-next (Bundle.module in CmuxNextActions, GhosttyKit lib prefix). The same goes for the branch-wide routing guards that fail on #16431.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Reopens newest closed workspace in cmux-next (previously registered unavailable). It reads the daemon's closed history (closed.list, closed.reopen), has the daemon recreate the workspace, and shows it in the active window.

  • Picks the newest closed workspace from closed.list; headers closed after it (tabs, screens) stay in history for their own verbs.
  • Retries up to three times with a fresh list when another press reopened the item in between, then reopens the next newest.
  • Waits up to 5 seconds for the recreated workspace to reach the app's mirror before showing it in the active window.
  • Refuses with "no recently closed workspace" (localized in all 21 languages, beeping like Reopen Closed Tab) when there's nothing to reopen; an offline daemon refuses up front.
  • reopenPreviousSession and recentlyClosed stay unavailable.
  • No daemon change. The daemon doesn't advertise a closed-history capability yet, so an older daemon's error reaches the caller; proposed follow-up is to advertise closed-history-v1 and gate the action on it.
  • Not restored yet (daemon side): split layout, first terminal's directory, group, color, title, and original window and position.
  • Stacked on feat-cmux-next-acpmux because the daemon methods are pinned on cmux-next: the Rust cmux CLI (cmux-tui) with acpmux and cmux acp; delete the Swift CLI #16174; this stays open until that merges and retargets.

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

Review in cubic

teamleaderleo and others added 2 commits October 1, 2026 11:43
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The refusal for an empty history beeps like Reopen Closed Tab, an offline
daemon refuses up front, and a press that loses its item to another press
reopens the next newest. The reveal wait uses a helper task, which the
region isolation checker accepts, and the plan lists what is not restored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: e26e31c2-273d-4ecf-9011-9f73d4d53fea

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

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.

2 participants