diff --git a/.agents/scripts/dispatch-dedup-helper.sh b/.agents/scripts/dispatch-dedup-helper.sh index a82bcaa27..210f7bb33 100755 --- a/.agents/scripts/dispatch-dedup-helper.sh +++ b/.agents/scripts/dispatch-dedup-helper.sh @@ -84,8 +84,15 @@ extract_keys() { fi # Pattern 4: Branch-style "issue-NNN-" or "pr-NNN-" (from worktree names) + # Use a portable fallback chain: rg (ripgrep) → ggrep -P (GNU grep on macOS) → grep -E local branch_issue_nums - branch_issue_nums=$(printf '%s' "$lower_title" | grep -oE 'issue-([0-9]+)' | grep -oE '[0-9]+' || true) + if command -v rg &>/dev/null; then + branch_issue_nums=$(printf '%s' "$lower_title" | rg -o 'issue-([0-9]+)' | grep -oE '[0-9]+' || true) + elif command -v ggrep &>/dev/null && ggrep -P '' /dev/null 2>/dev/null; then + branch_issue_nums=$(printf '%s' "$lower_title" | ggrep -oP 'issue-\K[0-9]+' || true) + else + branch_issue_nums=$(printf '%s' "$lower_title" | grep -oE 'issue-([0-9]+)' | grep -oE '[0-9]+' || true) + fi if [[ -n "$branch_issue_nums" ]]; then while IFS= read -r num; do [[ -n "$num" ]] && keys+=("issue-${num}") @@ -124,31 +131,32 @@ normalize_title() { # Returns: one "pid|key" pair per line on stdout ####################################### list_running_keys() { - local worker_procs - # Get full command lines of running worker processes - # macOS ps -eo pid,args works; Linux ps -eo pid,args works too - # shellcheck disable=SC2009 # Need ps+grep for full cmdline; pgrep can't return args - worker_procs=$(ps -eo pid,args 2>/dev/null | grep -E '/full-loop|opencode run|claude.*run' | grep -v grep || true) - - if [[ -z "$worker_procs" ]]; then + # Get PIDs of running worker processes using portable pgrep -f (no -a flag). + # pgrep -f matches against the full command line on both Linux and macOS. + # We then resolve the full command line per PID via ps -p -o args= + # which is POSIX-compatible and works on Linux, macOS, and BSD. + local worker_pids="" + worker_pids=$(pgrep -f '/full-loop|opencode run|claude.*run' || true) + + if [[ -z "$worker_pids" ]]; then return 0 fi - while IFS= read -r proc_line; do - [[ -z "$proc_line" ]] && continue - local pid - pid=$(printf '%s' "$proc_line" | awk '{print $1}') - local cmdline - cmdline=$(printf '%s' "$proc_line" | sed 's/^[[:space:]]*[0-9]*[[:space:]]*//') + while IFS= read -r pid; do + [[ -z "$pid" ]] && continue + local cmdline="" + # ps -p -o args= prints only the command line (no header, no PID prefix) + cmdline=$(ps -p "$pid" -o args= 2>/dev/null || true) + [[ -z "$cmdline" ]] && continue - local keys - keys=$(extract_keys "$cmdline") - if [[ -n "$keys" ]]; then + local extracted_keys="" + extracted_keys=$(extract_keys "$cmdline") + if [[ -n "$extracted_keys" ]]; then while IFS= read -r key; do [[ -n "$key" ]] && printf '%s|%s\n' "$pid" "$key" - done <<<"$keys" + done <<<"$extracted_keys" fi - done <<<"$worker_procs" + done <<<"$worker_pids" return 0 }