Skip to content

Fix Cmd+T opening in home after agent-resume session restore (#6617) - #6621

Merged
austinywang merged 2 commits into
mainfrom
issue-6617-cmdt-cwd-after-restore
Jun 23, 2026
Merged

austinywang merged 2 commits into
mainfrom
issue-6617-cmdt-cwd-after-restore

Conversation

@austinywang

@austinywang austinywang commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #6617 — after Cmd+Q and session restore, Cmd+T opened the new tab in home (~) instead of the directory the resumed terminal/agent is in. This regressed the #6047 fix (whose Cmd+T workspace-cwd fallback is correct, but was being fed a clobbered value).

Root cause

The snapshot does persist the workspace cwd, and restore does replay it onto currentDirectory / panelDirectories. The directory was being lost after restore:

  • A terminal whose startup command cds itself — agent resume, tmux attach, agent-hook — is intentionally spawned with no working directory so it tolerates a since-deleted saved directory (see the localWorkingDirectory == nil branch).
  • Its shell therefore starts in the default directory and shell integration emits a report_pwd (OSC-7) for that directory — typically home — before the resume command cds into the saved one.
  • That spurious live report flows report_pwd → updateSurfaceDirectory → Workspace.updatePanelDirectory(.liveReport) and overwrote the restored panelDirectories[focused] and the focused workspace currentDirectory.
  • Cmd+T's cwd-inheritance fallback (panelDirectories[source] → … → currentDirectory) then resolved to home.

A fresh (non-restored) terminal doesn't hit this: it's spawned in the project directory, so its first report already is the project directory.

The restore path already had a guard (restoredGuardedWorkingDirectoriesByPanelId) meant to ignore exactly these spurious post-resume reports — but it only armed when the saved directory was on an unmounted volume, so a normal (existing) project directory was left unprotected.

Fix

  • Arm the guard for every startup-handles-cwd restore with a non-empty saved directory (not just unmounted volumes).
  • shouldIgnoreRestoredGuardedDirectoryReport now:
    • clears + allows when the report matches the restored directory (shell confirmed it);
    • for an accessible directory, ignores the first mismatched report once and then stops guarding (so the spurious home report is dropped while the user's own later navigation is honored);
    • keeps the existing persistent ignore for unmounted volumes.

This is surgical: only a report that differs from the restored directory is suppressed, and only the first one for accessible directories. savedWorkingDirectory is the panel's last-known directory, so legitimate same-directory reports (e.g. tmux panes) match and clear the guard immediately.

Tests

Two-commit structure (red → green):

  1. test: adds cmdTAfterAgentResumeRestoreKeepsProjectCwdDespiteSpuriousHomePwdReport in AgentSessionAutoResumeSwiftTests (a .serialized session-restore suite). It saves a workspace whose focused terminal runs an auto-resumed Claude agent in a project dir, restores it, simulates the resumed shell's spurious home report_pwd, and asserts currentDirectory survives and a new Cmd+T surface inherits the project directory. Fails without the fix (home clobbers the cwd).
  2. fix: the guard change above.

Localization

No user-facing strings changed (guard logic + a #if DEBUG diagnostic only); no Localizable.xcstrings updates required.


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


Summary by cubic

Fixes #6617: after Cmd+Q and session restore, Cmd+T now opens in the project directory instead of home when resuming terminals whose startup command cds itself (agent resume, tmux attach, agent-hook). The restore path now guards the restored cwd for local terminals, ignoring the first spurious home PWD report and accepting it if the saved directory was deleted.

  • Bug Fixes
    • Arm cwd guard for all startup-handles-cwd restores on local terminals; ignore the first mismatched report once when the saved dir still exists, persist ignore for unmounted volumes, accept the report if the saved dir was deleted; remote terminals keep prior behavior.
    • Added regression tests for both cases; updated .github/swift-file-length-budget.tsv.

Written for commit 2084b4f. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Release Notes

  • Tests

    • Added regression coverage for auto-resumed agent session restore, verifying the restored working directory stays correct for project vs. home directory cases, including when a saved directory was deleted.
  • Bug Fixes

    • Improved terminal session restore to better preserve the intended working directory. When startup commands can change cwd, the restore now guards against spurious shell-reported directory updates and correctly falls back if the saved directory is no longer available.

@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0c449988-13fa-4f10-81d7-16d7f11512d7

📥 Commits

Reviewing files that changed from the base of the PR and between fa6727c and 2084b4f.

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

📝 Walkthrough

Walkthrough

Adds guarded working directory logic to session restore and two regression tests. Workspace.swift now registers guarded directories more broadly during terminal restore (whenever the startup command handles cd with no explicit cwd), and refines the acceptance logic from unmounted-volume-only guarding to a three-stage policy: accept when the report matches the restored directory, ignore indefinitely on unmounted volumes, or one-shot guard on mounted volumes. Regression tests validate that spurious post-restore home-directory reports are ignored (so Cmd+T uses the project directory) and that deleted-directory scenarios correctly fall back to home-directory acceptance.

Changes

Session Restore Guarded Directory and Regression Tests

Layer / File(s) Summary
Guarded working directory registration and acceptance logic
Sources/Workspace.swift
Broadened terminal restore guarded-directory registration to cover any startup command expected to cd itself when no explicit local cwd is provided. Refactored shouldIgnoreRestoredGuardedDirectoryReport from unmounted-volume-only guarding to a three-stage policy: stop guarding when the report matches the restored directory, keep guarding indefinitely if on an unmounted volume, or perform one-shot guarding (ignore only while the mounted directory exists).
Regression tests and helper for guarded restore scenarios
cmuxTests/AgentSessionAutoResumeSwiftTests.swift
Added two @MainActor regression tests with a shared helper: cmdTAfterAgentResumeRestoreKeepsProjectCwdDespiteSpuriousHomePwdReport asserts that spurious post-restore home-directory reports are ignored and Cmd+T uses the persisted project directory; agentResumeRestoreAcceptsHomePwdReportWhenSavedDirectoryWasDeleted asserts that home-directory reports are accepted when the saved directory does not exist; restoreWorkspaceWithAutoResumedClaudeAgent(savedDirectory:) helper constructs and restores an auto-resumable Claude agent workspace rooted at a saved directory and asserts cwd preservation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • manaflow-ai/cmux#4859: Both PRs modify session/terminal restore handling of the working directory in Sources/Workspace.swift around recovering from deleted or mismatched cwd/pwd by guarding or ignoring subsequent directory reports.
  • manaflow-ai/cmux#5300: Both PRs address drifted or restored agent working-directory selection—this PR adds regression coverage for Claude auto-resume workspace cwd/panel directory correctness while the related PR changes the actual resume/binding working-directory logic.
  • manaflow-ai/cmux#5307: Both PRs modify the same Sources/Workspace.swift guarded-cwd restore logic, adjusting conditions for when to ignore shell-reported cwd changes and when to clear guarding during terminal restore.

Poem

🐇 Hop through the restore with guard in place,
Keep the project dir, not home's embrace!
Three stages guard the spurious "pwd" away,
So Cmd+T finds the right cwd to stay.
The snapshot holds the path so true,
Regression tests hop through and through! 🌿


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Expensive Synchronous Load ❌ Error PR adds FileManager.fileExists() sync call on MainActor in shouldIgnoreRestoredGuardedDirectoryReport, invoked from shell integration report_pwd handlers. While the code comment acknowledges "guard... Move FileManager.fileExists() to a background Task.detached for determining directory existence; return immediately on @MainActor with a conservatively safe default while the check completes asynchronously, or use a cached result from an...
Docstring Coverage ⚠️ Warning Docstring coverage is 37.50% 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 directly and clearly describes the main fix: preventing Cmd+T from opening in home after agent-resume session restore, matching the primary bug being addressed.
Description check ✅ Passed The description comprehensively covers the Summary (what and why), includes detailed testing methodology with regression test information, and addresses the checklist items (tests added, no localization changes needed).
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 Production changes in Workspace.swift introduce no actor isolation mistakes. Private dictionary property stored within @MainActor class, accessed only from main-actor-isolated methods; uses value t...
Cmux Swift Blocking Runtime ✅ Passed PR introduces only test code and guard logic using dictionaries and directory existence checks; no blocking primitives (semaphores, sleeps, waits, locks, delayed dispatch, polling, main-queue sync)...
Cmux Cache Substitution Correctness ✅ Passed Guard is armed with fresh snapshot data and makes decisions using fresh FileManager.fileExists() checks; no stale cache substitution occurs.
Cmux No Hacky Sleeps ✅ Passed All modified files are Swift (.swift extension); check scope excludes Swift code, which is covered by "cmux Swift blocking runtime" check instead.
Cmux Algorithmic Complexity ✅ Passed PR adds directory-guard logic with O(1) dictionary/Set operations, one-shot FileManager call, and bounded collections (~10-50 panels max). No nested scans, per-target rescans, or hot-path filtering...
Cmux Swift Concurrency ✅ Passed No legacy async patterns introduced. PR adds synchronous guard logic with FileManager.fileExists checks and @if DEBUG logging—all appropriate for @MainActor Workspace restore state management.
Cmux Swift @Concurrent ✅ Passed No concurrent annotation violations detected. PR adds only synchronous code to @MainActor class with no async functions, @concurrent annotations, or nonisolated async declarations.
Cmux Swift File And Package Boundaries ✅ Passed Workspace.swift adds only 45 lines net to an existing 12,828-line file (well below 250-line threshold for oversized files), contains no mixed responsibilities, and qualifies as a focused bug fix wi...
Cmux Swiftpm Lockfiles ✅ Passed PR includes all required Package.resolved lockfiles for 10 external-dependency cmux packages and root Xcode project, no cmux-owned .gitignore ignores Package.resolved, and vendored third-party pres...
Cmux Swift Logging ✅ Passed Two new cmuxDebugLog calls added in Workspace.swift are both properly guarded with #if DEBUG, following the codebase pattern for debug-only diagnostics. No unguarded logging violations found in pro...
Cmux User-Facing Error Privacy ✅ Passed All diagnostic logging is properly wrapped in #if DEBUG. No user-facing error messages, alerts, or localized strings were added outside of DEBUG blocks. Test additions use only internal test helper...
Cmux Full Internationalization ✅ Passed PR adds no user-facing strings. All changes are test additions and guard logic with debug-only diagnostics wrapped in #if DEBUG. No localization catalog updates needed.
Cmux Swiftui State Layout ✅ Passed The PR modifies Workspace (an ObservableObject model class) to improve guard logic for cwd restoration. No new @Published, @Observable, @State, or @StateObject properties were introduced. State mut...
Cmux Architecture Rethink ✅ Passed The PR fixes a correctness issue in session restore where Cmd+T opened in home instead of the project directory. The fix refines the existing guard mechanism (from #6205) to protect restored direct...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds regression tests and modifies working directory guarding logic in Workspace.swift. No new NSWindow, NSPanel, NSWindowController, or SwiftUI Window/WindowGroup creation detected. Window refe...
Cmux Source Artifacts ✅ Passed All changed files in the PR (test file, source code, config file) are intentional source artifacts per rules; no local tool output, generated logs, build artifacts, or scratch directories were added.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The two #if DEBUG blocks added only contain diagnostic logging (cmuxDebugLog) calls that gate real product behavior, not test-observability seams. No new test-only members with ForTesting/TestHook/...
✨ 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-6617-cmdt-cwd-after-restore

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.

@greptile-apps

greptile-apps Bot commented Jun 22, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a regression in Cmd+T cwd-inheritance after agent-resume session restore (#6617). When a terminal whose startup command cds itself (agent resume, tmux attach) was restored, its shell reported home via OSC-7 before the cd ran, clobbering panelDirectories and currentDirectory. The pre-existing restoredGuardedWorkingDirectoriesByPanelId guard was only armed for unmounted-volume paths; this PR arms it for every local startup-handles-cwd restore with a non-empty saved directory.

  • Guard logic extended (Sources/Workspace.swift): The guard is now armed for all local terminals where startupHandlesWorkingDirectory == true and localWorkingDirectory == nil; shouldIgnoreRestoredGuardedDirectoryReport gains a third branch — when the restored directory still exists on a mounted volume, the first mismatched report (spurious home) is suppressed once; when the directory was deleted, the report is accepted so Cmd+T inherits a valid fallback directory.
  • Tests added (cmuxTests/AgentSessionAutoResumeSwiftTests.swift): Two new @Test functions cover the fixed case (project dir still exists — home suppressed) and the companion deleted-directory case (home accepted as real fallback), both using a real on-disk temp directory to exercise the FileManager.fileExists guard path.

Confidence Score: 5/5

Safe to merge — the change is a targeted extension of an existing guard mechanism with no new state representations and two test cases that directly exercise the fixed paths.

The guard arming and one-shot suppress logic are well-bounded: the guard is indexed by panel ID, cleared after first use on mounted volumes, and the FileManager.fileExists check is a single stat that fires only once per restore. The three branches (match / unmounted / mounted) cover all distinct cases, and the deleted-directory companion test confirms the important edge case. No new test/debug seams are introduced to production source, and all #if DEBUG blocks gate legitimate diagnostic logs.

No files require special attention.

Important Files Changed

Filename Overview
Sources/Workspace.swift Guard arming extended to all local startup-handles-cwd restores; shouldIgnoreRestoredGuardedDirectoryReport gains the one-shot mounted-volume branch with a FileManager.fileExists check; #if DEBUG diagnostic log entries updated — all changes are well-bounded and correct.
cmuxTests/AgentSessionAutoResumeSwiftTests.swift Adds two regression tests and a shared helper; tests correctly exercise the live production path via updatePanelDirectory(.liveReport) and assert both currentDirectory and new-tab requestedWorkingDirectory; no issues found.
.github/swift-file-length-budget.tsv Mechanical budget update reflecting Workspace.swift growth (+45 lines) and other incidental file-size adjustments; new test file entry added correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["OSC-7 liveReport received\nupdatePanelDirectory(.liveReport)"] --> B{Guard entry exists\nfor panelId?}
    B -- No --> C[Update panelDirectories\nand currentDirectory]
    B -- Yes --> D{reportedDir ==\nrestoredDir?}
    D -- Yes --> E[Clear guard\nAllow update]
    D -- No --> F{Restored dir on\nunmounted volume?}
    F -- Yes --> G[Persistent ignore\nguard stays]
    F -- No --> H[Remove guard\none-shot check]
    H --> I{FileManager.fileExists\nrestoredDir still exists?}
    I -- Yes --> J[Ignore spurious\nhome report\nproject cwd preserved]
    I -- No --> K[Accept home report\ndeleted-dir fallback honored]
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["OSC-7 liveReport received\nupdatePanelDirectory(.liveReport)"] --> B{Guard entry exists\nfor panelId?}
    B -- No --> C[Update panelDirectories\nand currentDirectory]
    B -- Yes --> D{reportedDir ==\nrestoredDir?}
    D -- Yes --> E[Clear guard\nAllow update]
    D -- No --> F{Restored dir on\nunmounted volume?}
    F -- Yes --> G[Persistent ignore\nguard stays]
    F -- No --> H[Remove guard\none-shot check]
    H --> I{FileManager.fileExists\nrestoredDir still exists?}
    I -- Yes --> J[Ignore spurious\nhome report\nproject cwd preserved]
    I -- No --> K[Accept home report\ndeleted-dir fallback honored]
Loading

Reviews (3): Last reviewed commit: "fix: keep restored workspace cwd against..." | Re-trigger Greptile

Comment on lines +112 to +181
@Test func cmdTAfterAgentResumeRestoreKeepsProjectCwdDespiteSpuriousHomePwdReport() throws {
try withRestoredDefaults(key: AgentSessionAutoResumeSettings.autoResumeAgentSessionsKey) {
UserDefaults.standard.set(true, forKey: AgentSessionAutoResumeSettings.autoResumeAgentSessionsKey)

let projectDir = "/tmp/cmux-cmdt-resume-project-\(UUID().uuidString)"
let sessionId = "claude-cmdt-resume-session"
let source = Workspace()
source.currentDirectory = projectDir
let sourcePanelId = try #require(source.focusedPanelId)

let agent = SessionRestorableAgentSnapshot(
kind: .claude,
sessionId: sessionId,
workingDirectory: projectDir,
launchCommand: AgentLaunchCommandSnapshot(
launcher: "claude",
executablePath: "/usr/local/bin/claude",
arguments: ["/usr/local/bin/claude", "--resume", sessionId],
workingDirectory: projectDir,
environment: [:],
capturedAt: 1_777_777_777,
source: "process"
)
)
source.updatePanelShellActivityState(panelId: sourcePanelId, state: .commandRunning)
source.setRestoredAgentSnapshotForTesting(agent, panelId: sourcePanelId)

let bindingIndex = SurfaceResumeBindingIndex(bindingsByPanel: [
SurfaceResumeBindingIndex.PanelKey(workspaceId: source.id, panelId: sourcePanelId): SurfaceResumeBindingSnapshot(
name: "Claude",
kind: "claude",
command: "{ cd -- '\(projectDir)' 2>/dev/null || [ ! -d '\(projectDir)' ]; } && 'claude' '--resume' '\(sessionId)'",
cwd: projectDir,
checkpointId: sessionId,
source: "agent-hook",
autoResume: true,
updatedAt: 1_777_777_777
),
])

let snapshot = source.sessionSnapshot(
includeScrollback: false,
surfaceResumeBindingIndex: bindingIndex
)
#expect(snapshot.currentDirectory == projectDir)

let restored = Workspace()
restored.restoreSessionSnapshot(snapshot)
let restoredPanelId = try #require(restored.focusedPanelId)

// Restore replays the persisted project directory onto the workspace
// and the resumed panel.
#expect(restored.currentDirectory == projectDir)
#expect(restored.panelDirectories[restoredPanelId] == projectDir)

// The resumed shell starts before its agent-resume command cds, so
// shell integration reports home first. This spurious live report must
// be ignored so the restored project cwd survives.
let spuriousHomeReport = FileManager.default.homeDirectoryForCurrentUser.path
try #require(spuriousHomeReport != projectDir)
restored.updatePanelDirectory(panelId: restoredPanelId, directory: spuriousHomeReport)

#expect(restored.currentDirectory == projectDir)
#expect(restored.panelDirectories[restoredPanelId] == projectDir)

// Cmd+T must open the new tab in the project directory, not home.
let createdPanel = try #require(restored.newTerminalSurfaceInFocusedPane(focus: false))
#expect(createdPanel.requestedWorkingDirectory == projectDir)
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Test will fail — production fix is absent

The new test asserts that updatePanelDirectory ignores a spurious home report after session restore, but the guard that enforces this was never committed. In Sources/Workspace.swift (line 1380-1388), restoredGuardedWorkingDirectoriesByPanelId is only armed when Self.unmountedVolumeRoot(for: guardedWorkingDirectory) != nil — i.e., the saved path must be on an unmounted volume. For a live, accessible /tmp/… project path the condition is false, the guard is never set, and shouldIgnoreRestoredGuardedDirectoryReport at line 4507-4511 falls into the guard missingVolumeRoot != nil else { …; return false } branch and lets the home write through. Both #expect(restored.currentDirectory == projectDir) assertions will fail. The PR description's "two-commit structure (red → green)" names a fix: commit that does not appear in the branch — git log da3d1a03..794b0b4c shows only the test: commit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This thread reviewed the test-only commit (I pushed the failing test first, then the fix). The fix is present in the current head: Workspace.swift now arms the restored-cwd guard for every local startup-handles-cwd restore (not just unmounted volumes), so shouldIgnoreRestoredGuardedDirectoryReport ignores the spurious post-resume home report. Both regression tests pass on CI (shard 2), and your latest review of the head commit reports 'Safe to merge'.

— Claude Code

@vercel

vercel Bot commented Jun 22, 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 Jun 23, 2026 1:04am

After Cmd+Q/restore of a workspace whose focused terminal runs an
auto-resumed agent, the resumed shell spawns in its default directory and
shell integration reports it (typically home) before the agent-resume
command cds into the project. While the project directory still exists
that spurious live pwd report must not overwrite the restored workspace
cwd, otherwise Cmd+T opens the next tab in home (~) instead of the
project directory.

The main test asserts the spurious home report is ignored (saved dir
still exists) so Cmd+T inherits the project dir; it fails until the
restore path guards the restored working directory. A companion test
asserts the home report IS honored when the saved dir was deleted between
sessions, so the guard cannot strand the cwd on a missing path.

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

@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 `@Sources/Workspace.swift`:
- Around line 1390-1393: The guard registration condition at the
startupHandlesWorkingDirectory check is too broad and includes remote restore
paths where localWorkingDirectory is nil, but the subsequent existence check
only uses FileManager.default.fileExists which operates on the local filesystem.
This causes remote saved paths like /home/... that don't exist locally to be
incorrectly accepted. Separate the logic by carrying context about whether the
terminal is local or remote throughout the guard and restoration flow, then
apply the local FileManager existence check only for local terminals while
implementing a remote-aware existence signal or policy for remote terminals that
does not treat local absence as a deleted-remote-cwd.
- Around line 4523-4528: The DEBUG log statements in the cmuxDebugLog calls are
logging sensitive directory paths that can expose usernames, customer names, or
project details. Replace the logging of the full restoredDirectory and
reportedDirectory path values with non-sensitive metadata alternatives such as
byte counts, branch outcome, or other safe indicators instead. Apply this change
to both debug log occurrences at lines 4523-4528 and 4546-4550, while keeping
panelId in the logs as it is safe to expose. Ensure the log message remains
clear and useful for debugging without revealing sensitive file system
information.
🪄 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: c10033b1-271a-4446-8b6f-740675132d8f

📥 Commits

Reviewing files that changed from the base of the PR and between 794b0b4 and fa6727c.

⛔ Files ignored due to path filters (1)
  • .github/swift-file-length-budget.tsv is excluded by !**/*.tsv
📒 Files selected for processing (2)
  • Sources/Workspace.swift
  • cmuxTests/AgentSessionAutoResumeSwiftTests.swift

Comment thread Sources/Workspace.swift
Comment thread Sources/Workspace.swift
…ort (#6617)

After session restore, a terminal whose startup command cds itself (agent
resume, tmux attach, agent-hook) is spawned without a working directory so
it tolerates a since-deleted saved directory. Its shell therefore starts
in the default directory and shell integration reports it (typically home)
before the startup command cds into the saved one. That spurious live pwd
report overwrote the restored panelDirectories/currentDirectory, so Cmd+T's
cwd-inheritance fallback resolved to home — the new tab opened in ~ instead
of the project directory the agent is in. This regressed the #6047 fix,
whose Cmd+T workspace-cwd fallback is correct but was fed a clobbered value.

The restore path already had a guard (restoredGuardedWorkingDirectoriesByPanelId)
to ignore such spurious reports, but it only armed when the saved directory
was on an unmounted volume. Arm it for every LOCAL startup-handles-cwd
restore with a saved directory, and have shouldIgnoreRestoredGuardedDirectoryReport:
- ignore the first mismatched report ONCE while the saved directory still
  exists (the startup command will cd into it),
- accept the report when the saved directory was deleted between sessions
  (the shell's reported cwd is then the real fallback — dropping it would
  strand the cwd on a missing path and make Cmd+T inherit an invalid dir),
- keep the existing persistent-ignore for unmounted volumes (#5278).

The guard is scoped to local terminals: its existence check stats the local
Mac, so remote restores (whose saved cwd is a remote path) keep the prior
behavior, matching the original unmounted-volume guard which was local-only.
A report matching the restored directory still clears the guard immediately.

Closes #6617

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@austinywang
austinywang force-pushed the issue-6617-cmdt-cwd-after-restore branch from fa6727c to 2084b4f Compare June 23, 2026 01:03
@austinywang
austinywang merged commit 448fc6c into main Jun 23, 2026
31 checks passed
austinywang added a commit that referenced this pull request Jun 23, 2026
Integrate #6625 (revert sidebar row-height layout feedback), #6617/#6621,
and #6624. ContentView conflict: #6625 removed the render-context/row
`sidebarWidth` threading while this branch added `pinResolutionContext` —
took #6625's sidebarWidth removal and kept pinResolutionContext. Font fix
(`magnifiedFont`/@Environment), lazy tooltips, and #6625's rowHeight probe
all preserved. swift-file-length-budget.tsv regenerated via --write-budget
(only ContentView's entry changes, +40 lines).

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

This branch was successfully deployed

1 active deployment
Preview – cmux — 2084b4fd Deployed Jun 23, 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.

Cmd+T opens new tab in home (~) after session restore — workspace/agent cwd not persisted across restart (regression of #6047)

1 participant