Add local tmux support to the remote-tmux mirror with two-way sync
Summary
Makes the tmux -CC mirror work against the local machine's tmux server as a first-class endpoint — no SSH — reusing the entire existing control-mode stack (parser, control connection, session/window mirrors, sizing) unchanged. Sync is two-way exactly like a remote mirror: splits, closes, renames, reorders, and new windows made in cmux propagate to tmux, and tmux-side changes (including from a plain tmux client co-attached to the same session) appear in cmux.
How
RemoteTmuxHostgains aKind(.ssh/.local) and a canonical.localvalue. The local endpoint keys its ownconnectionHashnamespace (the literal"local", which can never collide with an SSH host's 16-hex digest — an ssh alias actually namedlocalstays a distinct endpoint), skips all ControlMaster socket work, and builds directtmuxargv through the same resolver script the SSH path uses (so Homebrew/MacPorts tmux is found from a GUI app's bare PATH, and missing-tmux classification is identical).RemoteTmuxSSHTransportruns local one-shots directly (/bin/shresolver argv fortmux …,/usr/bin/envotherwise);ensureMasterReady/ssh -O check/ssh -O exitdegenerate to no-ops, soRemoteTmuxControllerneeded no local-vs-ssh branching.RemoteTmuxControlConnectionspawns the localtmux -CCclient under a locally-allocated PTY (newRemoteTmuxLocalPTY): control mode requires a controlling tty (bare pipe →tcgetattr failed);ssh -ttsupplies it remotely, cmux supplies it locally. The slave is made raw before launch (no echo/ONLCR can touch the control stream), the writer gets adupof the master so reader/writer closes can't double-close, and stderr stays a separate pipe so failure classification keeps working. The child env stripsTMUX/TMUX_PANEand guarantees aTERM.- Socket API: every
remote.tmux.*method acceptslocal: truein place ofhost. - CLI: new
cmux tmux [--no-focus] [--new-window]command (help localized in all 20 catalog locales). - Image paste into a local mirror inserts the macOS path directly instead of scp-uploading.
- Docs: "Local tmux" section on the remote-tmux docs page (en/ja catalogs).
Verification
- New
cmuxTests/RemoteTmuxLocalEndpointTests(wired into the pbxproj): identity invariants, argv shapes, socket-param parsing, transport local exec, and a live end-to-end test that creates a session on an isolated (TMUX_TMPDIR) local server, attaches the real control connection under a local PTY, waits for%enter+ topology publication, lands an out-of-bandsplit-windowin mirror state (tmux→cmux), and lands a control-streamsplit-windowon the server (cmux→tmux). Skips silently when no tmux is installed. - All 5 tests green locally (
cmux-unitscheme); tagged Debug build green. - App-level dogfood against a live lab server via the debug socket:
cmux tmuxmirrored the session; tmux-side split +rename-windowappeared in cmux (pane surfaces + tab title); cmux-side new tab routed tonew-window, workspace rename routed torename-session;remote.tmux.detachleft the session alive.
Localization audit
New user-facing strings: CLI help (cli.help.tmux) added to Resources/Localizable.xcstrings with translations for all 20 locales the catalog carries; docs page strings added to web/messages/en.json and web/messages/ja.json (the remote-tmux docs page is en/ja-only per remoteTmuxDocsLocales). No new shortcuts, settings rows, alerts, or error strings.
🤖 Generated with Claude Code
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.
Summary by cubic
Adds first‑class support for mirroring the local tmux server with full two‑way sync, plus auto‑mirroring of new sessions and routing “New Workspace” to tmux when a local mirror is selected. Also adds sane working directories, focus‑gated sizing, and close‑to‑kill for local sessions.
-
New Features
cmux tmux [--no-focus] [--new-window]mirrors local sessions; sync is two‑way.- Socket API: every
remote.tmux.*method acceptslocal: trueinstead ofhost. - Auto‑mirror:
%sessions-changedtriggers a debounced re‑discovery that mirrors only new sessions (skips during an explicit attach). - “New Workspace” in a window with a selected local tmux mirror creates
tmux new-session -d, mirrors it, and selects it; falls back to a plain workspace on failure. - New‑tab cwd: falls back to
-c '#{pane_current_path}'when no concrete path is known; local “New Workspace” starts at$HOME. - Focus‑gated sizing: while the app isn’t frontmost, send
refresh-client -f ignore-size; re‑assert on return and after reconnect. - Closing a local mirror workspace kills its tmux session; SSH mirrors still detach.
- Image paste into a local mirror inserts the local file path (no upload).
- Docs: added “Local tmux” section and localized CLI help.
-
Refactors
RemoteTmuxHostaddsKind(.ssh/.local) and a canonical.localendpoint with its ownconnectionHash; builds directtmuxargv via the shared resolver.RemoteTmuxSSHTransportruns local commands directly; ControlMaster warmup/check/exit are no‑ops for local.RemoteTmuxControlConnectionspawns localtmux -CCunderRemoteTmuxLocalPTY; stripsTMUX/TMUX_PANE, ensuresTERM;%sessions-changednow notifies observers for reconcile; reconnect re‑applies size authority.
Summary by CodeRabbit
-
New Features
- Added support for running
cmux tmuxagainst a local tmux server (no SSH), including local bidirectional mirroring. - Extended remote tmux socket commands to support
local: truetargeting. - Improved mirrored session behavior with server-wide
%sessions-changedreconciliation and local workspace routing.
- Added support for running
-
Bug Fixes
- Improved command suggestions to recognize
tmux. - Prevented local mirror panes from using SSH-based upload target resolution.
- Improved command suggestions to recognize
-
Documentation
- Added localized
cmux tmuxhelp text. - Updated remote tmux landing pages with “local tmux” usage and examples.
- Added localized