-
Notifications
You must be signed in to change notification settings - Fork 0
Test/trigger ai review #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6bc724a
cd39d86
e9073fd
c1e4c94
1516e43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| [ | ||
| { | ||
| "repo": "Alamofire/Alamofire", | ||
| "pr": 4038, | ||
| "title": "Fix for DataPreprocessor doesn't have it's own failure reason #3073", | ||
| "url": "https://github.com/Alamofire/Alamofire/pull/4038", | ||
| "reviewed_at": "2026-06-08T02:38:00.000Z", | ||
| "mode": "agent", | ||
| "findings": { | ||
| "high": 0, | ||
| "medium": 1, | ||
| "low": 0 | ||
| }, | ||
| "merged": false, | ||
| "pr_state": "open" | ||
| } | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| 'use strict'; | ||
| // Usage: node log-review.js <owner/repo> <pr-number> <mode> | ||
| // Fetches PR metadata + latest Preflight review from GitHub, appends to data/reviews.json. | ||
|
|
||
| const { execSync } = require('child_process'); | ||
| const fs = require('fs'); | ||
| const path = require('path'); | ||
|
|
||
| const [repo, pr, mode] = process.argv.slice(2); | ||
| if (!repo || !pr || !mode) { | ||
| console.error('Usage: log-review.js owner/repo pr-number mode'); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| function gh(endpoint) { | ||
| return JSON.parse(execSync(`gh api ${endpoint}`, { encoding: 'utf-8' })); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] Command injection via unsanitized The Category: security issues |
||
| } | ||
|
|
||
| const prData = gh(`repos/${repo}/pulls/${pr}`); | ||
| const reviews = gh(`repos/${repo}/pulls/${pr}/reviews`); | ||
|
|
||
| const review = [...reviews].reverse().find(r => r.body && r.body.includes('Preflight')) | ||
| || [...reviews].reverse().find(r => r.body); | ||
|
|
||
| let high = 0, medium = 0, low = 0; | ||
| if (review) { | ||
| const body = review.body; | ||
| const hm = body.match(/(\d+) high/i); if (hm) high = parseInt(hm[1], 10); | ||
| const mm = body.match(/(\d+) medium/i); if (mm) medium = parseInt(mm[1], 10); | ||
| const lm = body.match(/(\d+) low/i); if (lm) low = parseInt(lm[1], 10); | ||
| } | ||
|
|
||
| const entry = { | ||
| repo, | ||
| pr: parseInt(pr, 10), | ||
| title: prData.title, | ||
| url: prData.html_url, | ||
| reviewed_at: new Date().toISOString(), | ||
| mode, | ||
| findings: { high, medium, low }, | ||
| merged: prData.merged, | ||
| pr_state: prData.state, | ||
| }; | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] On line 44, Category: edge cases |
||
| const dataFile = path.join(__dirname, '..', 'data', 'reviews.json'); | ||
| const log = JSON.parse(fs.readFileSync(dataFile, 'utf-8')); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [HIGH] Line 46 calls Category: edge cases |
||
| log.unshift(entry); | ||
| fs.writeFileSync(dataFile, JSON.stringify(log, null, 2) + '\n'); | ||
|
|
||
| console.log(`[preflight] Logged — ${high} high, ${medium} medium, ${low} low → ${prData.html_url}`); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| #!/usr/bin/env bash | ||
| # Preflight — agent mode | ||
| # Usage: ./scripts/preflight-agent.sh <owner/repo> <pr-number> | ||
| # | ||
| # Runs Claude Code as the reviewer directly — no Anthropic API key needed. | ||
| # Requires: claude CLI (Claude Code), gh CLI authenticated with repo access. | ||
| # Works with public repos, private repos, and GitHub Enterprise (gh handles auth). | ||
| set -euo pipefail | ||
|
|
||
| REPO="${1:?Usage: preflight-agent.sh owner/repo pr-number}" | ||
| PR="${2:?Usage: preflight-agent.sh owner/repo pr-number}" | ||
|
|
||
| if ! command -v claude &>/dev/null; then | ||
| echo "Error: claude CLI not found. Install Claude Code: https://claude.ai/code" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! command -v gh &>/dev/null; then | ||
| echo "Error: gh CLI not found. Install: https://cli.github.com" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if ! gh api "repos/$REPO" --silent 2>/dev/null; then | ||
| echo "Error: gh cannot access $REPO. Run 'gh auth login' and ensure you have repo access." | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] Unquoted Line 24 uses Category: security issues |
||
| exit 1 | ||
| fi | ||
|
|
||
| echo "[preflight] Starting agent review of $REPO#$PR ..." | ||
|
|
||
| claude -p "You are Preflight, an automated code reviewer. Review GitHub PR $REPO#$PR and post your findings as inline comments. | ||
|
|
||
| ## Steps | ||
|
|
||
| 1. Fetch the list of changed files: | ||
| gh api repos/$REPO/pulls/$PR/files --paginate | ||
|
|
||
| 2. Filter out files that should be skipped (do not review these): | ||
| - Paths containing: vendor/, node_modules/ | ||
| - Filenames matching: *.generated.*, package-lock.json, go.sum, *.lock, *.pb.go, *_generated.go | ||
| - Files where (additions + deletions) > 500 | ||
| - After filtering, take only the top 10 files ranked by (additions + deletions) descending | ||
|
|
||
| 3. For each file to review, fetch its full content using the blob sha from step 1: | ||
| gh api repos/$REPO/git/blobs/{sha} --jq '.content' | base64 -d | ||
|
|
||
| 4. Study the diff patch for each file. Note exactly which line numbers in the new file were added or changed (lines starting with '+' in the patch, tracking the @@ hunk headers). | ||
|
|
||
| 5. Review only the changed lines for real bugs — not style, not formatting. Categories: | ||
| - null/nil dereference | ||
| - unhandled errors / ignored return values | ||
| - race conditions | ||
| - resource leaks (unclosed files, connections, goroutines) | ||
| - security issues (injection, path traversal, unvalidated input, auth bypass) | ||
| - logic errors / off-by-one | ||
| - type mismatches | ||
|
|
||
| 6. Post a single PR review via: | ||
| gh api repos/$REPO/pulls/$PR/reviews --method POST --input - | ||
|
|
||
| Build the JSON payload with: | ||
| - commit_id: the PR head SHA (fetch from gh api repos/$REPO/pulls/$PR --jq '.head.sha') | ||
| - event: COMMENT | ||
| - body: MUST start with exactly '## Preflight Review', followed by a blank line, | ||
| then 2-3 sentences summarizing what the PR does, then a blank line, | ||
| then exactly one of these findings lines: | ||
| '**Findings:** N high, N medium, N low' (if bugs found) | ||
| '**No bugs found** in the reviewed files.' (if none) | ||
| - comments: array of inline findings (high + medium severity only) | ||
| Each comment needs: path, line (new-file line number), side: RIGHT, body | ||
|
|
||
| Format each inline comment body as: | ||
| **[SEVERITY] Title** | ||
|
|
||
| Explanation citing exact symbol name and line. | ||
|
|
||
| _Category: category_ | ||
|
|
||
| 7. If no bugs are found, post the review with an empty comments array. | ||
|
|
||
| ## Rules | ||
| - Only comment on lines present in the diff. Never flag unchanged lines. | ||
| - Cite exact line numbers, function names, and variable names. | ||
| - Consolidate everything into a single gh api call — do not post multiple reviews. | ||
| - If files were skipped due to filters, list them in the summary body." \ | ||
| --allowedTools "Bash" \ | ||
| --max-turns 30 | ||
|
|
||
| node "$(dirname "$0")/log-review.js" "$REPO" "$PR" "agent" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #!/usr/bin/env bash | ||
| # Usage: ./scripts/preflight.sh <owner/repo> <pr-number> | ||
| # Runs a local dry-run review against any GitHub PR (public or private). | ||
| set -euo pipefail | ||
|
|
||
| REPO="${1:?Usage: preflight.sh owner/repo pr-number}" | ||
| PR="${2:?Usage: preflight.sh owner/repo pr-number}" | ||
|
|
||
| if [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then | ||
| echo "Error: ANTHROPIC_API_KEY is not set." | ||
| echo "Export it first: export ANTHROPIC_API_KEY=sk-ant-..." | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Pull a token from gh CLI — works for both public and private repos | ||
| # as long as the user is authenticated with sufficient scope (repo). | ||
| GITHUB_TOKEN=$(gh auth token) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] With Category: unhandled errors |
||
|
|
||
| SHA=$(gh api repos/"$REPO"/pulls/"$PR" --jq '.head.sha') | ||
|
|
||
| GITHUB_TOKEN="$GITHUB_TOKEN" \ | ||
| GITHUB_REPOSITORY="$REPO" \ | ||
| PR_NUMBER="$PR" \ | ||
| PR_HEAD_SHA="$SHA" \ | ||
| DRY_RUN=true \ | ||
| node "$(dirname "$0")/review.js" | ||
|
|
||
| node "$(dirname "$0")/log-review.js" "$REPO" "$PR" "api" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[HIGH] Shell injection via unsanitized
repoandprarguments inghhelperThe
ghfunction builds a shell command by string-interpolatingendpointdirectly:execSync(gh api ${endpoint}). The valuesrepoandprcome fromprocess.argvwithout any sanitisation. A malicious caller could passrepo = 'x/y --method DELETE'or a PR number containing shell metacharacters, causing arbitraryghAPI calls or command execution. The arguments should be passed as an array withexecSync('gh', ['api', endpoint], …)or at minimum validated to match expected patterns before use.Category: security issues