Repository navigation
Fix remote SSH workspace cwd tracking - #6747
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe PR adds Changessurface.report_pwd pipeline
Diff viewer launch update
Sequence Diagram(s)sequenceDiagram
participant ShellHooks as Shell hooks
participant Coordinator as ControlCommandCoordinator
participant TerminalController as TerminalController
participant Workspace as Workspace
ShellHooks->>Coordinator: surface.report_pwd(workspace_id, surface_id?, path)
Coordinator->>TerminalController: surfaceReportPWD(request.params)
TerminalController->>Workspace: controlSurfaceReportPWD(workspaceID, requestedSurfaceID, path)
Workspace-->>TerminalController: ControlSurfaceReportPWDResolution
TerminalController-->>Coordinator: ok / pending / not_found
Coordinator-->>ShellHooks: control call response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (1 error, 2 warnings)
✅ Passed checks (22 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR implements end-to-end remote SSH workspace cwd tracking by adding a
Confidence Score: 5/5Safe to merge — the new RPC, pending-queue pattern, and filesystem guards are all consistent with existing patterns in the codebase and well-covered by new integration tests. The implementation follows the established pending-state pattern (TTY, port-kick) exactly, adds proper cleanup on disconnect, and all remote-path filesystem guards are symmetric across every call site that was previously unguarded. Shell integration changes are additive and covered by regression tests for all three shells. No files require special attention. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Shell as Remote Shell (bash/zsh/fish)
participant Relay as cmux CLI relay
participant Socket as ControlSocket Coordinator
participant TC as TerminalController
participant WS as Workspace
Shell->>Relay: "rpc surface.report_pwd {workspace_id, path, surface_id}"
Relay->>Socket: surfaceReportPWD(params)
Socket->>TC: controlSurfaceReportPWD(workspaceID, surfaceID, path)
alt No surfaces registered yet (remote workspace)
TC->>WS: rememberPendingRemoteSurfacePWD(path, requestedSurfaceId)
TC-->>Socket: .pending
Socket-->>Relay: "{ok, pending: true}"
Note over WS: pendingRemoteSurfacePWD stored
WS->>WS: _didActivateRemoteTerminalSurface(panelId)
WS->>WS: applyPendingRemoteSurfacePWDIfNeeded(panelId)
WS->>WS: updatePanelDirectory(panelId, path)
else Surface registered
TC->>WS: updatePanelDirectory(surfaceId, path)
TC-->>Socket: .recorded(surfaceID)
Socket-->>Relay: "{ok, surface_id, path}"
end
%%{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"}}}%%
sequenceDiagram
participant Shell as Remote Shell (bash/zsh/fish)
participant Relay as cmux CLI relay
participant Socket as ControlSocket Coordinator
participant TC as TerminalController
participant WS as Workspace
Shell->>Relay: "rpc surface.report_pwd {workspace_id, path, surface_id}"
Relay->>Socket: surfaceReportPWD(params)
Socket->>TC: controlSurfaceReportPWD(workspaceID, surfaceID, path)
alt No surfaces registered yet (remote workspace)
TC->>WS: rememberPendingRemoteSurfacePWD(path, requestedSurfaceId)
TC-->>Socket: .pending
Socket-->>Relay: "{ok, pending: true}"
Note over WS: pendingRemoteSurfacePWD stored
WS->>WS: _didActivateRemoteTerminalSurface(panelId)
WS->>WS: applyPendingRemoteSurfacePWDIfNeeded(panelId)
WS->>WS: updatePanelDirectory(panelId, path)
else Surface registered
TC->>WS: updatePanelDirectory(surfaceId, path)
TC-->>Socket: .recorded(surfaceID)
Socket-->>Relay: "{ok, surface_id, path}"
end
Reviews (3): Last reviewed commit: "Make remote notification hook root expli..." | Re-trigger Greptile |
| guard let path = pendingRemoteSurfacePWD?.trimmingCharacters(in: .whitespacesAndNewlines), | ||
| !path.isEmpty else { | ||
| return false | ||
| } |
There was a problem hiding this comment.
The path is already trimmed and validated non-empty inside
rememberPendingRemoteSurfacePWD before it is stored in pendingRemoteSurfacePWD, so the re-trim here is redundant. A simpler guard that just checks for nil / empty after unwrapping would be clearer and consistent with how applyPendingRemoteSurfaceTTYIfNeeded reads the stored value directly without re-trimming.
| guard let path = pendingRemoteSurfacePWD?.trimmingCharacters(in: .whitespacesAndNewlines), | |
| !path.isEmpty else { | |
| return false | |
| } | |
| guard let path = pendingRemoteSurfacePWD, !path.isEmpty else { | |
| return false | |
| } |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| let rawPath = rawString(params, "path") | ||
| ?? rawString(params, "directory") | ||
| ?? rawString(params, "cwd") |
There was a problem hiding this comment.
The coordinator silently accepts
"directory" and "cwd" as undocumented aliases for the path key. No shell integration sends either of these keys — all three shells always use "path" — and the ControlSurfaceContext protocol doc only mentions path. Accepting three different keys without documenting them creates an invisible surface area in the API; if the intent is deliberate forward-compatibility, a comment explaining the aliases would prevent future readers from pruning them as dead code.
| let rawPath = rawString(params, "path") | |
| ?? rawString(params, "directory") | |
| ?? rawString(params, "cwd") | |
| // "directory" and "cwd" are accepted as forward-compatibility aliases for "path". | |
| let rawPath = rawString(params, "path") | |
| ?? rawString(params, "directory") | |
| ?? rawString(params, "cwd") |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Surface/ControlCommandCoordinator`+Surface3.swift:
- Around line 223-227: The cwd parsing in ControlCommandCoordinator+Surface3
currently treats path, directory, and cwd as interchangeable and silently picks
the first value, which can hide conflicting inputs. Update the logic around the
rawString(params, ...) lookup to require a single authoritative alias, and
reject the request with an invalid_params error if more than one of
path/directory/cwd is present with different trimmed values. Keep the existing
empty-path validation, but ensure the chosen remote cwd is derived only when the
aliases agree.
In `@Resources/shell-integration/fish/config.fish`:
- Around line 299-307: The cwd cache is being updated too early in the prompt
handler, causing missed retries when the report cannot actually be sent. Move
the set of _CMUX_PWD_LAST_PWD in config.fish so it only happens after
_cmux_send_bg or _cmux_report_pwd_via_relay succeeds, and keep the existing
precondition checks around the report path in the prompt/cwd reporting flow. Use
the current pwd-report logic around _CMUX_PWD_LAST_PWD, _cmux_socket_is_unix,
and _cmux_report_pwd_via_relay to ensure the launch cwd is retried until the
terminal surface is ready.
In `@Sources/Workspace.swift`:
- Around line 6279-6299: The pending remote cwd handling in
rememberPendingRemoteSurfacePWD and applyPendingRemoteSurfacePWDIfNeeded is
stripping valid leading/trailing spaces from the reported path. Remove the
trimming logic in both places so the exact shell-reported cwd is preserved when
storing pendingRemoteSurfacePWD and when later passing it to
updatePanelDirectory; keep the empty-path guard based on the unmodified string.
🪄 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: 71b03fd8-5dea-4d1e-895a-aad4c63997c1
📒 Files selected for processing (13)
Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Surface/ControlCommandCoordinator+Surface.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Surface/ControlCommandCoordinator+Surface3.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Surface/ControlSurfaceContext.swiftPackages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Surface/ControlSurfaceReportPWDResolution.swiftPackages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandContextTestStubs.swiftResources/shell-integration/cmux-bash-integration.bashResources/shell-integration/cmux-zsh-integration.zshResources/shell-integration/fish/config.fishSources/TerminalController+ControlSurfaceContext4.swiftSources/TerminalController.swiftSources/Workspace.swiftcmuxTests/FishShellIntegrationTests.swiftcmuxTests/GhosttyConfigTests.swift
06009c4 to
da3b3c7
Compare
There was a problem hiding this comment.
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 `@Sources/TerminalNotificationStore.swift`:
- Line 1057: The notification hook startup logic in TerminalNotificationStore is
relying on workspace?.surfaceTabBarDirectory being nil for remote workspaces,
and the non-remote branch also redundantly falls back to the same value already
represented by cwd. Update the notificationHooks(startingFrom:) call to pass nil
explicitly in the remote-workspace path, and simplify the non-remote path to use
cwd directly, keeping the behavior in line with the existing workspace/cwd
resolution used earlier in the method.
🪄 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: a0e5561c-c7aa-4758-bebc-25a31c1d3009
📒 Files selected for processing (2)
Sources/Feed/FeedCoordinator.swiftSources/TerminalNotificationStore.swift
Summary
surface.report_pwdso remote shell integrations can update the shared workspace panel directoryTesting
Issue: #6746
Closes #6746
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Summary by cubic
Fixes remote SSH workspace CWD tracking from the first prompt and stops local config/hook scans on remote paths. Adds and advertises the
surface.report_pwdRPC; bash/zsh/fish now report CWD via socket or the remote relay. Addresses #6746.surface.report_pwdend-to-end with alias support (path/directory/cwd), conflict checks, and clear not_found errors; capability is now advertised.cmux-{bash,zsh}and fish prompts to report CWD (UNIX socket when present, relay otherwise) with last-PWD dedupe; added relay helpers and regression tests for bash/zsh/fish.FeedCoordinatorandTerminalNotificationStore.Written for commit af708de. Summary will update on new commits.
Summary by CodeRabbit
New Features
surface.report_pwdcommand so the app can process directory reports.Bug Fixes
path/cwdinputs, rejecting conflicting or missing values.Tests
surface.report_pwdfor bash/zsh relay scenarios and parameter validation.