Files
John T. MyersandJohn Myers 4d16a2a6f4 feat(gator): improve review output and launch compatibility (#2896)
* feat(gator): render human-readable review findings

Signed-off-by: John Myers <johntmyers@users.noreply.github.com>

* feat(gator): collapse operational review metadata

Signed-off-by: John Myers <johntmyers@users.noreply.github.com>

* fix(gator): support canonical sandbox startup

Signed-off-by: John Myers <johntmyers@users.noreply.github.com>

* fix(gator): preserve credential placeholder identity

Signed-off-by: John Myers <johntmyers@users.noreply.github.com>

* feat(gator): resolve addressed review threads

Signed-off-by: John Myers <johntmyers@users.noreply.github.com>

* fix(agents): preserve provider profile revisions

Signed-off-by: John Myers <johntmyers@users.noreply.github.com>

---------

Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
Co-authored-by: John Myers <johntmyers@users.noreply.github.com>
2026-08-25 19:59:04 +00:00

214 lines
7.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
REAL_GH="${OPENSHELL_REAL_GH:-/usr/bin/gh}"
GATOR_MARKER='> **gator-agent**'
GATOR_PAYLOAD_VERSION="${OPENSHELL_AGENT_PAYLOAD_VERSION:-5}"
if [[ $# -lt 1 || "$1" != "api" ]]; then
exec "$REAL_GH" "$@"
fi
method="GET"
input_file=""
body_field=""
endpoint=""
args=("$@")
consume_next=false
for ((i = 1; i < ${#args[@]}; i++)); do
arg="${args[$i]}"
if [[ "$consume_next" == "true" ]]; then
consume_next=false
continue
fi
case "$arg" in
--method|-X)
if (( i + 1 < ${#args[@]} )); then
method="${args[$((i + 1))]}"
consume_next=true
fi
;;
--method=*)
method="${arg#--method=}"
;;
--input)
if (( i + 1 < ${#args[@]} )); then
input_file="${args[$((i + 1))]}"
consume_next=true
fi
;;
--input=*)
input_file="${arg#--input=}"
;;
-f|--field|-F|--raw-field)
if (( i + 1 < ${#args[@]} )); then
field="${args[$((i + 1))]}"
if [[ "$field" == body=* ]]; then
body_field="${field#body=}"
fi
consume_next=true
fi
;;
-fbody=*|--field=body=*|-Fbody=*|--raw-field=body=*)
body_field="${arg#*=body=}"
;;
--*)
;;
*)
if [[ -z "$endpoint" ]]; then
endpoint="${arg#/}"
fi
;;
esac
done
read_body() {
if [[ -n "$input_file" && -f "$input_file" ]]; then
jq -r '.body // empty' "$input_file" 2>/dev/null || true
return
fi
printf '%s' "$body_field"
}
is_legacy_reviewer_failure_disposition() {
local existing_body="$1"
local head_sha="$2"
[[ "$existing_body" == *"$GATOR_MARKER"* ]] || return 1
[[ "$existing_body" == *"$head_sha"* ]] || return 1
[[ "$existing_body" == *"principal-engineer-reviewer"* ]] || return 1
[[ "$existing_body" == *"failed before producing"* ]] || return 1
}
is_draft_only_blocker_disposition() {
local existing_body="$1"
local head_sha="$2"
local lower_body
[[ "$existing_body" == *"$GATOR_MARKER"* ]] || return 1
[[ "$existing_body" == *"$head_sha"* ]] || return 1
lower_body="$(printf '%s' "$existing_body" | tr '[:upper:]' '[:lower:]')"
[[ "$lower_body" == *"## blocked"* ]] || return 1
[[ "$lower_body" == *"marked as a draft"* || "$lower_body" == *"pull request is a draft"* || "$lower_body" == *"pr is draft"* ]] || return 1
}
is_ttl_state_nudge() {
local body="$1"
[[ "$body" == *"$GATOR_MARKER"* ]] || return 1
[[ "$body" == *"more than 48 business hours"* ]] || return 1
case "$body" in
*"## Author Follow-Up Nudge"*|*"## Maintainer Review Nudge"*|*"## Merge Decision Nudge"*|*"## Blocker Follow-Up Nudge"*)
return 0
;;
*)
return 1
;;
esac
}
has_blocking_same_sha_disposition() {
local head_sha="$1"
local current_is_draft="$2"
local encoded_bodies="$3"
local encoded_body existing_body
while IFS= read -r encoded_body; do
[[ -n "$encoded_body" ]] || continue
existing_body="$(printf '%s' "$encoded_body" | jq -r . 2>/dev/null || printf '%s' "$encoded_body")"
[[ "$existing_body" == *"$head_sha"* ]] || continue
if is_legacy_reviewer_failure_disposition "$existing_body" "$head_sha"; then
continue
fi
if [[ "$current_is_draft" != "true" ]] && is_draft_only_blocker_disposition "$existing_body" "$head_sha"; then
continue
fi
return 0
done <<< "$encoded_bodies"
return 1
}
guard_duplicate_gator_disposition() {
local owner="$1"
local repo="$2"
local number="$3"
local body="$4"
[[ "$body" == *"$GATOR_MARKER"* ]] || return 0
[[ "$body" != *"## Monitoring Complete"* ]] || return 0
# A TTL state nudge is not a review disposition. Its frequency and target
# are governed by the gator skill; allow it to keep an unchanged PR moving.
is_ttl_state_nudge "$body" && return 0
local pull_json head_sha current_is_draft
if ! pull_json="$($REAL_GH api "repos/$owner/$repo/pulls/$number" 2>/dev/null)"; then
echo "openshell-agent: blocked gator write because current PR head lookup failed for $owner/$repo#$number" >&2
return 21
fi
head_sha="$(printf '%s' "$pull_json" | jq -r '.head.sha // empty' 2>/dev/null || true)"
current_is_draft="$(printf '%s' "$pull_json" | jq -r '.draft // false' 2>/dev/null || true)"
if [[ -z "$head_sha" ]]; then
echo "openshell-agent: blocked gator write because current PR head was missing for $owner/$repo#$number" >&2
return 21
fi
if is_legacy_reviewer_failure_disposition "$body" "$head_sha"; then
echo "openshell-agent: blocked public reviewer sub-agent failure disposition for $owner/$repo#$number ($head_sha)" >&2
echo "openshell-agent: return OPENSHELL_AGENT_RESULT status=transient_failure with reason=reviewer_subagent_failed instead" >&2
return 20
fi
local existing_comments existing_reviews
if ! existing_comments="$($REAL_GH api "repos/$owner/$repo/issues/$number/comments" --paginate --jq '.[] | select(.body | contains("> **gator-agent**")) | .body | @json' 2>/dev/null)"; then
echo "openshell-agent: blocked gator write because existing comment lookup failed for $owner/$repo#$number" >&2
return 21
fi
if ! existing_reviews="$($REAL_GH api "repos/$owner/$repo/pulls/$number/reviews" --paginate --jq '.[] | select(.body | contains("> **gator-agent**")) | .body | @json' 2>/dev/null)"; then
echo "openshell-agent: blocked gator write because existing review lookup failed for $owner/$repo#$number" >&2
return 21
fi
if has_blocking_same_sha_disposition "$head_sha" "$current_is_draft" "$(printf '%s\n%s\n' "$existing_comments" "$existing_reviews")"; then
echo "openshell-agent: blocked duplicate gator same-SHA disposition for $owner/$repo#$number ($head_sha)" >&2
echo "openshell-agent: push a new commit, remove the old disposition, or set OPENSHELL_GATOR_ALLOW_SAME_SHA_COMMENT=1 for an explicit maintainer-requested same-SHA action" >&2
return 20
fi
if [[ "$body" == *"## PR Review Status"* || "$body" == *"## Re-check After"* ]]; then
if [[ "$body" != *"Head SHA: \`$head_sha\`"* && "$body" != *"Head SHA: $head_sha"* ]]; then
echo "openshell-agent: blocked gator review disposition without the exact current Head SHA for $owner/$repo#$number" >&2
return 22
fi
if [[ "$body" != *"Gator payload: \`$GATOR_PAYLOAD_VERSION\`"* && "$body" != *"Gator payload: $GATOR_PAYLOAD_VERSION"* ]]; then
echo "openshell-agent: blocked gator review disposition without Gator payload version $GATOR_PAYLOAD_VERSION" >&2
return 22
fi
fi
}
if [[ "${OPENSHELL_GATOR_ALLOW_SAME_SHA_COMMENT:-}" != "1" && "${method^^}" == "POST" ]]; then
request_body="$(read_body)"
if [[ "$endpoint" =~ ^repos/([^/]+)/([^/]+)/issues/([0-9]+)/comments$ ]]; then
guard_duplicate_gator_disposition "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}" "$request_body"
elif [[ "$endpoint" =~ ^repos/([^/]+)/([^/]+)/pulls/([0-9]+)/reviews$ ]]; then
guard_duplicate_gator_disposition "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}" "$request_body"
fi
fi
exec "$REAL_GH" "$@"