- 新增 jsc-skills plugin,含 herdr、herdr-issue、ingest,以 /jsc-skills:<名稱> 呼叫 - ingest 自 companion 移入,移除獨立的 herdr-issue plugin - companion 版本由 0.0.3 改為 0.0.1 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
71 lines
3.2 KiB
Bash
Executable File
71 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# 用法:watch-issue.sh <owner/repo> <N>(在 clone 裡以背景執行)
|
||
# 每 HERDR_ISSUE_WATCH_INTERVAL 秒(預設 5)查議題;agent blocked 超過 HERDR_ISSUE_BLOCKED_AFTER 秒(預設 60,只通知一次)或消失就彈 Herdr 通知;議題關閉時清理並往上檢查規格、總覽。
|
||
source "$(dirname "$0")/lib.sh"
|
||
REPO="${1:?}"; N="${2:?用法:watch-issue.sh <owner/repo> <N>}"
|
||
CLONE="$(clone_root_for "$REPO")"
|
||
BRANCH="issue-$N"
|
||
WT="$(worktree_path "$N" "$CLONE")"
|
||
LAST=""
|
||
WATCH_INTERVAL="${HERDR_ISSUE_WATCH_INTERVAL:-5}" # 輪詢秒數(不耗額度,只查 Gitea 與 Herdr)
|
||
BLOCKED_AFTER="${HERDR_ISSUE_BLOCKED_AFTER:-60}" # blocked 連續超過幾秒才通知
|
||
BLOCKED_SINCE=0
|
||
NOTIFIED=false
|
||
|
||
# 若 <label> 底下沒有 open 議題,留言並關閉議題 X;印出 closed|open|skip
|
||
close_if_done() { # $1=X $2=label
|
||
[ "$(issue_state "$REPO" "$1")" = open ] || { echo skip; return; }
|
||
if [ "$(open_count_with_label "$REPO" "$2")" = 0 ]; then
|
||
tea comment "$1" --repo "$REPO" "底下的議題全部關閉,由 herdr-issue 自動關閉。" >/dev/null
|
||
tea issues close "$1" --repo "$REPO" >/dev/null
|
||
echo closed
|
||
else
|
||
echo open
|
||
fi
|
||
}
|
||
|
||
while [ "$(issue_state "$REPO" "$N")" != closed ]; do # 查詢失敗會回空字串,要繼續等,不能當成已關閉
|
||
S="$(agent_status "$N")"
|
||
NOW="$(date +%s)"
|
||
if [ "$S" = blocked ]; then
|
||
[ "$LAST" = blocked ] || { BLOCKED_SINCE=$NOW; NOTIFIED=false; }
|
||
if ! $NOTIFIED && [ $((NOW - BLOCKED_SINCE)) -ge "$BLOCKED_AFTER" ]; then
|
||
notify "#$N 等你回答" "issue-$N 已 blocked 超過 $BLOCKED_AFTER 秒"
|
||
NOTIFIED=true
|
||
fi
|
||
elif [ "$S" = missing ] && [ "$LAST" != missing ] && [ -n "$LAST" ]; then
|
||
notify "#$N 的 agent 不見了" "issue-$N 的 agent 已結束,議題仍 open"
|
||
fi
|
||
LAST="$S"
|
||
sleep "$WATCH_INTERVAL"
|
||
done
|
||
|
||
echo "#$N 已關閉,開始清理"
|
||
LABELS="$(issue_labels "$REPO" "$N")"
|
||
TAB="$(tab_for_issue "$N")"
|
||
[ -n "$TAB" ] && herdr tab close "$TAB" >/dev/null && echo "關閉 tab $TAB"
|
||
tea issues edit "$N" --repo "$REPO" --remove-labels "$LABEL" >/dev/null 2>&1 || true
|
||
|
||
git -C "$CLONE" fetch --quiet origin || true
|
||
read -r PR STATE _ <<<"$(pr_for_issue "$REPO" "$N")" || true
|
||
DELETE_BRANCH=false
|
||
case "${STATE:-none}" in
|
||
merged) DELETE_BRANCH=true; echo "PR #$PR 已合併" ;;
|
||
closed|open) echo "PR #$PR 狀態 $STATE,保留分支" ;;
|
||
*) if [ "$(git -C "$CLONE" rev-list --count "origin/main..$BRANCH" 2>/dev/null || echo 0)" = 0 ]; then DELETE_BRANCH=true; echo "沒有 PR 也沒有 commit"; else echo "沒有 PR 但分支有 commit,保留"; fi ;;
|
||
esac
|
||
if git -C "$CLONE" worktree list --porcelain | grep -qx "worktree $WT"; then
|
||
git -C "$CLONE" worktree remove --force "$WT" && echo "移除 worktree $WT"
|
||
fi
|
||
$DELETE_BRANCH && git -C "$CLONE" branch -D "$BRANCH" >/dev/null 2>&1 && echo "刪除分支 $BRANCH"
|
||
|
||
SPEC="$(grep -o '規格/#[0-9]*' <<<"$LABELS" | head -1 | tr -d '規格/#')"
|
||
if [ -n "$SPEC" ]; then
|
||
R="$(close_if_done "$SPEC" "規格/#$SPEC")"; echo "規格 #$SPEC:$R"
|
||
if [ "$R" = closed ]; then
|
||
OV="$(issue_labels "$REPO" "$SPEC" | grep -o '總覽/#[0-9]*' | head -1 | tr -d '總覽/#')"
|
||
[ -n "$OV" ] && echo "總覽 #$OV:$(close_if_done "$OV" "總覽/#$OV")"
|
||
fi
|
||
fi
|
||
echo "#$N 清理完成"
|