@@ -105,46 +105,35 @@ extract_review_score_from_text() {
105105 | grep -oP ' \d+(?=/100)' || echo " "
106106}
107107
108- # Extract the full body of the most recent review comment containing a score
109- # Returns the review comment text (up to 8000 chars, truncated for prompt injection)
108+ # Extract the full body of the most recent review comment containing a score.
109+ # Uses jq to process complete JSON strings, correctly handling multi-line bodies.
110+ # Returns the review comment text (up to 8000 chars, truncated for prompt injection).
110111get_pr_latest_review_body () {
111112 local pr_number=" ${1:- } "
112113 local repo=" ${2:- } "
113- local all_comments=" "
114114 local review_body=" "
115+ # jq regex to match score patterns like "Score: 72/100" or "**Overall Score:** 85/100"
116+ local score_regex=' (?:Overall\s+)?Score:\*?\*?\s*[0-9]+/100'
115117
116118 if [ -z " ${pr_number} " ]; then
117119 echo " "
118120 return
119121 fi
120122
121- # Fetch comments from both gh pr view and gh api
122- all_comments=$(
123- {
124- gh pr view " ${pr_number} " --json comments --jq ' .comments[].body' 2> /dev/null || true
125- if [ -n " ${repo} " ]; then
126- gh api " repos/${repo} /issues/${pr_number} /comments" --jq ' .[].body' 2> /dev/null || true
127- fi
128- } | awk ' !seen[$0]++'
123+ # Use jq to select the last comment body containing a score pattern.
124+ # jq processes the full JSON string (including embedded newlines), so multi-line
125+ # review bodies are matched correctly. "m" flag enables multi-line mode in jq regex.
126+ review_body=$(
127+ gh pr view " ${pr_number} " --json comments \
128+ --jq " [.comments[].body | select(test(\" ${score_regex} \" ; \" m\" ))] | last // empty" 2> /dev/null || true
129129 )
130130
131- if [ -z " ${all_comments} " ]; then
132- echo " "
133- return
134- fi
135-
136- # Find the most recent comment that contains a review score pattern
137- # We iterate through comments and keep the last one that matches the score pattern
138- while IFS= read -r line; do
139- if printf ' %s\n' " ${line} " | grep -qP ' (?:Overall\s+)?Score:\*?\*?\s*\d+/100' ; then
140- review_body=" ${line} "
141- fi
142- done <<< " ${all_comments}"
143-
144- # If no single-line match, try to find a multi-line review comment
145- if [ -z " ${review_body} " ]; then
146- # Fall back to getting all comments and looking for score pattern across multiple lines
147- review_body=$( printf ' %s' " ${all_comments} " | grep -Pzo ' (?s)(?:Overall\s+)?Score:\*?\*?\s*\d+/100.*?(?s)' | tail -1)
131+ # Fallback to gh api if pr view returned nothing (e.g. auth scope differences)
132+ if [ -z " ${review_body} " ] && [ -n " ${repo} " ]; then
133+ review_body=$(
134+ gh api " repos/${repo} /issues/${pr_number} /comments" \
135+ --jq " [.[].body | select(test(\" ${score_regex} \" ; \" m\" ))] | last // empty" 2> /dev/null || true
136+ )
148137 fi
149138
150139 # Truncate to 8000 chars to avoid prompt bloat
@@ -1050,7 +1039,7 @@ if [ -n "${TARGET_PR}" ]; then
10501039 if [ " ${TARGET_SCORE} " -lt " ${MIN_REVIEW_SCORE} " ]; then
10511040 TARGET_REVIEW_BODY=$( get_pr_latest_review_body " ${TARGET_PR} " " ${REPO} " )
10521041 if [ -n " ${TARGET_REVIEW_BODY} " ]; then
1053- TARGET_SCOPE_PROMPT+=$' \n\n ## Latest Review Feedback\n The following review was posted for this PR. Address ALL issues mentioned:\ \ n' " ${TARGET_REVIEW_BODY} " $' \n '
1042+ TARGET_SCOPE_PROMPT+=$' \n\n ## Latest Review Feedback\n The following review was posted for this PR. Address ALL issues mentioned:\n ' " ${TARGET_REVIEW_BODY} " $' \n '
10541043 else
10551044 TARGET_SCOPE_PROMPT+=$' \n\n ## Latest Review Feedback\n - action: fix (review score below threshold)\n '
10561045 fi
0 commit comments