Skip to content

Instantly share code, notes, and snippets.

@i3130002
Created August 9, 2026 11:46
Show Gist options
  • Select an option

  • Save i3130002/59bfbf5e6dfcee7c32428ec6d2737f01 to your computer and use it in GitHub Desktop.

Select an option

Save i3130002/59bfbf5e6dfcee7c32428ec6d2737f01 to your computer and use it in GitHub Desktop.
# herdr-session.sh — pick or create a herdr session, then launch it. # # • Type to search existing sessions; Enter attaches to the selection. # • Type a name and press Ctrl-N to create + launch a new session. # • Esc cancels. # # Requires: herdr, fzf, jq
#!/usr/bin/env bash
#
# herdr-session.sh — pick or create a herdr session, then launch it.
#
# • Type to search existing sessions; Enter attaches to the selection.
# • Type a name and press Ctrl-N to create + launch a new session.
# • Esc cancels.
#
# Requires: herdr, fzf, jq
set -uo pipefail
# --- locate herdr ---------------------------------------------------------
HERDR="${HERDR:-}"
if [[ -z "$HERDR" || ! -x "$HERDR" ]]; then
HERDR="$(command -v herdr 2>/dev/null || true)"
fi
if [[ -z "$HERDR" || ! -x "$HERDR" ]]; then
HERDR="$HOME/.local/bin/herdr"
fi
if [[ -z "$HERDR" || ! -x "$HERDR" ]]; then
printf 'herdr not found on PATH. Install it or set HERDR=/path/to/herdr.\n' >&2
exit 1
fi
# --- dependencies ---------------------------------------------------------
need() { command -v "$1" >/dev/null 2>&1 || { printf '%s is required.\n' "$1" >&2; exit 1; }; }
need fzf
need jq
# --- colors ---------------------------------------------------------------
ESC=$'\033'
C_TITLE="${ESC}[1;36m"
C_RUN="${ESC}[1;32m"
C_STOP="${ESC}[2m"
C_DIM="${ESC}[2m"
C_KEY="${ESC}[1m"
R="${ESC}[0m"
# --- gather sessions ------------------------------------------------------
# Each session becomes a tab-delimited line: name<TAB>status<TAB>dir
# The name field stays plain so we can recover it from fzf's selection.
json="$("$HERDR" session list --json 2>/dev/null || true)"
rendered=""
count=0
while IFS=$'\t' read -r name status dir; do
[[ -z "${name:-}" ]] && continue
count=$((count + 1))
if [[ "$status" == "running" ]]; then
s="${C_RUN}● running${R}"
else
s="${C_STOP}○ stopped${R}"
fi
pname="$(printf '%-18s' "$name")"
rendered+="$(printf '%s\t%s\t%s' "$pname" "$s" "${C_DIM}${dir}${R}")"$'\n'
done < <(jq -r '
(.sessions // [])
| sort_by((.running | not), .name)
| .[]
| [ .name,
(if .running then "running" else "stopped" end),
(.session_dir // "") ]
| @tsv
' <<<"$json" 2>/dev/null)
# --- header ---------------------------------------------------------------
header="${C_TITLE}herdr sessions${R} ${C_DIM}(${count} existing)${R}"$'\n'
header+="${C_KEY}Enter${R} attach ${C_KEY}Ctrl-N${R} create from typed name ${C_KEY}Esc${R} cancel"
# --- pick -----------------------------------------------------------------
# --print-query : first output line is whatever the user typed
# --expect=ctrl-n: second line is "ctrl-n" if Ctrl-N was pressed, else empty
# selection line : the original chosen line (3rd output line), or empty
out="$(printf '%s' "$rendered" | fzf \
--ansi \
--delimiter=$'\t' \
--with-nth=1,2,3 \
--print-query \
--expect=ctrl-n \
--header="$header" \
--prompt='session ❯ ' \
--info=inline)" || true
[[ -z "$out" ]] && exit 0 # cancelled (Esc / Ctrl-C)
query="$(printf '%s\n' "$out" | sed -n '1p')"
key="$(printf '%s\n' "$out" | sed -n '2p')"
sel="$(printf '%s\n' "$out" | sed -n '3p')"
if [[ "$key" == "ctrl-n" ]]; then
name="$query" # create new from typed name
else
name="${sel%%$'\t'*}" # first field of the chosen line
fi
# trim leading/trailing whitespace
name="${name#"${name%%[![:space:]]*}"}"
name="${name%"${name##*[![:space:]]}"}"
if [[ -z "$name" ]]; then
printf 'No session name given.\n' >&2
exit 1
fi
# --- launch ---------------------------------------------------------------
exec "$HERDR" --session "$name"
@i3130002

i3130002 commented Aug 9, 2026

Copy link
Copy Markdown
Author

TUI Screenshot

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment