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>
This commit is contained in:
David Heinemeier Hansson
2026-08-09 13:57:36 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent 19572a13c7
commit dd61d4a75b
8 changed files with 321 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
#!/bin/bash
set -euo pipefail
source "$(dirname "$0")/base-test.sh"
source "$ROOT/default/bash/fns/herdr"
test_dir=$(mktemp -d)
trap 'rm -rf -- "$test_dir"' EXIT
mkdir -p "$test_dir/first project's files" "$test_dir/second project"
log="$test_dir/herdr.log"
herdr() {
if [[ $1 == "workspace" ]]; then
return
elif [[ $1 == "tab" ]]; then
printf '{"result":{"root_pane":{"pane_id":"new-pane"}}}\n'
elif [[ $1 == "pane" && $2 == "run" ]]; then
printf '%s\n' "$4" >>"$log"
fi
}
export HERDR_PANE_ID="current-pane"
export HERDR_WORKSPACE_ID="workspace"
cd "$test_dir"
hdlm "codex --flag='value with spaces'" "claude --model sonnet"
mapfile -t commands <"$log"
expected_first=$(printf 'cd %q && hdl %q %q' \
"$test_dir/first project's files" "codex --flag='value with spaces'" "claude --model sonnet")
expected_second=$(printf 'hdl %q %q' "codex --flag='value with spaces'" "claude --model sonnet")
[[ ${commands[0]} == "$expected_first" ]] || fail "hdlm safely quotes its first queued command"
pass "hdlm safely quotes its first queued command"
[[ ${commands[1]} == "$expected_second" ]] || fail "hdlm preserves agent argument boundaries"
pass "hdlm preserves agent argument boundaries"
: >"$log"
hdlm "codex --quiet"
mapfile -t commands <"$log"
expected_first=$(printf 'cd %q && hdl %q' "$test_dir/first project's files" "codex --quiet")
[[ ${commands[0]} == "$expected_first" ]] || fail "hdlm omits an absent second agent argument"
pass "hdlm omits an absent second agent argument"