Skip to content

Add detachable SSH PTY daemon persistence - #4807

Merged
lawrencecchen merged 86 commits into
mainfrom
feat-ssh-detachable-pty
May 31, 2026
Merged

lawrencecchen merged 86 commits into
mainfrom
feat-ssh-detachable-pty

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented May 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add persistent per-slot cmuxd-remote daemon mode for normal cmux ssh PTY sessions.
  • Preserve remote PTY session IDs, relay port metadata, and restore attach commands across app relaunch only when a persistent daemon slot and relay port exist.
  • Add CLI, Swift, Go daemon, tests_v2, docs, and tmux corpus PR workflow coverage.

Testing

  • ./scripts/reload.sh --tag sshpty
  • ./scripts/reload.sh --tag sshpty --launch (tagged app launched, but local socket later refused connections, so tests_v2 was not used as local proof)
  • git diff --check
  • go test ./... -run ^$ -exec /usr/bin/true (daemon/remote compile gate)
  • python3 -m py_compile tests_v2/test_ssh_remote_detachable_pty.py

Notes

  • Local Go test execution on this Mac still aborts with dyld missing LC_UUID for the generated test binary, so executable Go tests need to run on CI/AWS.
  • This changes runtime SSH behavior and should stop at dogfood handoff before merge.

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


Note

High Risk
Changes SSH remote bootstrap, session restore, relay/daemon lifecycle, and orphan cleanup—core infrastructure where regressions affect live remote workspaces and terminal state.

Overview
This PR wires detachable persistent SSH PTY through the CLI, app, and cmuxd-remote: each eligible cmux ssh workspace gets a validated persistent_daemon_slot, remote bootstrap runs serve --stdio --persistent --slot, and snapshots carry relayPort, slot, and isRemoteTerminal so relaunch can ssh-pty-attach --require-existing only when a live local socket and slot metadata exist.

Restore and lifecycle changes avoid silently turning failed remote attaches into local shells: persistent panes stay visible on child exit, ended sessions are not blindly reattached, relay RPCs remap restored workspace/surface IDs, and forked agent workspaces do not inherit the parent’s persistent relay identity. Operational hardening adds slot-aware stale relay/orphan cleanup, stricter slot validation, localized daemon capability errors, RemoteInteractiveShellBootstrapBuilder for restored remote shells, and shell-wrapped attach startup commands (optional embedded remote command via --command-b64).

CI / app polish: macOS lag job timeout commentary stays at 55m; tmux corpus runs on PRs touching daemon/remote/** with shorter fuzz time; bundled Ghostty resources are preferred over inherited GHOSTTY_RESOURCES_DIR; browser tab audio mute syncs to the sidebar.

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


Summary by cubic

Adds detachable SSH PTY sessions backed by a per‑slot persistent cmuxd-remote daemon so remote shells survive terminal close and app relaunch. Restore only reattaches when a live or reserved local socket exists; ended sessions don’t auto‑start, and the CLI auto‑assigns a slot with slot‑scoped list/attach/cleanup.

  • New Features

    • Persistent daemon: cmuxd-remote serve --stdio --persistent --slot <slot> proxies to a per‑slot server with token auth, single‑owner lock, a short per‑user Unix socket, and state under ~/.cmux/daemon/<version>/<slot>/.
    • CLI/app/restore: auto‑generate and pass persistent_daemon_slot; add ssh-session-list, ssh-session-attach, ssh-session-cleanup; snapshots include isRemoteTerminal and slot; restore consults TerminalController.currentSocketPathForRemoteRestore() and reattaches via ssh-pty-attach --require-existing; new RemoteInteractiveShellBootstrapBuilder; batch exec starts the daemon with --persistent --slot.
    • CI/Docs/Build: tmux corpus runs on PRs touching daemon/remote/** with 30s fuzz; macOS 15 release/nightly; prefer Homebrew Zig and enforce Zig 0.15.2; docs/spec updated; new Python integration tests_v2/test_ssh_remote_detachable_pty.py; daemon tests preserve event frames during RPC calls.
  • Bug Fixes

    • Restore/lifecycle: gate restore on live/reserved socket and preserve_after_terminal_exit; wait for restored PTY foreground auth before reattach; avoid reattaching ended PTYs; keep exits visible for persistent panes; preserve split panes and remap IDs; forked agent workspaces don’t reuse parent relay/slot; clear failed attach; reconnect restored remote browser workspaces.
    • Security/cleanup: strict persistent_daemon_slot validation; hardened socket dir; unique token temp files; sessions persist across token rotation; cancel stale reverse‑forwards; slot‑aware orphan/relay cleanup; stabilized daemon tests.
    • Fidelity/UI: preserve SSH options, terminfo, and local cwd on remote restore; localized error when the remote daemon lacks persistent PTY support; prefer bundled Ghostty resources over inherited GHOSTTY_RESOURCES_DIR.

Written for commit 603bb76. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Persistent per‑slot detachable SSH PTY daemon; new CLI session commands to list/attach/cleanup SSH sessions; startup/attach commands now invoked via a shell-wrapped script and support embedded remote commands; snapshots include workspace id and remote-terminal markers.
  • Bug Fixes

    • Stricter validation and safer handling of persistent slot, relay/port, and restore edge cases; improved fork/restore and orphaned SSH cleanup behavior.
  • Documentation

    • Updated remote daemon docs, CLI contract, living spec, and TMUX corpus for persistent PTY flows.
  • Tests

    • Extensive new integration/unit tests covering persistent-daemon auth, PTY restore/reattach, CLI flows, and socket security.
  • Chores

    • CI: PR trigger for workflows and reduced fuzz time on pull-request runs.

Review Change Stack

@vercel

vercel Bot commented May 26, 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 31, 2026 1:52am
cmux-staging Building Building Preview, Comment May 31, 2026 1:52am

@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 26, 2026 •

Copy link
Copy Markdown

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 per-slot persistent SSH PTY daemon support, slot validation, snapshot/restore reminted relay credentials, authenticated per-slot daemon client/server, CLI command assembly and attach-wrapping, workspace aliasing/command rewriting, orphaned-SSH cleanup updates, docs/CI changes, and broad tests (Go/Swift/Python).

Changes

Persistent SSH PTY daemon

Layer / File(s) Summary
Daemon server/client & Go tests
daemon/remote/cmd/cmuxd-remote/main.go, daemon/remote/cmd/cmuxd-remote/main_test.go
Implements per-slot persistent-daemon mode with --persistent/--persistent-server/--slot, atomic slot token/bootstrap, auth handshake, reader-backed RPC, single-instance lock, readiness signaling, and comprehensive tests covering paths, token/auth/timeouts/replay and CLI validation.
Workspace restore, remote config & aliasing
Sources/WorkspaceRemoteConfiguration.swift, Sources/Workspace.swift
Adds relayPort/persistentDaemonSlot to snapshots; normalizes/validates slots; remints relay credentials on restore and wires restored relay/slot into WorkspaceRemoteConfiguration; gates PTY restore on preserveAfterTerminalExit + normalized slot/socket/port + reusable-foreground-auth SSH options; introduces alias maps and command rewriting and threads slot into orphaned-SSH detection and fork sanitization.
CLI slot generation & batch command assembly
CLI/cmux.swift, Sources/WorkspaceRemoteSSHBatchCommandBuilder.swift
CLI derives persistentDaemonSlot when enabled and conditionally sets preserve_after_terminal_exit/persistent_daemon_slot in configure/payload; batch builder composes serve args with optional --persistent --slot <slot> and wraps in an exec shell script; SSH PTY attach command now returned as /bin/sh -c '...' and may embed a base64 --command-b64 payload.
TerminalController socket accessor & validation
Sources/TerminalController.swift
Adds currentSocketPathForRemoteRestore(); trims and validates persistent_daemon_slot inputs, rejects ./.., enforces cross-parameter rules with preserve_after_terminal_exit, and returns invalid_params on validation failures; maps validated string to persistentDaemonSlot or nil.
Session persistence & TabManager note
Sources/SessionPersistence.swift, Sources/TabManager.swift
Adds SessionTerminalPanelSnapshot.isRemoteTerminal and SessionWorkspaceSnapshot.id to persisted snapshots; updates TabManager child-exit handling to gate persistent-visibility on preserveAfterTerminalExit.
Remote interactive shell bootstrap
Sources/RemoteRelayZshBootstrap.swift
Adds RemoteInteractiveShellBootstrapBuilder to generate login-shell bootstrap scripts, shell feature normalization, optional bundled integration scripts, terminfo handling, relay warmup lines, and quoting helpers.
Swift tests: snapshot, RPC validation, orphan cleanup, remote connect, fork
cmuxTests/*
Adds and updates tests asserting persistent_daemon_slot shaping/presence, snapshot restore and fallback behaviors, RPC invalid_params cases, orphaned-SSH PID matching with --slot, remote-session end/seed behavior, fork sanitization clearing relay/slot fields, and TabManager persistent-panel behavior.
End-to-end detachable PTY Python integration test
tests_v2/test_ssh_remote_detachable_pty.py
New script exercising detachable SSH PTY lifecycle: create detachable SSH workspace, probe shell, detach, verify session persist/scrollback, reattach, assert state preserved, and cleanup helpers.
Docs & CI adjustments
.github/workflows/tmux-corpus.yml, daemon/remote/README.md, daemon/remote/TMUX_CORPUS.md, docs/cli-contract.md, docs/remote-daemon-spec.md
Documents persistent per-slot daemon behavior, new pty.* RPC methods, CLI commands (ssh-session-*), capability gating, acceptance scenarios and TMUX corpus CI clarifications; CI workflow adds pull_request path filter and forces FUZZTIME 30s for PRs.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I stitched a slot named ssh-quick-hop,
So shells can nap, then spring back on top.
Detach with a twirl, reattach with a cheer,
The daemon keeps tunnels cozy and near.
Hooray for slots that hold our shells dear!

✨ 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 feat-ssh-detachable-pty

Comment thread daemon/remote/cmd/cmuxd-remote/main.go
@greptile-apps

greptile-apps Bot commented May 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds detachable persistent SSH PTY sessions: each SSH workspace gets a cmuxd-remote serve --persistent --slot daemon on the remote, and the app persists relay port, slot, and PTY session IDs so terminals can reattach after app relaunch. Previous review concerns (startup polling sleep, missing auth deadlines, non-constant-time token comparison, missing server-side auth deadline, and shell placeholder substitution) are all addressed in the current head.

  • Go daemon (main.go): Persistent daemon uses a ready-pipe for startup sync, subtle.ConstantTimeCompare for token auth, symmetric client and server auth deadlines, and atomic token/socket-dir creation via os.Link. Idle exit uses accept-deadline polling (a well-established Go accept-loop idiom, not a synchronization sleep).
  • Swift restore path (Workspace.swift, WorkspaceRemoteConfiguration.swift): Restore gates on a live/reserved local socket and full slot+port metadata; forked-agent workspaces explicitly opt out of PTY restore (allowPersistentPTYRestore: false); relay ID aliases are re-mapped after relaunch; and a new suppressRemoteTerminalStartupForSessionRestoreScaffold boolean flag suppresses the workspace-level remote startup command during layout reconstruction (flagged as an architectural smell).
  • Localization (Localizable.xcstrings): All five new user-facing error strings carry entries for all 19 supported locales.

Confidence Score: 5/5

Safe to merge at dogfood stage; previous blocking concerns about auth timing, polling sleeps, and token comparison are all resolved in this head.

The persistent daemon auth path is solid: ready-pipe startup, constant-time token comparison, symmetric auth deadlines, and atomic file creation via hard-link. Session restore correctly gates on live socket + full metadata, forked workspaces opt out of PTY restore, and all 19 locales are covered. The two flagged items are style-level: a flag/side-channel for restore sequencing and continued growth of an already very large Workspace.swift.

Sources/Workspace.swift — restore sequencing flag and file size; daemon/remote/cmd/cmuxd-remote/main.go is the critical new path but the auth and lifecycle logic looks correct.

Important Files Changed

Filename Overview
daemon/remote/cmd/cmuxd-remote/main.go Adds ~890 lines implementing persistent per-slot daemon mode: startup via ready-pipe, token auth with constant-time compare, server-side auth deadline, atomic token creation via Link, and socket-dir fallback.
Sources/Workspace.swift Adds persistent PTY session restore, relay ID aliasing, stale relay cleanup, and orphan detection. Introduces suppressRemoteTerminalStartupForSessionRestoreScaffold flag (architectural concern) and grows the already-oversized file by 877 lines.
Sources/RemoteInteractiveShellBootstrapBuilder.swift New 278-line builder for remote interactive shell bootstrap scripts; correctly splits placeholder sentinel patterns to prevent literal export, handles zsh/bash/fallback shells.
Sources/WorkspaceRemoteConfiguration.swift Adds persistentDaemonSlot and relayPort to snapshot/config, gates restore on live/reserved socket and slot, uses SecRandomCopyBytes for relay token entropy.
Sources/TerminalController.swift Adds currentSocketPathForRemoteRestore(), persistent_daemon_slot validation, and auto-assignment gated on preserve_after_terminal_exit.
Sources/TabManager.swift Keeps persistent PTY surfaces visible after child exit, routes to markPersistentRemotePTYAttachFailed on attach failure.
Sources/cmuxApp.swift Prefers bundled Ghostty resources, sets TERMINFO from bundle, switches XDG_DATA_DIRS/MANPATH from append to prepend.
Resources/Localizable.xcstrings All 19 supported locales present for each of the five new error string keys.
Sources/WorkspaceRemoteSSHBatchCommandBuilder.swift Adds --persistent --slot to batch exec, adds reverseRelayControlMasterCancelArguments.
Sources/SessionPersistence.swift Adds isRemoteTerminal and persists relay port and slot for cross-launch PTY reattach.

Reviews (68): Last reviewed commit: "fix: wait for restored pty foreground au..." | Re-trigger Greptile

Comment thread daemon/remote/cmd/cmuxd-remote/main.go
Comment thread daemon/remote/cmd/cmuxd-remote/main.go Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes May 26, 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: 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 `@CLI/cmux.swift`:
- Around line 6654-6656: The optional unwrap around persistentDaemonSlot inside
the usesPersistentSSHPTY branch is redundant; inside the same scope
persistentDaemonSlot is guaranteed non-nil (see usesPersistentSSHPTY check).
Remove the inner "if let persistentDaemonSlot { ... }" and directly assign
configureParams["persistent_daemon_slot"] = persistentDaemonSlot (or restructure
to safely bind once where persistentDaemonSlot is introduced), referencing the
configureParams dictionary, usesPersistentSSHPTY check, and the
persistentDaemonSlot variable so the value is set without an extra optional
check.

In `@daemon/remote/cmd/cmuxd-remote/main.go`:
- Around line 383-386: The open-for-create branch treating errors.Is(err,
os.ErrExist) should not immediately call readExisting() because another process
may have created the file but not finished writing the token; modify the
os.OpenFile error path so that when errors.Is(err, os.ErrExist) you retry for a
short window (e.g., up to ~200–500ms total) with small sleeps between attempts
and then call readExisting() only after retry timeout or when readExisting()
succeeds with a non-empty token; reference the token file handling around
os.OpenFile(paths.tokenFile, ...) and the readExisting() call and implement a
bounded retry/backoff loop to avoid returning the empty-file error during
concurrent first-run creation.

In `@docs/remote-daemon-spec.md`:
- Around line 198-199: The acceptance-test matrix contains duplicate test IDs:
RZ-003 and RZ-004 are repeated; locate the later occurrences of the rows that
read "| RZ-003 | detach smallest, PTY expands to next smallest | DONE |" and "|
RZ-004 | reconnect preserves session + applies recomputed size | DONE |" and
either remove those duplicate rows or renumber them to unique IDs (e.g., RZ-00x)
so each test ID appears only once; update any cross-references or the status
column as needed to keep the matrix consistent.
🪄 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: f364eb17-fc8f-4b42-8e82-4fddb6e0c0ef

📥 Commits

Reviewing files that changed from the base of the PR and between 4faba0c and b495d43.

📒 Files selected for processing (16)
  • .github/workflows/tmux-corpus.yml
  • CLI/cmux.swift
  • Sources/TerminalController.swift
  • Sources/Workspace.swift
  • Sources/WorkspaceRemoteConfiguration.swift
  • Sources/WorkspaceRemoteSSHBatchCommandBuilder.swift
  • cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift
  • cmuxTests/TabManagerSessionSnapshotTests.swift
  • cmuxTests/TerminalControllerSocketSecurityTests.swift
  • daemon/remote/README.md
  • daemon/remote/TMUX_CORPUS.md
  • daemon/remote/cmd/cmuxd-remote/main.go
  • daemon/remote/cmd/cmuxd-remote/main_test.go
  • docs/cli-contract.md
  • docs/remote-daemon-spec.md
  • tests_v2/test_ssh_remote_detachable_pty.py

Comment thread CLI/cmux.swift Outdated
Comment thread daemon/remote/cmd/cmuxd-remote/main.go Outdated
Comment thread docs/remote-daemon-spec.md Outdated
Comment thread Sources/Workspace.swift
Comment thread Sources/Workspace.swift
Comment thread daemon/remote/cmd/cmuxd-remote/main.go
Comment thread Sources/TerminalController.swift
Comment thread Sources/Workspace.swift
Comment thread daemon/remote/cmd/cmuxd-remote/main.go
Comment thread Sources/Workspace.swift Outdated
Comment thread Sources/WorkspaceRemoteConfiguration.swift Outdated
Comment thread daemon/remote/cmd/cmuxd-remote/main.go Outdated
Comment thread Sources/WorkspaceRemoteSSHBatchCommandBuilder.swift
coderabbitai[bot]
coderabbitai Bot previously requested changes May 26, 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/WorkspaceRemoteConfiguration.swift (1)

389-428: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Validate persistentDaemonSlot before enabling PTY restore.

This gate treats any non-empty slot as valid, but cmuxd-remote only accepts [A-Za-z0-9._-]{1,128}. An edited/corrupted snapshot with a bad slot will still turn preservePTYSession on here and build the persistent attach path, only to fail later in the daemon instead of taking the plain-SSH fallback you already use for missing inputs.

🤖 Prompt for 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.

In `@Sources/WorkspaceRemoteConfiguration.swift` around lines 389 - 428, The
preservePTYSession flag currently treats any non-nil
normalizedPersistentDaemonSlot as valid; update the logic that computes
preservePTYSession to validate normalizedPersistentDaemonSlot against the
allowed daemon slot pattern ([A-Za-z0-9._-]{1,128}) before using it, so that
preservePTYSession is only true when the slot matches that regex; locate the
preserved session gating in WorkspaceRemoteConfiguration where
normalizedPersistentDaemonSlot is referenced (the preservePTYSession
computation) and add a validation step (or helper like
isValidPersistentDaemonSlot(_:)) to reject malformed slots so the code falls
back to plain SSH instead of attempting to build a persistent attach path.
🤖 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 `@daemon/remote/cmd/cmuxd-remote/main.go`:
- Around line 679-693: The recovery logic in recoverPersistentDaemonAuthFailure
currently kills the PID from persistentDaemonLockPID and removes paths.socket
without verifying that PID/socket belong to the same daemon; change this to
first perform a stronger liveness/identity check (e.g., attempt a local
connection to the socket and validate a daemon-specific handshake/identity, or
verify the process cmdline/owner for the PID) before calling syscall.Kill or
removing paths.socket; if the identity check fails or cannot be performed, do
not SIGTERM or unlink the socket and instead return the original authErr (i.e.,
fail closed), use waitPersistentDaemonLockAvailable only after identity is
confirmed, and keep references to paths.lockFile, persistentDaemonLockPID,
waitPersistentDaemonLockAvailable and paths.socket to locate where to implement
the check.

---

Outside diff comments:
In `@Sources/WorkspaceRemoteConfiguration.swift`:
- Around line 389-428: The preservePTYSession flag currently treats any non-nil
normalizedPersistentDaemonSlot as valid; update the logic that computes
preservePTYSession to validate normalizedPersistentDaemonSlot against the
allowed daemon slot pattern ([A-Za-z0-9._-]{1,128}) before using it, so that
preservePTYSession is only true when the slot matches that regex; locate the
preserved session gating in WorkspaceRemoteConfiguration where
normalizedPersistentDaemonSlot is referenced (the preservePTYSession
computation) and add a validation step (or helper like
isValidPersistentDaemonSlot(_:)) to reject malformed slots so the code falls
back to plain SSH instead of attempting to build a persistent attach path.
🪄 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: 961c5557-c715-4c53-81f0-b5e6daeec963

📥 Commits

Reviewing files that changed from the base of the PR and between fc5f4b0 and 4251df2.

📒 Files selected for processing (7)
  • Sources/TerminalController.swift
  • Sources/Workspace.swift
  • Sources/WorkspaceRemoteConfiguration.swift
  • cmuxTests/TabManagerSessionSnapshotTests.swift
  • cmuxTests/TerminalControllerSocketSecurityTests.swift
  • daemon/remote/cmd/cmuxd-remote/main.go
  • daemon/remote/cmd/cmuxd-remote/main_test.go

Comment thread daemon/remote/cmd/cmuxd-remote/main.go Outdated
Comment thread Sources/TerminalController.swift
Comment thread daemon/remote/cmd/cmuxd-remote/main.go Outdated
Comment thread daemon/remote/cmd/cmuxd-remote/main.go
Comment thread daemon/remote/cmd/cmuxd-remote/main.go

@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 5f7148c. Configure here.

Comment thread Sources/TabManager.swift
@lawrencecchen
lawrencecchen merged commit 25a710d into main May 31, 2026
21 checks passed
@lawrencecchen
lawrencecchen deleted the feat-ssh-detachable-pty branch May 31, 2026 02:43
hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request May 31, 2026
Includes detachable SSH PTY persistence (manaflow-ai#4807), titlebar polish,
Hermes session restore + pre_tool_call notif, omnibar lag fix,
sidebar extension polish, blank sidebar icon fallback, browser
extension pane integration, GitHub GraphQL rate-limit handling,
sidebar resize-toggle drag, large diff viewer pre-render.

Conflicts resolved:
- Workspace.swift: keep fork's layoutTabs scaffolding while adopting
  upstream's snapshotWorkspaceId-aware restore signature, persistent
  SSH PTY restored session-id path, browser tab mute (manaflow-ai#5005), and
  the relayPort-aware reverse-relay control-master invocation.
- AppDelegate.swift, ShortcutBareStartRouting.swift: combine fork's
  toggleQuickTerminal exception with upstream's browser-content
  shortcut filter.
- UpdateTitlebarAccessory.swift: keep both fork's
  rightSidebarToggleControllers + sidebarTrailingEdgesByWindow and
  upstream's titlebar control changes.
- TerminalControllerSocketSecurityTests.swift: keep both fork's v2
  surface report-pwd remote workspace test and upstream's
  preserve_after_terminal_exit + remote PTY resize tests.
- SessionBlueprintEncoder.swift: extend StableLayout encoder with the
  new PanelType.extensionBrowser case.
- CmuxSettingsUI/SettingsWindowScene.swift: rename the local
  `anchor` binding so fork's host-injected extra-section path
  doesn't shadow upstream's new function-scope `anchor` parameter.

This branch was successfully deployed

1 active deployment
Preview – cmux — 603bb76f Deployed May 31, 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