From 42a5a4ef8573ce46f8b02d56918ac775d14346c9 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 28 Mar 2026 14:11:32 +0000 Subject: [PATCH] fix: review-poll.sh still uses tmux for session cleanup and injection (#11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace tmux session discovery with .sid file globbing for stale session cleanup and re-review triggering. Remove inject_review_into_dev_session (dead code — both review and dev sessions now use SDK agent_run). Co-Authored-By: Claude Opus 4.6 (1M context) --- review/review-poll.sh | 165 +++++++----------------------------------- 1 file changed, 28 insertions(+), 137 deletions(-) diff --git a/review/review-poll.sh b/review/review-poll.sh index dbd6e72..aa373df 100755 --- a/review/review-poll.sh +++ b/review/review-poll.sh @@ -38,56 +38,42 @@ fi log "--- Poll start ---" -# --- Clean up stale review sessions --- -# Kill sessions for merged/closed PRs or idle > 4h -REVIEW_SESSIONS=$(tmux list-sessions -F '#{session_name}' 2>/dev/null | grep "^review-${PROJECT_NAME}-" || true) -if [ -n "$REVIEW_SESSIONS" ]; then - while IFS= read -r session; do - pr_num="${session#review-"${PROJECT_NAME}"-}" +# --- Clean up stale review sessions (.sid files + worktrees) --- +# Remove .sid files, phase files, and worktrees for merged/closed PRs or idle > 4h +REVIEW_SIDS=$(compgen -G "/tmp/review-session-${PROJECT_NAME}-*.sid" 2>/dev/null || true) +if [ -n "$REVIEW_SIDS" ]; then + while IFS= read -r sid_file; do + base=$(basename "$sid_file") + pr_num="${base#review-session-"${PROJECT_NAME}"-}" + pr_num="${pr_num%.sid}" phase_file="/tmp/review-session-${PROJECT_NAME}-${pr_num}.phase" + worktree="/tmp/${PROJECT_NAME}-review-${pr_num}" # Check if PR is still open pr_state=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \ "${API_BASE}/pulls/${pr_num}" | jq -r '.state // "unknown"' 2>/dev/null) || true if [ "$pr_state" != "open" ]; then - log "cleanup: killing session ${session} (PR #${pr_num} state=${pr_state})" - tmux kill-session -t "$session" 2>/dev/null || true - rm -f "$phase_file" "/tmp/${PROJECT_NAME}-review-output-${pr_num}.json" \ - "/tmp/review-injected-${PROJECT_NAME}-${pr_num}" + log "cleanup: PR #${pr_num} state=${pr_state} — removing sid/worktree" + rm -f "$sid_file" "$phase_file" "/tmp/${PROJECT_NAME}-review-output-${pr_num}.json" cd "$REPO_ROOT" - git worktree remove "/tmp/${PROJECT_NAME}-review-${pr_num}" --force 2>/dev/null || true - rm -rf "/tmp/${PROJECT_NAME}-review-${pr_num}" 2>/dev/null || true + git worktree remove "$worktree" --force 2>/dev/null || true + rm -rf "$worktree" 2>/dev/null || true continue fi - # Check idle timeout (4h) - phase_mtime=$(stat -c %Y "$phase_file" 2>/dev/null || echo 0) + # Check idle timeout (4h) via .sid file mtime + sid_mtime=$(stat -c %Y "$sid_file" 2>/dev/null || echo 0) now=$(date +%s) - if [ "$phase_mtime" -gt 0 ] && [ $(( now - phase_mtime )) -gt "$REVIEW_IDLE_TIMEOUT" ]; then - log "cleanup: killing session ${session} (idle > 4h)" - tmux kill-session -t "$session" 2>/dev/null || true - rm -f "$phase_file" "/tmp/${PROJECT_NAME}-review-output-${pr_num}.json" \ - "/tmp/review-injected-${PROJECT_NAME}-${pr_num}" + if [ "$sid_mtime" -gt 0 ] && [ $(( now - sid_mtime )) -gt "$REVIEW_IDLE_TIMEOUT" ]; then + log "cleanup: PR #${pr_num} idle > 4h — removing sid/worktree" + rm -f "$sid_file" "$phase_file" "/tmp/${PROJECT_NAME}-review-output-${pr_num}.json" cd "$REPO_ROOT" - git worktree remove "/tmp/${PROJECT_NAME}-review-${pr_num}" --force 2>/dev/null || true - rm -rf "/tmp/${PROJECT_NAME}-review-${pr_num}" 2>/dev/null || true + git worktree remove "$worktree" --force 2>/dev/null || true + rm -rf "$worktree" 2>/dev/null || true continue fi - - # Safety net: clean up sessions in terminal phases (review already posted) - current_phase=$(head -1 "$phase_file" 2>/dev/null | tr -d '[:space:]' || true) - if [ "$current_phase" = "PHASE:review_complete" ]; then - log "cleanup: killing session ${session} (terminal phase: review_complete)" - tmux kill-session -t "$session" 2>/dev/null || true - rm -f "$phase_file" "/tmp/${PROJECT_NAME}-review-output-${pr_num}.json" \ - "/tmp/review-injected-${PROJECT_NAME}-${pr_num}" - cd "$REPO_ROOT" - git worktree remove "/tmp/${PROJECT_NAME}-review-${pr_num}" --force 2>/dev/null || true - rm -rf "/tmp/${PROJECT_NAME}-review-${pr_num}" 2>/dev/null || true - continue - fi - done <<< "$REVIEW_SESSIONS" + done <<< "$REVIEW_SIDS" fi PRS=$(curl -sf -H "Authorization: token ${FORGE_TOKEN}" \ @@ -105,95 +91,12 @@ log "Found ${TOTAL} open PRs" REVIEWED=0 SKIPPED=0 -inject_review_into_dev_session() { - local pr_num="$1" pr_sha="$2" pr_branch="$3" - - local issue_num - issue_num=$(printf '%s' "$pr_branch" | grep -oP 'issue-\K[0-9]+' || true) - [ -z "$issue_num" ] && return 0 - - local session="dev-${PROJECT_NAME}-${issue_num}" - local phase_file="/tmp/dev-session-${PROJECT_NAME}-${issue_num}.phase" - - tmux has-session -t "${session}" 2>/dev/null || return 0 - - local current_phase - current_phase=$(head -1 "${phase_file}" 2>/dev/null | tr -d '[:space:]' || true) - [ "${current_phase}" = "PHASE:awaiting_review" ] || return 0 - - local review_text="" verdict="" - - # Try bot review comment first (richer content with marker) - local review_comment - review_comment=$(forge_api_all "/issues/${pr_num}/comments" | \ - jq -r --arg sha "${pr_sha}" \ - '[.[] | select(.body | contains("