(175) commits
Eric Bower
·
2025-12-20
fix: timing issue with first attach and sending terminal state On first attach we don't want to send the terminal state but there appears to be a timing issue where sometimes we already have pty output before the Init handler can complete.
Eric Bower
·
2025-12-19
fix: correct cursor position when reattaching to session Serialize terminal state BEFORE resizing the terminal in handleInit. Previously, the resize was done first, which caused cursor reflow and moved the cursor position. The shell's SIGWINCH-triggered prompt redraw would then run after our snapshot was sent, leaving the cursor at the wrong position (end of line instead of after the prompt). By capturing the terminal state before resize, we preserve the correct cursor position from when the user detached.
Eric Bower
·
2025-12-19
refactor: input shortcut handling Another code clarity change that abstracts handling the shortcuts for detach
Eric Bower
·
2025-12-19
refactor: daemonLoop and terminal serialization Code cleanup to make the daemonLoop and ghostty interaction easier to understand
Eric Bower
·
2025-12-19
feat: ctrl+b + d to detach With support to add more commands
Eric Bower
·
2025-12-19
fix: reset terminal modes on detach Closes: https://github.com/neurosnap/zmx/issues/26
Tristan Partin
·
2025-12-18
Use XDG_RUNTIME_DIR for the socket directory if defined XDG_RUNTIME_DIR[0] is a file path for user-specific runtime files, like sockets. It will typically be defined on Linux. I can't say for sure on BSDs, and I know for certain it is not defined on macOS. Link: https://specifications.freedesktop.org/basedir/latest/ [0] Signed-off-by: Tristan Partin <tristan@partin.io>
Eric Bower
·
2025-12-18
revert: don't force pty resize This seems to be causing issues with multiple clients connected, instead we will require clients to force resize themselves for now
Eric Bower
·
2025-12-15
fix: send SIGWINCH to PTY on re-attach TIOCSWINSZ alone doesn't notify the shell when terminal size is set. Now we explicitly signal the foreground process group after setting the window size, fixing display issues on re-attach.
Eric Bower
·
2025-12-11
fix(getTerminalSize): return default size if cols and rows are 0 The issue is that `getTerminalSize` can return 0x0 even when ioctl(TIOCGWINSZ) succeeds. The ghostty terminal library panics when initialized with zero dimensions. The fix in `getTerminalSize` now validates that both rows and cols are positive before using them, otherwise falling back to the default 24x80. Closes: https://github.com/neurosnap/zmx/issues/25
Eric Bower
·
2025-12-10
fix: flake.nix only supports linux atm `ghostty` does not support packaging nix on mac which I think means we will not be able to support it: - https://github.com/ghostty-org/ghostty/blob/cf06417b7dfbd0daeb58a9143f9b6ee194cbce26/nix/package.nix#L49 - https://github.com/ghostty-org/ghostty#2824 When our flake tries to build on macOS, it pulls ghostty as a Zig dependency, and ghostty's build.zig calls into apple-sdk/build.zig which needs the Darwin SDK — but ghostty's Nix infrastructure hasn't set that up.
a65a2b0
(version-cmd)
Jesse Farebrother
·
2025-12-05
chore: build.zig version build option
Eric Bower
·
2025-12-05
refactor!: postfix uid for socket dir
- first we look for TMPDIR env var or else we default to `/tmp`
- then we look for ZMX_DIR env var or else we create a `/tmp/zmx-{uid}` folder
Since this is a breaking change, you can kill all of your previous
sessions by using `ZMX_DIR=/tmp/zmx zmx kill {sesh}`
Closes: https://github.com/neurosnap/zmx/issues/15
BREAKING CHANGE: this moves sockets to a new location which means none
of your previous sessions will be available
Eric Bower
·
2025-12-06
fix(attach): cannot attach to session within session Closes: https://github.com/neurosnap/zmx/issues/20
Eric Bower
·
2025-12-05
fix: support kitty keyboard ctrl+\ with event flags References: https://github.com/neurosnap/zmx/issues/10
Eric Bower
·
2025-12-03
refactor: when daemon is unresponsive, remove it This commit does a better job removing a unix socket file when the daemon is unresponsive, likely indicating that the process has already been killed. We accomplish this by creating a probSession fn that will connect to the unix socket, send the Info event, and timeout after 1 second. After that point we remove the unix socket file.
Eric Bower
·
2025-12-03
fix: send SIGTERM to pty child process before shutting down The issue was that when `zmx kill` was called, the daemon would call `shutdown()` and exit the loop, but then get stuck at `waitpid(daemon.pid, 0)` waiting for the PTY child shell to exit. Since the shell was never killed, the daemon would hang forever, preventing the defer block from running that deletes the socket file. The fix sends SIGTERM to the PTY child process before shutting down, allowing the shell to exit gracefully so waitpid returns and the socket cleanup defer runs. References: https://github.com/neurosnap/zmx/issues/10
Eric Bower
·
2025-12-03
fix: print help text with unknown commands We should print the help text when possible and refrain from using the logger when the user provides invalid input since that gets sent to our log files. Closes: https://github.com/neurosnap/zmx/issues/11
Eric Bower
·
2025-12-03
fix: ghostty should not send color pallet on re-attach When `zmx` starts a session, `ghostty-vt.Terminal.init()` uses Ghostty's default palette, not foot's palette. On reattach, it dumps all 256 colors from ghostty's defaults, which may differ from foot's defaults. References: https://github.com/neurosnap/zmx/issues/7
Eric Bower
·
2025-12-03
feat: increase max scrollback Closes: https://github.com/neurosnap/zmx/issues/9
Eric Bower
·
2025-12-02
fix: dont send ghostty snapshot on first attach chore: clear main screen and set cursor to home on first attach
Eric Bower
·
2025-12-02
fix: dont use alt screen on attach The problem is that the client switches to the alternate screen buffer on attach, which doesn't have scrollback. When ghostty replays content, it goes into the alt screen where scrollback doesn't accumulate. The alternate screen buffer (\x1b[?1049h) never has scrollback - that's by design in terminals. To get scrollback working properly we now stay on main screen and clear on detach.
Eric Bower
·
2025-11-27
feat: render terminal snapshot to client on re-attach This change uses libghostty-vt to restore the previous state of the terminal when a client re-attaches to a session. How it works: - user creates session `zmx attach term` - user interacts with terminal stdin - stdin gets sent to pty via daemon - daemon sends pty output to client *and* ghostty-vt - ghostty-vt holds terminal state and scrollback - user disconnects - user re-attaches to session - ghostty-vt sends terminal snapshot to client stdout In this way, ghostty-vt doesn't sit in the middle of an active terminal session, it simply receives all the same data the client receives so it can re-hydrate clients that connect to the session.
Eric Bower
·
2025-11-26
fix: discard any unread input when restoring terminal settings on detach
Eric Bower
·
2025-11-26
fix: free socket_path and the clients array backing storage before the daemon process exits
Eric Bower
·
2025-11-26
fix: close the server socket and delete the socket file if spawnPty fails
Eric Bower
·
2025-11-26
fix: client socket fd ensure the socket is closed when the function exits
Eric Bower
·
2025-11-26
fix: ensure the fd is closed if initUnix, bind, or listen fails
Eric Bower
·
2025-11-26
fix: use relative path since we are already inside the socket_dir
Eric Bower
·
2025-11-26
fix: properly allocate NUL-terminated copies of each argument the child process will exec (replacing memory) or exit, so no cleanup needed.
Eric Bower
·
2025-11-25
fix: cpu spike from unhandled events in our daemon and client loops
Eric Bower
·
2025-11-23
daemon-per-session (#4) This is a ground-up rewrite of this tool. We have dramatically simplified how this tool works. Instead of having a single daemon that manages all sessions, we have a daemon-per-session. We employ a simple architecture: `fork() -> setsid() on child -> forkpty() -> attach on parent` This has a bunch of benefits, one of which is we can safely remove libxev and use simple `poll()` loops for daemon and clients.
Eric Bower
·
2025-10-15
fix: filter our client input queries from echoing to stdout
Eric Bower
·
2025-10-15
feat: in-band resize window events https://gist.github.com/rockorager/e695fb2924d36b2bcf1fff4a3704bd83
Eric Bower
·
2025-10-15
refactor: move render terminal snapshot to separate module
Eric Bower
·
2025-10-13
refactor: increase pty buffer sizes This improves performance when writing to ghostty-vt
Eric Bower
·
2025-10-13
refactor(daemon): we dont need to buffer pty read for partial utf8 ghostty already handles this for us.
Eric Bower
·
2025-10-13
fix(attach): when daemon shuts down don't print EOF msg in attach
Eric Bower
·
2025-10-13
fix: respond to Device Attribute queries to prevent fish shell warning Fish shell sends a Primary Device Attribute (DA1) query (ESC [ c) when it starts to detect terminal capabilities. Previously, zmx forwarded this query to the PTY but never sent a response back to the client, causing fish to wait 2 seconds and display a terminal compatibility warning. This commit intercepts DA queries in handlePtyInput() before they reach the PTY and responds directly to the client with VT220 capabilities: - Primary DA (ESC [ c): VT220 with color (22) and clipboard (52) - Secondary DA (ESC [ > c): Terminal version info The response format matches ghostty's deviceAttributes implementation. Fixes the "fish could not read response to Primary Device Attribute query" warning on first attach.
Eric Bower
·
2025-10-12
fix: vt.resize on attach fix: filter out characters ghostty cannot handle
Tim Culverhouse
·
2025-10-13
support macOS and FreeBSD PTY functions (#1) Replace Linux-specific PTY headers with platform-specific imports to enable cross-platform compatibility. On macOS, use util.h for openpty(). On FreeBSD, use libutil.h for openpty(). On Linux and other platforms, continue using pty.h. Remove unused utmp.h include that was never referenced in the code. This change allows the daemon to compile and run on macOS and FreeBSD in addition to Linux without requiring platform-specific preprocessor directives or build configurations. Amp-Thread-ID: https://ampcode.com/threads/T-15fd58fa-5673-40c5-87e1-3ea0057599ca Co-authored-by: Amp <amp@ampcode.com>