Commit Graph
29 Commits
Author SHA1 Message Date
6ddc39520d Clean up the terminal and reconnect when SSH connections drop (#6661)
* Clean up the terminal and reconnect when SSH connections drop

A remote tmux, herdr, or editor arms terminal modes over the SSH pipe
(mouse tracking, focus reporting, the alternate screen) that only it can
disarm. When the connection dies instead of exiting cleanly, those modes
stay armed on the local terminal, and every mouse move floods the prompt
with escape-sequence junk.

Wrap ssh in a shell function that disarms those modes after every exit,
and automatically reconnects when an established interactive session
drops. Remote commands, configured RemoteCommands, and redirected stdin
never reconnect, so their side effects cannot replay, and the retry loop
runs in a subshell so Ctrl-C cancels both the in-flight attempt and the
loop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Detect dead SSH connections within a minute

Without keepalives, ssh does not notice a dead peer until TCP gives up,
which can take hours of sitting on a hung terminal with remote-armed
terminal modes stuck on. Ship a client keepalive default so drops are
detected in about 45 seconds, letting the shell's ssh wrapper clean up
and reconnect. ~/.ssh/config is read first and wins, so per-host
overrides still apply.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Fail closed when ssh -G cannot resolve the effective config

An unresolvable configuration could hide a RemoteCommand, so treat it
as non-interactive rather than reconnectable. Also strengthen the
tests from Copilot review: assert the complete disarm sequence, and
verify on a real interactive pty that Ctrl-C during a retry attempt
kills the reconnect loop itself, not just the in-flight attempt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Tolerate the explicit RemoteCommand none when probing ssh -G

The literal "none" is how ssh_config cancels a configured
RemoteCommand, and some OpenSSH versions emit it even when unset, which
would have silently disabled reconnecting entirely. Treat it as no
remote command while still failing closed on real ones and unresolvable
configs, and make the fake ssh -G emit the "none" form so the behavior
tests cover it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-09 19:15:21 +02:00
dd61d4a75b Ship herdr alongside tmux (#6406)
* Ship herdr with a config that mirrors our tmux setup

Installs herdr through the mise shim, ships the matching config as an
Omarchy default, and adds the usual refresh/restart pair. The keybindings
map tmux sessions to workspaces, windows to tabs, and keep both the prefix
and direct bindings from config/tmux/tmux.conf.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Add herdr versions of the tmux dev layout functions

hdl, hds, hdlm, and hsl drive herdr through its socket API instead of
tmux. hsl tiles into a real grid since herdr has no select-layout tiled.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Namespace the herdr layout helpers so they stay out of the shell

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Create hdlm's tabs in its own workspace instead of the focused one

herdr tab create follows the focused workspace without --workspace, so
switching workspaces while hdlm loops scatters the new tabs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Lay hsl's grid out in visual order

Splitting the first column repeatedly inserted each new column between it
and the previous one, so uneven counts put the spare row in a middle
column instead of the last.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Report herdr config reload failures instead of swallowing them

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Hide herdr's pane scrollbars to match tmux

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Escape queued herdr layout commands

* Install herdr from the omarchy-herdr package instead of mise

* Use native herdr resize keybindings for tmux-style pane resizing

* Rename the omarchy-herdr package to herdr

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 13:57:36 +02:00
David Heinemeier HanssonandClaude Fable 5 ddab62ea0d Only brace the expansions zsh misparses
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 17:48:17 -07:00
Paul WagnerandDavid Heinemeier Hansson 26bca7d834 Fix fip function on zsh 2026-07-19 17:48:17 -07:00
David Heinemeier Hansson aac579a2df Add rsyncing to remote host intended for easy forwarding of screenshots to remote AI runners 2026-07-15 10:54:30 -07:00
David Heinemeier Hansson 0dfbd74663 Drop old compatibility functions 2026-05-19 21:45:52 +02:00
David Heinemeier Hansson 43ec46f699 Add tds 4-way 2026-05-11 18:21:45 +02:00
David Heinemeier Hansson b8fc1bb6d9 Add omarchy menu transcoding 2026-05-05 13:55:21 +02:00
David Heinemeier Hansson 10165f2799 Add video to gif transcoding 2026-05-03 19:16:16 +02:00
8c6fcbf2f0 Rename local path variable in ga() to avoid clobbering zsh PATH (#5115)
Co-authored-by: John Allen <git@porcnick.com>
2026-03-26 07:47:49 +01:00
David Heinemeier Hansson a91fde6a3b Add 6K too 2026-03-25 14:25:01 +01:00
David Heinemeier Hansson 5726f22471 85 is probably the sweetspot 2026-03-25 14:22:31 +01:00
David Heinemeier Hansson e288092084 Adjust sizes and quality 2026-03-25 14:20:25 +01:00
David Heinemeier Hansson 462575c880 Fix worktree removal 2026-03-08 13:25:46 +01:00
David Heinemeier Hansson 3306c428dd Spelling 2026-03-08 13:25:46 +01:00
David Heinemeier Hansson e58ac44a0d Don't leak local var into global space 2026-03-08 13:25:46 +01:00
David Heinemeier Hansson 1c8d7a7487 Add worktrees functions 2026-03-01 17:39:12 +01:00
David Heinemeier Hansson c3f7575474 Allow for a second AI 2026-02-26 14:48:42 +01:00
David Heinemeier Hansson b1960fe870 Fix for many panes 2026-02-26 13:15:36 +01:00
David Heinemeier Hansson 74c9703ea3 Add usage docs 2026-02-26 13:12:17 +01:00
David Heinemeier Hansson 3408445880 Use consistent style 2026-02-26 12:13:05 +01:00
David Heinemeier Hansson ab615092ab Fix comment 2026-02-26 12:10:53 +01:00
David Heinemeier Hansson 57f07cc9c8 Follow style guide 2026-02-26 12:08:20 +01:00
David Heinemeier Hansson cc3d8e4abe Fix quoting for file inputs in transcoding functions 2026-02-26 12:00:08 +01:00
David Heinemeier Hansson 95e5a5a754 Better naming 2026-02-25 21:40:39 +01:00
David Heinemeier Hansson a7f83a576a Usage 2026-02-25 21:37:44 +01:00
David Heinemeier Hansson 0bb3973a8c Reduce this to generic functions 2026-02-25 21:32:51 +01:00
David Heinemeier Hansson 1785fb6185 Add tpl for creating multi-pane layouts for the same command
All the agents, all at once!
2026-02-25 21:21:45 +01:00
David Heinemeier Hansson fe21bb1fad Split out functions and add multi mode for tml 2026-02-23 06:59:21 -05:00