Added tmux and multi-wide compatibility#112
Open
aditya-kapadia wants to merge 18 commits into
Open
Conversation
fixing macos mojave issues
fixing macos mojave issues
A Formula/csshx.rb
D Formula/csshx.rb
Fix compatibility with macOS Big Sur
…kends Stdlib-only Python 3 cluster-SSH tool under csshx-latest/. Replaces the original csshX TIOCSTI keystroke-injection hack with real PTYs and a pluggable Launcher protocol. Backends shipped: WaveTerm, tmux, iTerm2, Terminal.app, Kitty, WezTerm, plus a Manual fallback that prints attach commands for any terminal. Master process owns every PTY and bridges them through per-slave UNIX sockets gated by 32-byte AUTH tokens. Suite of 33 pytest cases. The original Perl csshX, README.txt, and surrounding files are left exactly as-is. A new top-level README.md points users at both. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
slave.py: add a per-slave scrollback buffer (capped at 64 KiB) that captures every byte the PTY emits before any terminal block has connected, then replays it to each new client right after AUTH. The bridge previously dropped any output that arrived between fork-exec of ssh and the launcher spawning the visible block — which on WaveTerm is long enough to lose the banner, MOTD, and login prompt, leaving the block blank. A small state_lock makes the "extend scrollback / snapshot writers" and "replay scrollback / register writer" paths atomic so no chunk is duplicated or lost across the race. waveterm.py: flip _run's default to capture=True so the legacy wsh probes in tile() (setlayout, layout, tile) plus deleteblock and settitle no longer spit error text into the user's terminal on modern wsh builds where those subcommands have been renamed or removed. Adds tests/test_slave_bridge.py covering: late-client scrollback replay, scrollback cap, and that a wrong AUTH token never receives any buffered output. Skips cleanly on hosts without Unix-domain sockets. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When the master rejects an AUTH attempt it closes the socket without sending any data. The fallback attach client used to read 0 bytes, fall through to ``return 0``, and exit silently — the spawned terminal block flashed and disappeared with no explanation. Track whether any bytes have been received; on EOF with received_any=False, print a specific diagnostic to stderr (token mismatch is the realistic cause) and exit 1. Adds tests/test_attach.py covering: - AUTH rejection (server closes immediately) → rc=1 with stderr - Normal EOF after data → rc=0, no rejection message - Bad argv → rc=2 - Connect to missing socket → rc=1 Skips on Windows since attach.py is a Unix-only client. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two issues bit only on macOS, both via tests that exercised AF_UNIX sockets and a Slave shutdown path: * macOS limits ``sockaddr_un.sun_path`` to 104 bytes (Linux is 108). pytest's ``tmp_path`` lives at ``/private/var/folders/.../pytest-of-USER/pytest-N/test_name0/`` which routinely blew past the limit and aborted ``bind()``. Replace ``tmp_path`` with a new ``short_socket_dir`` fixture that uses ``tempfile.mkdtemp(prefix="csshx-")`` for a path with plenty of headroom under the cap. * ``shutdown_slave`` calls ``os.kill(slave.pid, SIGTERM)``. POSIX treats ``os.kill(0, ...)`` as "signal every process in my process group" — i.e. pytest itself. Tests that built a Slave with ``pid=0`` were one accidental cleanup-call away from the test runner killing itself. Add a ``harmless_pid`` fixture that spawns a short-lived ``time.sleep`` subprocess and yields its PID; reap it on teardown. ``test_broadcaster.py`` still passes ``pid=0`` because that suite never reaches ``shutdown_slave``, only the broadcaster write path. Both fixtures live in ``tests/conftest.py`` so they're available to any future test that touches the bridge or shutdown path. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
attach.py calls sys.stdin.fileno() and sys.stdout.fileno() to drive its select() loop. pytest's default capsys swaps both with StringIO mocks that have no real fd, so attach.main() raises io.UnsupportedOperation before it can ever observe the AUTH reject. Add a stdio_devnull fixture in tests/conftest.py that opens os.devnull (rb/wb), monkeypatches sys.stdin/sys.stdout to point at those file objects, and closes them on teardown. Wire it into the two attach tests that actually call attach.main() with a connecting socket (test_auth_rejection_returns_1_with_clear_stderr and test_clean_eof_after_data_returns_0). sys.stderr is deliberately left alone so capsys.readouterr().err keeps capturing the error message we assert on — no need to switch to capfd. The other two attach tests (bad argv, missing socket) return before ever touching stdin/stdout fds, so they don't need the fixture. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add csshx-latest: Python rewrite of csshX with pluggable terminal bac…
CRITICAL fixes:
- Bounded reap with SIGKILL fallback (no more hang-on-shutdown)
- StrictHostKeyChecking=accept-new injected when user did not set it
- --max-hosts cap (default 16) to prevent fork-bomb typos
- Broadcaster logs per-slave write failures (no more silent drops)
- WaveTerm bash export parser uses shlex.split (handles all quote forms)
MUST HAVE features:
- Per-slave focus toggle: Ctrl-T <digit> for 1-9, Ctrl-T i for 10+
- iTerm2 and Apple Terminal close_block actually closes the pane now
- Launcher.start(total) lifecycle hook (drops CSSHX_HOST_COUNT env smuggle)
- ~/.config/csshx-latest/config.toml or ~/.csshrc cluster aliases
- TCP-22 preflight, --strict / --no-preflight flags
- Per-block SIGWINCH via dedicated control socket (WINSZ commands)
- Real-PTY round-trip integration test
- --reconnect with exponential backoff on slave death
- Tile after every spawn so panes stay balanced
Other:
- Alpha brace expansion: host-{a..c}
- Always use the stdlib attach client (control socket needs dual sockets)
- 150 tests passing (was 111)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.