From 919f12e721d7fa22afcaea97d12b9837707e1d67 Mon Sep 17 00:00:00 2001 From: alfdav <23536173+alfdav@users.noreply.github.com> Date: Sun, 19 Apr 2026 11:28:20 -0500 Subject: [PATCH] fix: update codex-review.sh for current Codex CLI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Codex CLI no longer supports `--approval-mode`, `--quiet`, or `-p` flags. The `o4-mini` model is also unavailable on ChatGPT accounts. Additionally, `codex review` outputs a full session transcript (header, tool calls, skill loading) before the actual review — the old script captured only the preamble and missed the findings entirely. Changes: - Replace `codex --approval-mode full-auto --model X --quiet -p` with native `codex review --base ` subcommand - Remove hardcoded `o4-mini` — uses Codex's configured default - Add `_extract_codex_review_body()` to parse session transcripts and extract the final assistant turn (the actual review) - Remove 3000-char truncation that cut off findings - Add broader clean-review detection (LGTM, no issues, looks good) - Add `_append_raw_review()` for native review output storage - Keep legacy P0-P3 table parser as fallback Tested against Codex CLI v0.118.0 with gpt-5.4 on a 1264-line diff. Review produced 4 real findings (2x P1, 2x P2), all correctly extracted and stored. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/codex-review.sh | 102 ++++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 14 deletions(-) diff --git a/scripts/codex-review.sh b/scripts/codex-review.sh index dbd454a..b36018e 100755 --- a/scripts/codex-review.sh +++ b/scripts/codex-review.sh @@ -21,6 +21,9 @@ else bp_config_get() { echo "${2:-}"; } fi +# Note: custom review prompts were used with the old `codex --approval-mode` +# invocation. The current `codex review --base` subcommand uses its own +# built-in review logic. The prompt builder is kept for `codex exec` fallback. _bp_build_review_prompt() { local caveman_active="false" if type bp_config_caveman_active &>/dev/null; then @@ -34,8 +37,6 @@ _bp_build_review_prompt() { fi } -REVIEW_PROMPT="$(_bp_build_review_prompt)" - # ── Main entry point ─────────────────────────────────────────────────── bp_codex_review() { @@ -82,38 +83,58 @@ bp_codex_review() { diff_lines="$(echo "$diff" | wc -l | tr -d ' ')" echo "[ck:review] Diff is ${diff_lines} lines. Sending to Codex..." - # Build Codex invocation - local model - model="$(bp_config_get codex_model o4-mini)" - - local codex_cmd=(codex --approval-mode full-auto --model "$model" --quiet -p "$REVIEW_PROMPT") + # Build Codex invocation — uses native `codex review` subcommand. + # `codex review --base` handles diffing internally and uses its own + # review prompt. Model comes from Codex config (~/.codex/config.toml), + # not forced here — avoids model-availability errors across accounts. + local codex_cmd=(codex review --base "$base_ref") if [[ "${BP_CODEX_DRY_RUN:-}" == "1" ]]; then - echo "[ck:review] DRY RUN — would execute: ${codex_cmd[*]} <<< " + echo "[ck:review] DRY RUN — would execute: ${codex_cmd[*]}" return 0 fi local raw_output - raw_output="$(echo "$diff" | "${codex_cmd[@]}" 2>&1)" || { + raw_output="$("${codex_cmd[@]}" 2>&1)" || { echo "[ck:review] Codex invocation failed. Falling back to inspector-only review." echo "[ck:review] Error: ${raw_output:0:500}" return 0 } - # Parse output - if echo "$raw_output" | grep -qi 'NO_FINDINGS'; then + # Extract the review body from the Codex session transcript. + # `codex review` outputs a full session log: header, tool calls (skill loading), + # then the actual review as the final assistant ("codex") turn. We want only + # the review body — everything after the last "codex\n" marker that follows + # tool output, skipping the session preamble and skill-loading noise. + local review_body + review_body="$(_extract_codex_review_body "$raw_output")" + + if [[ -z "$review_body" ]]; then + # Fallback: couldn't parse transcript structure, use full output + review_body="$raw_output" + fi + + # Check for clean review + if echo "$review_body" | grep -qiE 'NO_FINDINGS|no issues|LGTM|looks good|no bugs|no problems'; then echo "[ck:review] Codex found no issues. Clean review." return 0 fi echo "[ck:review] Parsing Codex findings..." + # Try legacy table format first (P0-P3 severity rows) local findings - findings="$(_parse_codex_findings "$raw_output")" + findings="$(_parse_codex_findings "$review_body")" if [[ -z "$findings" ]]; then - echo "[ck:review] Could not parse findings from Codex output." - echo "[ck:review] Raw (first 1000 chars): ${raw_output:0:1000}" + # Native codex review format — store full review body + echo "[ck:review] Native review format detected. Storing findings." + _append_raw_review "$review_body" + echo "" + echo "[ck:review] === Codex Review Output ===" + echo "$review_body" + echo "[ck:review] === End of Review ===" + echo "[ck:review] Findings appended to $FINDINGS_FILE" return 0 fi @@ -213,6 +234,59 @@ _next_finding_number() { fi } +_extract_codex_review_body() { + # Codex session transcript format (simplified): + #
+ # user + # + # exec + # + # codex ← the assistant's review response starts here + # + # + # We want everything after the LAST "^codex$" line, which is the + # final assistant turn containing the actual review findings. + local raw="$1" + + # Find the last occurrence of a line that is exactly "codex" + # (the assistant turn marker in the transcript) + local last_codex_line + last_codex_line="$(echo "$raw" | grep -n '^codex$' | tail -1 | cut -d: -f1)" + + if [[ -z "$last_codex_line" ]]; then + # No "codex" turn marker found — can't parse transcript + echo "" + return + fi + + # Extract everything after that line + echo "$raw" | tail -n +"$((last_codex_line + 1))" +} + +_append_raw_review() { + local raw="$1" + mkdir -p "$(dirname "$FINDINGS_FILE")" + + if [[ ! -f "$FINDINGS_FILE" ]]; then + cat > "$FINDINGS_FILE" << 'HEADER' +# Review Findings + +| Finding | Severity | File | Status | Task | +|---------|----------|------|--------|------| +HEADER + fi + + # Append native review output as a fenced block (no truncation) + { + echo "" + echo "### Codex Native Review — $(date -u '+%Y-%m-%dT%H:%M:%SZ')" + echo "" + echo '```' + echo "$raw" + echo '```' + } >> "$FINDINGS_FILE" +} + _append_findings_to_file() { local findings="$1"