diff --git a/.agents/skills/lib.sh b/.agents/skills/lib.sh index 42a5b75..af39f2c 100644 --- a/.agents/skills/lib.sh +++ b/.agents/skills/lib.sh @@ -28,7 +28,7 @@ AGENT_SESSIONS_YAML="${AGENT_SESSIONS_YAML:-$WORKSPACE_ROOT/.mam/agent-sessions. # Add common Homebrew and local binary paths to PATH to ensure they are available in non-interactive shells for dir in /home/linuxbrew/.linuxbrew/bin /home/linuxbrew/.linuxbrew/sbin "$HOME/.local/bin" "$HOME/.npm-global/bin"; do if [ -d "$dir" ] && [[ ":$PATH:" != *":$dir:"* ]]; then - export PATH="$dir:$PATH" + export PATH="$PATH:$dir" fi done @@ -58,7 +58,16 @@ _resolve_real_herdr_path() { _init_herdr_isolation() { local wrapper_dir="$WORKSPACE_ROOT/.mam/shim" mkdir -p "$wrapper_dir" - cat <<'EOF' > "$wrapper_dir/herdr" + if [ -x "$wrapper_dir/herdr" ]; then + if [[ ":$PATH:" != *":$wrapper_dir:"* ]]; then + export PATH="$wrapper_dir:$PATH" + fi + return 0 + fi + + local tmp_file + tmp_file=$(mktemp "$wrapper_dir/herdr.XXXXXX") + cat <<'EOF' > "$tmp_file" #!/usr/bin/env bash # Herdr-to-Herdr translation shim wrapper set -euo pipefail @@ -81,6 +90,16 @@ _resolve_real_herdr() { } REAL_HERDR=$(_resolve_real_herdr) +# Support parsing -L before the subcommand +while [ "${1:-}" = "-L" ]; do + if [ $# -lt 2 ]; then + echo "herdr shim: -L requires an argument" >&2 + exit 1 + fi + export HERDR_SERVER_NAME="$2" + shift 2 +done + wrapper_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) cmd="${1:-}" if [ -z "$cmd" ]; then @@ -89,12 +108,20 @@ if [ -z "$cmd" ]; then fi shift + case "$cmd" in has-session) sess="" while [ $# -gt 0 ]; do case "$1" in - -t) sess="$2"; shift 2 ;; + -t) + if [ $# -lt 2 ]; then + echo "Error: -t requires a value" >&2 + exit 1 + fi + sess="$2" + shift 2 + ;; *) shift ;; esac done @@ -104,12 +131,29 @@ case "$cmd" in name="" ws="" run_cmd="" while [ $# -gt 0 ]; do case "$1" in - -s) name="$2"; shift 2 ;; - -c) ws="$2"; shift 2 ;; + -s) + if [ $# -lt 2 ]; then + echo "Error: -s requires a value" >&2 + exit 1 + fi + name="$2" + shift 2 + ;; + -c) + if [ $# -lt 2 ]; then + echo "Error: -c requires a value" >&2 + exit 1 + fi + ws="$2" + shift 2 + ;; -d|-x|-y) shift ;; *) run_cmd="$1"; shift ;; esac done + if [ -z "$run_cmd" ]; then + run_cmd="${SHELL:-/bin/bash}" + fi "$REAL_HERDR" workspace create --label "${HERDR_SERVER_NAME:-default}" --cwd "${ws:-.}" >/dev/null 2>&1 || true parsed=$(python3 -c " @@ -136,13 +180,14 @@ print('\t'.join(env_flags) + '\n' + ' '.join(binary_tokens)) ws_label="${HERDR_SERVER_NAME:-default}" ws_id="w1" if [ "$ws_label" != "default" ]; then - ws_id=$("$REAL_HERDR" workspace list 2>/dev/null | python3 -c " -import sys, json + ws_id=$("$REAL_HERDR" workspace list 2>/dev/null | WS_LABEL="$ws_label" python3 -c " +import sys, os, json try: + ws_label = os.environ.get('WS_LABEL', '') data = json.loads(sys.stdin.read()) res = data.get('result', data) for ws in res.get('workspaces', []): - if ws.get('label') == '$ws_label' or ws.get('workspace_id') == '$ws_label': + if ws.get('label') == ws_label or ws.get('workspace_id') == ws_label: print(ws.get('workspace_id')) sys.exit(0) except Exception: @@ -157,7 +202,14 @@ except Exception: sess="" while [ $# -gt 0 ]; do case "$1" in - -t) sess="$2"; shift 2 ;; + -t) + if [ $# -lt 2 ]; then + echo "Error: -t requires a value" >&2 + exit 1 + fi + sess="$2" + shift 2 + ;; *) shift ;; esac done @@ -168,8 +220,22 @@ except Exception: sess="" format="" while [ $# -gt 0 ]; do case "$1" in - -t) sess="$2"; shift 2 ;; - -F) format="$2"; shift 2 ;; + -t) + if [ $# -lt 2 ]; then + echo "Error: -t requires a value" >&2 + exit 1 + fi + sess="$2" + shift 2 + ;; + -F) + if [ $# -lt 2 ]; then + echo "Error: -F requires a value" >&2 + exit 1 + fi + format="$2" + shift 2 + ;; *) shift ;; esac done @@ -198,7 +264,14 @@ except Exception: sess="" while [ $# -gt 0 ]; do case "$1" in - -t) sess="$2"; shift 2 ;; + -t) + if [ $# -lt 2 ]; then + echo "Error: -t requires a value" >&2 + exit 1 + fi + sess="$2" + shift 2 + ;; *) shift ;; esac done @@ -208,7 +281,14 @@ except Exception: sess="" key="" while [ $# -gt 0 ]; do case "$1" in - -t) sess="$2"; shift 2 ;; + -t) + if [ $# -lt 2 ]; then + echo "Error: -t requires a value" >&2 + exit 1 + fi + sess="$2" + shift 2 + ;; *) key="$1"; shift ;; esac done @@ -221,7 +301,14 @@ except Exception: text="" while [ $# -gt 0 ]; do case "$1" in - -b) buf="$2"; shift 2 ;; + -b) + if [ $# -lt 2 ]; then + echo "Error: -b requires a value" >&2 + exit 1 + fi + buf="$2" + shift 2 + ;; *) text="$1"; shift ;; esac done @@ -231,7 +318,14 @@ except Exception: sess="" while [ $# -gt 0 ]; do case "$1" in - -t) sess="$2"; shift 2 ;; + -t) + if [ $# -lt 2 ]; then + echo "Error: -t requires a value" >&2 + exit 1 + fi + sess="$2" + shift 2 + ;; *) shift ;; esac done @@ -249,7 +343,11 @@ try: data = json.load(sys.stdin) res = data.get('result', data) for a in res.get('agents', []): - print(f\"{a['name']}|0\") + try: + name = a.get('name') or a.get('agent') or 'unknown' + print(f\"{name}|0\") + except Exception: + pass except Exception: pass " || true @@ -259,7 +357,8 @@ except Exception: ;; esac EOF - chmod +x "$wrapper_dir/herdr" + chmod +x "$tmp_file" + mv -f "$tmp_file" "$wrapper_dir/herdr" if [[ ":$PATH:" != *":$wrapper_dir:"* ]]; then export PATH="$wrapper_dir:$PATH" fi @@ -334,7 +433,7 @@ name = os.environ['SESSION_NAME'] d = json.loads(os.environ.get('MAM_STATE_JSON', '{}')) for s in d.get('herdr_sessions', []): if s.get('name') == name: - print(s.get('herdr_workspace', 'default')) + print(s.get('herdr_workspace') or s.get('herdr_server') or 'default') sys.exit(0) print(os.environ.get('HERDR_SERVER_NAME', 'default')) ") @@ -342,13 +441,14 @@ print(os.environ.get('HERDR_SERVER_NAME', 'default')) echo "w1" else local ws_id - ws_id=$(herdr workspace list 2>/dev/null | python3 -c " -import sys, json + ws_id=$(herdr workspace list 2>/dev/null | RAW_LABEL="$raw_label" python3 -c " +import sys, os, json try: + raw_label = os.environ.get('RAW_LABEL', '') data = json.loads(sys.stdin.read()) res = data.get('result', data) for ws in res.get('workspaces', []): - if ws.get('label') == '$raw_label' or ws.get('workspace_id') == '$raw_label': + if ws.get('label') == raw_label or ws.get('workspace_id') == raw_label: print(ws.get('workspace_id')) sys.exit(0) except Exception: diff --git a/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job b/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job index bb78cfe..253d5cc 100755 --- a/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job +++ b/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job @@ -11,7 +11,7 @@ # # This is a reference wrapper: it shells out to the python scripts that live # next to it. Copy it into your project and customise as needed. It never hard -# fails if `claude`/`codex`/`tmux` are missing — it prints what it would run. +# fails if `claude`/`codex`/`herdr` are missing — it prints what it would run. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -28,6 +28,8 @@ pick_python() { local py_bin if [[ -n "${DELEGATE_JOB_PYTHON:-}" ]]; then py_bin="$DELEGATE_JOB_PYTHON" + elif [[ -n "${AGENT_PYTHON_BIN:-}" ]] && [[ -x "$AGENT_PYTHON_BIN" ]]; then + py_bin="$AGENT_PYTHON_BIN" elif [[ -x "${WORKDIR:-.}/.venv/bin/python" ]]; then py_bin="${WORKDIR}/.venv/bin/python" elif [[ -x ".venv/bin/python" ]]; then @@ -56,7 +58,7 @@ multi-agent-mux-delegate-job [options] [--type ] [--reviewer ] [--reviewer-session ] [--max-iterations ] [--counterpart-role ] [--strict-role-check] - # The skill is tmux-interactive only; --mode print was removed. + # The skill is herdr-interactive only; --mode print was removed. status --job [--registry-dir ] list [--registry-dir ] verify --job --validate