Last active
July 9, 2026 08:21
-
-
Save hotchpotch/8fbca5605af16c386acb34bc74f8c1ae to your computer and use it in GitHub Desktop.
herdr_cdd zsh helper
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
| # vim: ft=zsh | |
| # License: MIT. | |
| # Author: Yuichi Tateno (@hotchpotch). | |
| # Dependencies: herdr, jq, and fzf for interactive selection. | |
| # Gist URL: https://gist.github.com/hotchpotch/8fbca5605af16c386acb34bc74f8c1ae | |
| # When changing this file, update the gist at the URL above as well. | |
| _herdr_cdd_usage() { | |
| cat >&2 <<'EOF' | |
| Usage: | |
| herdr_cdd pick a Herdr cwd with fzf | |
| herdr_cdd 3 cd to current workspace tab 3 | |
| herdr_cdd t3 cd to current workspace tab 3 | |
| herdr_cdd p3 cd to current workspace pane 3 | |
| herdr_cdd w3 cd to workspace w3 active tab | |
| herdr_cdd w3:t1 cd to tab w3:t1 | |
| herdr_cdd w3:p1 cd to pane w3:p1 | |
| herdr_cdd a1 cd to agent 1 from `herdr agent list` | |
| herdr_cdd <agent> cd to an agent name/label target | |
| EOF | |
| } | |
| _herdr_cdd_compact_path() { | |
| local path="$1" | |
| case "$path" in | |
| "$HOME") print -r -- "~" ;; | |
| "$HOME"/*) print -r -- "~/${path#$HOME/}" ;; | |
| *) print -r -- "$path" ;; | |
| esac | |
| } | |
| _herdr_cdd_usable_path() { | |
| local path="${1:-}" | |
| [[ -n "$path" && -d "$path" ]] | |
| } | |
| _herdr_cdd_is_connection_error() { | |
| local message="$1" | |
| [[ "$message" == *"No such file or directory"* \ | |
| || "$message" == *"Connection refused"* \ | |
| || "$message" == *"connection refused"* \ | |
| || "$message" == *"Broken pipe"* ]] | |
| } | |
| _herdr_cdd_print_connection_error() { | |
| print -u2 "Herdr API is not reachable. Start or attach to Herdr, then try again." | |
| print -u2 "Run 'herdr status server' to inspect the server and socket." | |
| } | |
| _herdr_cdd_herdr() { | |
| local output rc | |
| output="$(herdr "$@" 2>&1)" | |
| rc=$? | |
| if (( rc == 0 )); then | |
| print -r -- "$output" | |
| return 0 | |
| fi | |
| if _herdr_cdd_is_connection_error "$output"; then | |
| _herdr_cdd_print_connection_error | |
| return 70 | |
| fi | |
| return 1 | |
| } | |
| _herdr_cdd_pane_cwd() { | |
| local target="$1" response cwd | |
| response="$(_herdr_cdd_herdr pane get "$target")" || return $? | |
| cwd="$(jq -er '.result.pane | .foreground_cwd // .cwd // empty' <<<"$response" 2>/dev/null)" || return 1 | |
| _herdr_cdd_usable_path "$cwd" || return 1 | |
| print -r -- "$cwd" | |
| } | |
| _herdr_cdd_tab_cwd() { | |
| local target="$1" workspace response cwd | |
| workspace="${target%%:t*}" | |
| [[ -n "$workspace" && "$workspace" != "$target" ]] || return 1 | |
| response="$(_herdr_cdd_herdr pane list --workspace "$workspace")" || return $? | |
| cwd="$( | |
| jq -er --arg tab "$target" ' | |
| .result.panes | |
| | map(select(.tab_id == $tab)) | |
| | (map(select(.focused)) + .) | |
| | .[0] | |
| | .foreground_cwd // .cwd // empty | |
| ' <<<"$response" 2>/dev/null | |
| )" || return 1 | |
| _herdr_cdd_usable_path "$cwd" || return 1 | |
| print -r -- "$cwd" | |
| } | |
| _herdr_cdd_workspace_cwd() { | |
| local target="$1" response active_tab cwd | |
| response="$(_herdr_cdd_herdr workspace get "$target")" || return $? | |
| active_tab="$(jq -er '.result.workspace.active_tab_id // empty' <<<"$response" 2>/dev/null)" || active_tab="" | |
| if [[ -n "$active_tab" ]]; then | |
| _herdr_cdd_tab_cwd "$active_tab" && return 0 | |
| fi | |
| response="$(_herdr_cdd_herdr pane list --workspace "$target")" || return $? | |
| cwd="$(jq -er '.result.panes | (map(select(.focused)) + .) | .[0] | .foreground_cwd // .cwd // empty' <<<"$response" 2>/dev/null)" || return 1 | |
| _herdr_cdd_usable_path "$cwd" || return 1 | |
| print -r -- "$cwd" | |
| } | |
| _herdr_cdd_current_workspace_id() { | |
| local response workspace | |
| if [[ -n "${HERDR_WORKSPACE_ID:-}" ]]; then | |
| print -r -- "$HERDR_WORKSPACE_ID" | |
| return 0 | |
| fi | |
| response="$(_herdr_cdd_herdr pane current)" || return $? | |
| workspace="$(jq -er '.result.pane.workspace_id // empty' <<<"$response" 2>/dev/null)" || return 1 | |
| [[ -n "$workspace" ]] || return 1 | |
| print -r -- "$workspace" | |
| } | |
| _herdr_cdd_current_workspace_tab_cwd() { | |
| local tab_number="$1" workspace | |
| [[ "$tab_number" =~ '^[0-9]+$' && "$tab_number" -gt 0 ]] || return 1 | |
| workspace="$(_herdr_cdd_current_workspace_id)" || return 1 | |
| _herdr_cdd_tab_cwd "${workspace}:t${tab_number}" | |
| } | |
| _herdr_cdd_current_workspace_pane_cwd() { | |
| local pane_number="$1" workspace | |
| pane_number="${pane_number#p}" | |
| [[ "$pane_number" =~ '^[0-9]+$' && "$pane_number" -gt 0 ]] || return 1 | |
| workspace="$(_herdr_cdd_current_workspace_id)" || return 1 | |
| _herdr_cdd_pane_cwd "${workspace}:p${pane_number}" | |
| } | |
| _herdr_cdd_agent_index_cwd() { | |
| local target="$1" index response cwd | |
| index="${target#a}" | |
| [[ "$index" =~ '^[0-9]+$' && "$index" -gt 0 ]] || return 1 | |
| response="$(_herdr_cdd_herdr agent list)" || return $? | |
| cwd="$(jq -er --argjson index "$((index - 1))" '.result.agents[$index] | .foreground_cwd // .cwd // empty' <<<"$response" 2>/dev/null)" || return 1 | |
| _herdr_cdd_usable_path "$cwd" || return 1 | |
| print -r -- "$cwd" | |
| } | |
| _herdr_cdd_agent_target_cwd() { | |
| local target="$1" response cwd | |
| response="$(_herdr_cdd_herdr agent get "$target")" || return $? | |
| cwd="$(jq -er '.result.agent | .foreground_cwd // .cwd // empty' <<<"$response" 2>/dev/null)" || return 1 | |
| _herdr_cdd_usable_path "$cwd" || return 1 | |
| print -r -- "$cwd" | |
| } | |
| _herdr_cdd_resolve_target() { | |
| local target="$1" rc | |
| if [[ "$target" =~ '^a[0-9]+$' ]]; then | |
| _herdr_cdd_agent_index_cwd "$target" | |
| rc=$? | |
| (( rc == 0 || rc == 70 )) && return $rc | |
| fi | |
| if [[ "$target" == *":p"* ]]; then | |
| _herdr_cdd_pane_cwd "$target" | |
| rc=$? | |
| (( rc == 0 || rc == 70 )) && return $rc | |
| fi | |
| if [[ "$target" =~ '^p[0-9]+$' ]]; then | |
| _herdr_cdd_current_workspace_pane_cwd "$target" | |
| rc=$? | |
| (( rc == 0 || rc == 70 )) && return $rc | |
| fi | |
| if [[ "$target" == *":t"* ]]; then | |
| _herdr_cdd_tab_cwd "$target" | |
| rc=$? | |
| (( rc == 0 || rc == 70 )) && return $rc | |
| fi | |
| if [[ "$target" =~ '^t[0-9]+$' ]]; then | |
| _herdr_cdd_current_workspace_tab_cwd "${target#t}" | |
| rc=$? | |
| (( rc == 0 || rc == 70 )) && return $rc | |
| fi | |
| if [[ "$target" =~ '^[0-9]+$' ]]; then | |
| _herdr_cdd_current_workspace_tab_cwd "$target" | |
| rc=$? | |
| (( rc == 0 || rc == 70 )) && return $rc | |
| fi | |
| if [[ "$target" =~ '^w[[:alnum:]]+$' ]]; then | |
| _herdr_cdd_workspace_cwd "$target" | |
| rc=$? | |
| (( rc == 0 || rc == 70 )) && return $rc | |
| fi | |
| _herdr_cdd_agent_target_cwd "$target" | |
| } | |
| _herdr_cdd_select_cwd() { | |
| command -v fzf >/dev/null 2>&1 || { | |
| print -u2 "fzf is required for interactive Herdr cwd selection." | |
| return 1 | |
| } | |
| local response lines selection cwd | |
| response="$(_herdr_cdd_herdr pane list)" || { | |
| (( $? == 70 )) && return 1 | |
| print -u2 "Unable to read Herdr panes." | |
| return 1 | |
| } | |
| lines="$( | |
| jq -r ' | |
| .result.panes[] | |
| | (.foreground_cwd // .cwd // empty) as $cwd | |
| | select($cwd != "") | |
| | [ | |
| $cwd, | |
| .pane_id, | |
| .tab_id, | |
| (.agent // .display_agent // .label // .title // "pane") | |
| ] | |
| | @tsv | |
| ' <<<"$response" \ | |
| | awk -F '\t' -v home="$HOME" ' | |
| function compact(path) { | |
| if (path == home) { | |
| return "~" | |
| } | |
| if (index(path, home "/") == 1) { | |
| return "~/" substr(path, length(home) + 2) | |
| } | |
| return path | |
| } | |
| !seen[$1]++ { | |
| printf "%s\t%s\t%s\t%s\t%s\n", compact($1), $2, $3, $4, $1 | |
| } | |
| ' | |
| )" | |
| [[ -n "$lines" ]] || { | |
| print -u2 "No matching Herdr cwd candidates." | |
| return 1 | |
| } | |
| selection="$( | |
| print -r -- "$lines" \ | |
| | fzf --delimiter=$'\t' --with-nth=1,2,3,4 --prompt='herdr cwd> ' | |
| )" || { | |
| print -u2 "No Herdr cwd selected." | |
| return 1 | |
| } | |
| cwd="$(awk -F '\t' '{print $5}' <<<"$selection")" | |
| _herdr_cdd_usable_path "$cwd" || { | |
| print -u2 "Selected Herdr cwd is not a directory." | |
| return 1 | |
| } | |
| print -r -- "$cwd" | |
| } | |
| herdr_cdd() { | |
| local dir target | |
| if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then | |
| _herdr_cdd_usage | |
| return 0 | |
| fi | |
| if (( $# > 1 )); then | |
| _herdr_cdd_usage | |
| return 2 | |
| fi | |
| if (( $# == 0 )); then | |
| dir="$(_herdr_cdd_select_cwd)" || return $? | |
| else | |
| target="$1" | |
| dir="$(_herdr_cdd_resolve_target "$target")" || { | |
| (( $? == 70 )) && return 1 | |
| print -u2 "No matching Herdr cwd for target: $target" | |
| return 1 | |
| } | |
| fi | |
| print -r -- "cd $(_herdr_cdd_compact_path "$dir")" | |
| cd -- "$dir" | |
| } | |
| _herdr_cdd_add_completion_candidate() { | |
| local value="$1" description="$2" | |
| [[ -n "$value" ]] || return | |
| [[ -n "${_herdr_cdd_seen[$value]-}" ]] && return | |
| _herdr_cdd_seen[$value]=1 | |
| _herdr_cdd_values+=("$value") | |
| _herdr_cdd_descriptions+=("$description") | |
| } | |
| _herdr_cdd_targets() { | |
| command -v herdr >/dev/null 2>&1 || return 1 | |
| command -v jq >/dev/null 2>&1 || return 1 | |
| local response agents kind value cwd label compact desc index current_workspace pane_number tab_id tab_number | |
| local -a _herdr_cdd_values _herdr_cdd_descriptions | |
| local -A _herdr_cdd_seen _herdr_cdd_workspace_seen _herdr_cdd_tab_seen | |
| current_workspace="$(_herdr_cdd_current_workspace_id 2>/dev/null)" || current_workspace="" | |
| response="$(_herdr_cdd_herdr pane list 2>/dev/null)" || response="" | |
| if [[ -n "$response" ]]; then | |
| while IFS=$'\t' read -r kind value cwd tab_id label; do | |
| [[ -n "$value" && -n "$cwd" ]] || continue | |
| compact="$(_herdr_cdd_compact_path "$cwd")" | |
| if [[ "$kind" == "pane" ]]; then | |
| desc="pane ${value} ${compact}" | |
| [[ -n "$tab_id" ]] && desc="${desc} in ${tab_id}" | |
| [[ -n "$label" ]] && desc="${desc} ${label}" | |
| _herdr_cdd_add_completion_candidate "$value" "$desc" | |
| if [[ -n "$current_workspace" && "$value" == "${current_workspace}:p"* ]]; then | |
| pane_number="${value#${current_workspace}:p}" | |
| _herdr_cdd_add_completion_candidate "p${pane_number}" "current workspace pane ${value} ${compact}" | |
| fi | |
| if [[ -n "$tab_id" && -z "${_herdr_cdd_tab_seen[$tab_id]-}" ]]; then | |
| _herdr_cdd_tab_seen[$tab_id]=1 | |
| _herdr_cdd_add_completion_candidate "$tab_id" "tab ${tab_id} ${compact}" | |
| if [[ -n "$current_workspace" && "$tab_id" == "${current_workspace}:t"* ]]; then | |
| tab_number="${tab_id#${current_workspace}:t}" | |
| _herdr_cdd_add_completion_candidate "t${tab_number}" "current workspace tab ${tab_id} ${compact}" | |
| _herdr_cdd_add_completion_candidate "$tab_number" "current workspace tab ${tab_id} ${compact}" | |
| fi | |
| fi | |
| local workspace="${value%%:p*}" | |
| if [[ -n "$workspace" && -z "${_herdr_cdd_workspace_seen[$workspace]-}" ]]; then | |
| _herdr_cdd_workspace_seen[$workspace]=1 | |
| _herdr_cdd_add_completion_candidate "$workspace" "workspace ${compact}" | |
| fi | |
| fi | |
| done < <( | |
| jq -r ' | |
| .result.panes[] | |
| | (.foreground_cwd // .cwd // empty) as $cwd | |
| | select($cwd != "") | |
| | [ | |
| "pane", | |
| .pane_id, | |
| $cwd, | |
| (.tab_id // ""), | |
| (.agent // .display_agent // .label // .title // "") | |
| ] | |
| | @tsv | |
| ' <<<"$response" 2>/dev/null | |
| ) | |
| fi | |
| agents="$(_herdr_cdd_herdr agent list 2>/dev/null)" || agents="" | |
| if [[ -n "$agents" ]]; then | |
| while IFS=$'\t' read -r index cwd label value; do | |
| [[ -n "$index" && -n "$cwd" ]] || continue | |
| compact="$(_herdr_cdd_compact_path "$cwd")" | |
| desc="agent ${compact}" | |
| [[ -n "$label" ]] && desc="${desc} ${label}" | |
| _herdr_cdd_add_completion_candidate "a${index}" "$desc" | |
| if [[ -n "$value" ]]; then | |
| _herdr_cdd_add_completion_candidate "$value" "agent name ${compact}" | |
| fi | |
| done < <( | |
| jq -r ' | |
| .result.agents | |
| | to_entries[] | |
| | (.key + 1) as $index | |
| | .value as $agent | |
| | ($agent.foreground_cwd // $agent.cwd // empty) as $cwd | |
| | select($cwd != "") | |
| | [ | |
| ($index | tostring), | |
| $cwd, | |
| ($agent.name // $agent.agent // $agent.display_agent // $agent.title // ""), | |
| ($agent.name // "") | |
| ] | |
| | @tsv | |
| ' <<<"$agents" 2>/dev/null | |
| ) | |
| fi | |
| if (( ${#_herdr_cdd_values[@]} == 0 )); then | |
| return 1 | |
| fi | |
| compadd -d _herdr_cdd_descriptions -a _herdr_cdd_values | |
| } | |
| _herdr_cdd() { | |
| _arguments \ | |
| '(-h --help)'{-h,--help}'[show help]' \ | |
| '1:Herdr target:_herdr_cdd_targets' \ | |
| '*:: :->none' | |
| } | |
| compdef _herdr_cdd herdr_cdd | |
| _herdr_cdd_in_herdr_shell() { | |
| [[ -n "${HERDR_ENV:-}" \ | |
| || -n "${HERDR_PANE_ID:-}" \ | |
| || -n "${HERDR_TAB_ID:-}" \ | |
| || -n "${HERDR_WORKSPACE_ID:-}" \ | |
| || -n "${HERDR_SOCKET_PATH:-}" ]] | |
| } | |
| if _herdr_cdd_in_herdr_shell; then | |
| unalias ccd >/dev/null 2>&1 || true | |
| function ccd { | |
| herdr_cdd "$@" | |
| } | |
| compdef _herdr_cdd ccd | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment