Add local tmux support to the remote-tmux mirror with two-way sync

NA
1mo ago
+1153-65

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

  • RemoteTmuxHost gains a Kind (.ssh / .local) and a canonical .local value. The local endpoint keys its own connectionHash namespace (the literal "local", which can never collide with an SSH host's 16-hex digest — an ssh alias actually named local stays a distinct endpoint), skips all ControlMaster socket work, and builds direct tmux argv 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).
  • RemoteTmuxSSHTransport runs local one-shots directly (/bin/sh resolver argv for tmux …, /usr/bin/env otherwise); ensureMasterReady / ssh -O check / ssh -O exit degenerate to no-ops, so RemoteTmuxController needed no local-vs-ssh branching.
  • RemoteTmuxControlConnection spawns the local tmux -CC client under a locally-allocated PTY (new RemoteTmuxLocalPTY): control mode requires a controlling tty (bare pipe → tcgetattr failed); ssh -tt supplies it remotely, cmux supplies it locally. The slave is made raw before launch (no echo/ONLCR can touch the control stream), the writer gets a dup of the master so reader/writer closes can't double-close, and stderr stays a separate pipe so failure classification keeps working. The child env strips TMUX/TMUX_PANE and guarantees a TERM.
  • Socket API: every remote.tmux.* method accepts local: true in place of host.
  • 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-band split-window in mirror state (tmux→cmux), and lands a control-stream split-window on the server (cmux→tmux). Skips silently when no tmux is installed.
  • All 5 tests green locally (cmux-unit scheme); tagged Debug build green.
  • App-level dogfood against a live lab server via the debug socket: cmux tmux mirrored the session; tmux-side split + rename-window appeared in cmux (pane surfaces + tab title); cmux-side new tab routed to new-window, workspace rename routed to rename-session; remote.tmux.detach left 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


View with Codesmith Autofix with Codesmith
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 accepts local: true instead of host.
    • Auto‑mirror: %sessions-changed triggers 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

    • RemoteTmuxHost adds Kind (.ssh/.local) and a canonical .local endpoint with its own connectionHash; builds direct tmux argv via the shared resolver.
    • RemoteTmuxSSHTransport runs local commands directly; ControlMaster warmup/check/exit are no‑ops for local.
    • RemoteTmuxControlConnection spawns local tmux -CC under RemoteTmuxLocalPTY; strips TMUX/TMUX_PANE, ensures TERM; %sessions-changed now notifies observers for reconcile; reconnect re‑applies size authority.

Summary by CodeRabbit

  • New Features

    • Added support for running cmux tmux against a local tmux server (no SSH), including local bidirectional mirroring.
    • Extended remote tmux socket commands to support local: true targeting.
    • Improved mirrored session behavior with server-wide %sessions-changed reconciliation and local workspace routing.
  • Bug Fixes

    • Improved command suggestions to recognize tmux.
    • Prevented local mirror panes from using SSH-based upload target resolution.
  • Documentation

    • Added localized cmux tmux help text.
    • Updated remote tmux landing pages with “local tmux” usage and examples.