← Files Compound EngineeringARCHIVED FILE
skills/ce-resolve-pr-feedback/scripts/reply-to-pr-thread
1.68 KB · Oct 5, 2026 · 18:34 UTC
#!/usr/bin/env bash
# Replies directly to a PR review thread's root comment. Body is read from
# stdin to preserve Markdown quotes and newlines. The REST reply endpoint is
# load-bearing: GraphQL addPullRequestReviewThreadReply can attach the reply to
# a pending review and return success before the reply is submitted or visible.
set -e
if [ $# -lt 2 ]; then
echo "Usage: reply-to-pr-thread PR_NUMBER ROOT_COMMENT_ID [OWNER/REPO] < reply-body.md"
echo "Example: reply-to-pr-thread 123 456789 EveryInc/cora < reply-body.md"
exit 1
fi
PR_NUMBER=$1
ROOT_COMMENT_ID=$2
BODY=$(cat)
if [ -n "$3" ]; then
OWNER=$(echo "$3" | cut -d/ -f1)
REPO=$(echo "$3" | cut -d/ -f2)
else
OWNER=$(gh repo view --json owner -q .owner.login 2>/dev/null || true)
REPO=$(gh repo view --json name -q .name 2>/dev/null || true)
fi
if [ -z "$OWNER" ] || [ -z "$REPO" ]; then
echo "Error: could not resolve owner/repo. Pass OWNER/REPO as the third argument." >&2
exit 1
fi
case "$PR_NUMBER" in
''|*[!0-9]*) echo "Error: PR_NUMBER must be numeric." >&2; exit 1 ;;
esac
case "$ROOT_COMMENT_ID" in
''|*[!0-9]*) echo "Error: ROOT_COMMENT_ID must be numeric." >&2; exit 1 ;;
esac
if [ -z "$BODY" ]; then
echo "Error: No body provided on stdin."
exit 1
fi
gh api --method POST \
"repos/$OWNER/$REPO/pulls/$PR_NUMBER/comments/$ROOT_COMMENT_ID/replies" \
-f body="$BODY"
PENDING_REVIEW=$(gh api --paginate \
"repos/$OWNER/$REPO/pulls/$PR_NUMBER/reviews" \
--jq '.[] | select(.state == "PENDING") | .id')
if [ -n "$PENDING_REVIEW" ]; then
echo "Error: a pending review appeared after posting. Stop without resolving the thread; do not submit or discard the review." >&2
exit 2
fi
SHA-256: 87f6fd4aa4bb599c40ec537308eb47c7f5c2e4dfe3963854c007810f457c7365