Skip to content

Fix Claude resume cwd - #3816

Merged
lawrencecchen merged 3 commits into
mainfrom
issue-3815-claude-resume-cwd
May 10, 2026
Merged

lawrencecchen merged 3 commits into
mainfrom
issue-3815-claude-resume-cwd

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented May 10, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

  • Make session-index resume commands change into the recorded session cwd before invoking the agent resume command.
  • Route resume and copy-resume entrypoints through the cwd-safe command.
  • Keep cwd-ignored registered agents unchanged.

Testing:

  • Reproduced on ssh cmux-macmini: the same Claude session ID was found from its original cwd and failed with "No conversation found" from a different cwd.
  • xcodebuild test -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS,arch=arm64' -derivedDataPath /tmp/cmux-3815-unit '-only-testing:cmuxTests/SocketListenerAcceptPolicyTests/testSessionEntryClaudeResumeCommandChangesToSessionCwdBeforeResume'
  • xcodebuild test -project GhosttyTabs.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS,arch=arm64' -derivedDataPath /tmp/cmux-3815-unit '-only-testing:cmuxTests/PiVaultAgentPersistenceTests/testRegisteredAgentCWDIgnoreSuppressesResumeWorkingDirectory' '-only-testing:cmuxTests/RovoDevSessionIndexTests/testRovoDevSessionIndexReadsMetadataAndResumeCommand'
  • ./scripts/reload.sh --tag 3815cwd

Closes #3815


Note

Low Risk
Low risk: small behavior change limited to how session resume commands are constructed and used; main risk is altering quoting/cd prefix semantics for some agents’ resume flows.

Overview
Fixes session-index resume failures (notably for Claude) by making SessionEntry.resumeCommand include cd <recorded cwd> && … when a resumeWorkingDirectory is available, and removing the separate resumeCommandWithCwd variant.

Routes both the UI resume action (ContentView) and “Copy Resume Command” menu item (SessionIndexView) through the updated resumeCommand, and updates/adds unit tests to validate cwd-changing behavior while keeping registered agents with cwd == .ignore unchanged.

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


Summary by cubic

Fixes resume failures for Claude when run from a different directory by cd-ing into the session’s recorded cwd before invoking the agent; both Resume and Copy Resume now use this cwd-safe command and agents marked to ignore cwd are unchanged. Fixes #3815.

  • Bug Fixes
    • SessionEntry.resumeCommand now prefixes cd <cwd> && when resumeWorkingDirectory is set; removed resumeCommandWithCwd.
    • Updated Resume and Copy Resume entrypoints to use the cwd-safe resumeCommand.
    • Tests added/updated to cover Claude cwd behavior and ensure CWD-ignored agents keep prior behavior.

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

Summary by CodeRabbit

  • Improvements
    • Session resume commands now automatically prepend working directory changes, ensuring sessions restore to the correct location. The "Copy Resume Command" feature will now copy the complete, fully-formed command including directory setup.

Review Change Stack

@vercel

vercel Bot commented May 10, 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 10, 2026 10:57pm
cmux-staging Building Building Preview, Comment May 10, 2026 10:57pm

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

@coderabbitai

coderabbitai Bot commented May 10, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

SessionEntry's resume command is refactored to unify cwd handling: resumeCommand now includes cwd-prefixing internally via a cd <path> && wrapper, replacing the prior split between resumeCommand and resumeCommandWithCwd. All callers and tests are updated to use the consolidated property.

Changes

Resume Command cwd Wrapping Refactor

Layer / File(s) Summary
SessionEntry Property Refactor
Sources/SessionIndexModels.swift
SessionEntry.resumeCommand is updated to wrap the command with cd <cwd> && when resumeWorkingDirectory is present; a new private resumeCommandWithoutWorkingDirectory helper is introduced; the prior resumeCommandWithCwd property is removed.
Resume Command Usage Updates
Sources/ContentView.swift, Sources/SessionIndexView.swift
ContentView.resumeSession now guards entry.resumeCommand instead of entry.resumeCommandWithCwd; SessionIndexView's clipboard copy uses resumeCommand.
Test Updates and Verification
cmuxTests/PiVaultAgentPersistenceTests.swift, cmuxTests/RovoDevSessionIndexTests.swift, cmuxTests/SessionPersistenceTests.swift
Test assertions updated to verify entry.resumeCommand includes cwd-prefixed form; a new test validates that resumeCommand properly wraps the session's cwd with cd, environment variables, and the resume invocation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • manaflow-ai/cmux#3530: Modifies how SessionEntry exposes resume command properties and their usage throughout the codebase.
  • manaflow-ai/cmux#3636: Touches the same session-resume code paths and resume command construction.
  • manaflow-ai/cmux#3211: Updates resume command construction and callers to use the new payload format.

Poem

🐰 A rabbit hops through sessions with glee,
Now resume commands know their working tree!
The cd wraps 'round, the path is preserved,
No matter where the shell's cwd swerved.
From ~/fun to branches deep—resumes succeed! 🌿

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix Claude resume cwd' accurately summarizes the main change: fixing Claude session resume behavior to work correctly regardless of the current working directory.
Linked Issues check ✅ Passed All code changes directly address issue #3815: the refactored resumeCommand now prefixes 'cd &&' to ensure sessions are resumed from their original cwd, satisfying both acceptance criteria.
Out of Scope Changes check ✅ Passed All modifications are directly related to fixing the resume cwd issue: session index models were refactored, UI resume entrypoints were updated, and tests were added/updated to cover the new behavior—no unrelated changes detected.
Cmux Swift Actor Isolation ✅ Passed Production changes only modify computed String? properties on the SessionEntry value struct and their usage in MainActor-bound SwiftUI views. No actor isolation violations introduced.
Cmux Swift Blocking Runtime ✅ Passed No blocking/timing primitives introduced. Changes are logical refactoring of resume command handling with string manipulation only.
Cmux No Hacky Sleeps ✅ Passed Not applicable. The runtime-no-hacky-sleeps rule covers TypeScript, JavaScript, and shell scripts only. All PR changes are in Swift files, which fall under swift-blocking-runtime.md instead.
Cmux Swift Concurrency ✅ Passed All changes are purely synchronous string manipulation in computed properties. No Dispatch, Combine, Task, or completion-handler patterns introduced.
Cmux Swift @Concurrent ✅ Passed All changes are synchronous computed properties and UI functions. No async/await, @concurrent annotations, or actor isolation issues. Complies with swift-concurrent-annotation.md.
Cmux Swift File And Package Boundaries ✅ Passed Minimal changes (~8 net lines), no new files. Pure data model refactoring. No boundary rule violations. Allowed case: focused bug fix touching existing oversized files incidentally.
Cmux Swift Logging ✅ Passed No logging violations found. Changes refactor resumeCommand property routing without adding print, NSLog, debugPrint, dump, or ad hoc logging in production code.
Cmux Swiftui State Layout ✅ Passed No SwiftUI state violations found. Changes are computed property refactoring in SessionEntry struct with property access updates in event handlers only.
Cmux Architecture Rethink ✅ Passed Single authoritative entry point for resume commands with clear invariants. Computed properties only, no timing/blocking. Unified call path, no duplicate wiring. Validated by comprehensive tests.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR does not add or materially change any standalone cmux-owned windows. Changes are confined to session resume command logic refactoring and test updates. No new window identifiers needed.
Description check ✅ Passed The pull request description comprehensively covers the changes made, testing approach, and includes references to specific test runs and issue closure.

✏️ 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-3815-claude-resume-cwd

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented May 10, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a Claude resume failure that occurred when claude --resume was invoked from a directory other than the session's recorded cwd (the "No conversation found" error). The fix folds the cd <cwd> && prefix directly into SessionEntry.resumeCommand, removing the previously separate resumeCommandWithCwd path.

  • SessionIndexModels.swift: resumeCommand now prepends cd <shellQuote(cwd)> && when resumeWorkingDirectory is set; the old logic is split into private resumeCommandWithoutWorkingDirectory. Registered agents with cwd == .ignore are unaffected because resumeWorkingDirectory returns nil for them, bypassing the prefix.
  • ContentView.swift / SessionIndexView.swift: Both resume and copy-resume callsites are updated to call entry.resumeCommand (the new cwd-safe property), removing the now-deleted resumeCommandWithCwd.
  • Tests: A new unit test asserts the Claude resume command shape with a real cwd; the Rovo Dev test and registered-agent test are updated to match the new resumeCommand semantics.

Confidence Score: 5/5

Safe to merge — a straightforward consolidation of an existing cwd-prefix path into the main resume command property, with both callsites and all affected tests updated consistently.

The logic moved is already battle-tested (it previously lived in resumeCommandWithCwd). The cwd == .ignore exclusion is preserved through the existing resumeWorkingDirectory nil guard. No new control flow is introduced and unit tests cover Claude, Rovo Dev, and registered-agent (ignore) cases explicitly.

No files require special attention.

Important Files Changed

Filename Overview
Sources/SessionIndexModels.swift Core model change: resumeCommand now includes cd <cwd> && prefix; resumeCommandWithCwd removed; logic cleanly split into private helper. Registered-agent cwd == .ignore exclusion is preserved correctly via resumeWorkingDirectory returning nil.
Sources/ContentView.swift One-line callsite update: resumeCommandWithCwd to resumeCommand. The targetCwd usage for smart tab placement and terminal workingDirectory: is unchanged and still correct.
Sources/SessionIndexView.swift One-line callsite update in the Copy Resume Command menu item: resumeCommandWithCwd to resumeCommand. Correct and consistent with the ContentView change.
cmuxTests/SessionPersistenceTests.swift New testSessionEntryClaudeResumeCommandChangesToSessionCwdBeforeResume test directly asserts the full command shape for a Claude entry with a real cwd.
cmuxTests/RovoDevSessionIndexTests.swift Test updated to verify resumeCommand returns the cwd-prefixed form. Correct update.
cmuxTests/PiVaultAgentPersistenceTests.swift Test updated to verify resumeCommand instead of the removed resumeCommandWithCwd for the cwd == .ignore registered agent; expectation correctly remains without a cd prefix.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[SessionEntry.resumeCommand] --> B{resumeCommandWithoutWorkingDirectory?}
    B -- nil --> C[return nil]
    B -- command --> D{resumeWorkingDirectory?}
    D -- nil or .ignore --> E[return command as-is]
    D -- cwd --> F["return 'cd shellQuote(cwd) && command'"]
    G[ContentView.resumeSession] --> A
    H[SessionIndexView Copy Resume] --> A
Loading

Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

@lawrencecchen
lawrencecchen merged commit 6c37266 into main May 10, 2026
24 checks passed
@lawrencecchen
lawrencecchen deleted the issue-3815-claude-resume-cwd branch May 10, 2026 23:05

This branch was successfully deployed

1 active deployment
Preview – cmux — f917cef1 Deployed May 10, 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.

claude --resume fails when cmux relaunches in a different cwd than the session's origin

1 participant