From ce72c4bbadb5d760e3267419fffce3cd3464302c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 13 Feb 2026 15:47:42 +0000 Subject: [PATCH] fix(agents): replace gh CLI with curl for PR checking to prevent duplicate work Agents do not have access to gh CLI, causing them to skip the pre-flight PR check and collide on duplicate work. This replaces all gh-based PR checking commands with curl + jq using the GitHub REST API, updates the task claiming protocol to use branch push + started log file as the primary lock mechanism, and updates automation scripts to use curl for PR listing and git fetch for PR checkout. Files updated: - AGENTS.md (Section 12 coordination rules) - CLAUDE.md (coordination rules) - META_PROMPTS.md (daily + weekly meta prompts) - daily-scheduler.md (pre-flight gate, task claiming, error handling) - weekly-scheduler.md (pre-flight gate, task claiming, error handling) - bitvid-pr-review-agent.md (PR enumeration + checkout) - bitvid-ci-health-agent.md (CI run gathering) - bitvid-weekly-synthesis-agent.md (PR metadata gathering) - bitvid-changelog-agent.md (PR metadata verification) - scripts/agent/review-open-prs.mjs (PR listing + checkout) - scripts/automated-pr-review.mjs (--all mode PR listing + checkout) https://claude.ai/code/session_01L5bzzGpZ6YTiLXcfqaL81G --- AGENTS.md | 37 ++++++++----------- CLAUDE.md | 6 ++- docs/agents/prompts/META_PROMPTS.md | 10 ++--- docs/agents/prompts/daily-scheduler.md | 37 +++++++------------ .../prompts/daily/bitvid-ci-health-agent.md | 2 +- docs/agents/prompts/weekly-scheduler.md | 37 +++++++------------ .../prompts/weekly/bitvid-changelog-agent.md | 2 +- .../prompts/weekly/bitvid-pr-review-agent.md | 11 +++--- .../weekly/bitvid-weekly-synthesis-agent.md | 15 +++++--- scripts/agent/review-open-prs.mjs | 22 +++++++---- scripts/automated-pr-review.mjs | 21 +++++++---- 11 files changed, 97 insertions(+), 103 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 32edb5ca..fe9949e1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -204,7 +204,11 @@ This project uses multiple AI agents (Claude Code, OpenAI Codex, Google Jules) w ### Before Starting Work -1. **Check open PRs.** Run `gh pr list --state open` or check GitHub. If another agent already has a PR touching the same files or subsystem, do not create a competing PR. Instead, note the conflict and ask the maintainer how to proceed. +1. **Check open PRs.** Run the following command to list all open PRs: + ``` + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' + ``` + If another agent already has a PR touching the same files or subsystem, do not create a competing PR. Instead, note the conflict and ask the maintainer how to proceed. 2. **Check this section for in-flight work.** The maintainer may list active work areas below. Respect these reservations. 3. **Read KNOWN_ISSUES.md.** Do not open PRs to fix issues already documented there unless explicitly asked. @@ -242,37 +246,28 @@ When you create a PR or start work, leave a clear signal: ### Task Claiming Protocol (Draft PR Lock) -To prevent multiple agents from working on the same task simultaneously, every agent must **check for and create a draft PR** before starting work. The draft PR acts as a distributed lock visible to all agents across all platforms (Claude Code, Codex, Jules). +To prevent multiple agents from working on the same task simultaneously, every agent must **check open PRs and create a claim** before starting work. The claim (pushed branch + `started` log file) acts as a distributed lock visible to all agents across all platforms (Claude Code, Codex, Jules). **Before starting any task:** -1. **Check for existing claims.** Search for open or draft PRs matching the task: +1. **Check for existing claims.** Search for open PRs matching the task: ``` - gh pr list --state open --search "" + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' ``` - If a matching PR exists (open or draft), **skip the task** — another agent is already working on it. + If a matching PR exists (open or draft) for the same agent or subsystem, **skip the task** — another agent is already working on it. 2. **Claim the task.** If no matching PR exists: a. Create your working branch. - b. Make a minimal initial commit (e.g., update `CONTEXT.md` with the task scope). - c. Push the branch and immediately open a **draft PR**: - ``` - gh pr create --draft \ - --title "[] : " \ - --body "Claimed by at . Work in progress." - ``` - d. Only after the draft PR is successfully created, begin the actual work. + b. Make a minimal initial commit (e.g., create a `context/CONTEXT_.md` with the task scope). + c. Create a `started` log file in the appropriate task-log directory. + d. Push the branch immediately to make the claim visible. + e. Only after the branch is pushed and the claim is visible, begin the actual work. -3. **Handle race conditions.** After creating your draft PR, re-check for duplicates: +3. **Handle race conditions.** After pushing your claim, re-check for duplicates: ``` - gh pr list --state open --search "" - ``` - If you find another agent's PR for the same task that was created **before** yours, close your PR with `gh pr close ` and skip the task. - -4. **Convert to ready when done.** When the task is complete and verified, mark the draft PR as ready for review: - ``` - gh pr ready + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' ``` + If you find another agent's PR for the same task that was created **before** yours, abandon your branch and skip the task. **Scheduler agents:** Daily and weekly scheduler agents must follow this protocol in addition to their directory-based rotation logic (`docs/agents/task-logs/daily/` and `docs/agents/task-logs/weekly/`). The draft PR check happens _after_ determining the next task but _before_ executing it. See the scheduler prompts for the specific implementation steps. diff --git a/CLAUDE.md b/CLAUDE.md index 692084e9..4318b565 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -458,7 +458,11 @@ This project uses multiple AI coding agents working in parallel: All agents **must** follow the subsystem boundaries and PR discipline rules in `AGENTS.md` Section 12. The key principles: -1. **Check before you start.** Look at open PRs (`gh pr list`) before beginning work. If another agent has an open PR touching the same files, stop and flag the conflict. +1. **Check before you start.** Look at open PRs before beginning work by running: + ``` + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' + ``` + If another agent has an open PR touching the same files, stop and flag the conflict. 2. **One subsystem per PR.** Don't mix unrelated changes. A lint fix and a feature addition are two separate PRs. 3. **`js/app.js` is single-writer.** Only one PR at a time should modify the main orchestrator. 4. **Merge fast, branch short.** Long-lived branches cause exponential merge pain with multiple agents. Keep PRs small and mergeable in one sitting. diff --git a/docs/agents/prompts/META_PROMPTS.md b/docs/agents/prompts/META_PROMPTS.md index 5ac32554..6a52005e 100644 --- a/docs/agents/prompts/META_PROMPTS.md +++ b/docs/agents/prompts/META_PROMPTS.md @@ -14,10 +14,9 @@ before choosing a task — is to run these two commands. Not later. NOW. COMMAND 1 — Check for open daily agent PRs: - gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[daily\]" + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' - If `gh` is not available, use this fallback: - curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[daily\][^"]*"' + Review the output. Any title containing "[daily]" means that agent is OFF LIMITS. COMMAND 2 — Check for in-progress task logs: @@ -63,10 +62,9 @@ before choosing a task — is to run these two commands. Not later. NOW. COMMAND 1 — Check for open weekly agent PRs: - gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[weekly\]" + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' - If `gh` is not available, use this fallback: - curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[weekly\][^"]*"' + Review the output. Any title containing "[weekly]" means that agent is OFF LIMITS. COMMAND 2 — Check for in-progress task logs: diff --git a/docs/agents/prompts/daily-scheduler.md b/docs/agents/prompts/daily-scheduler.md index 00117912..ff4fa509 100644 --- a/docs/agents/prompts/daily-scheduler.md +++ b/docs/agents/prompts/daily-scheduler.md @@ -76,17 +76,12 @@ If you arrived here from the meta prompt and already ran these commands and past Run this command: ```bash -gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[daily\]" +curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' ``` -If `gh` is unavailable, use this fallback: -```bash -curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[daily\][^"]*"' -``` +**Paste the complete raw output.** If the command returns nothing or errors, write: `OUTPUT: (empty — no results)` -**Paste the complete raw output.** If the command returns nothing, write: `OUTPUT: (empty — no results)` - -Every agent name that appears in these PR titles is **OFF LIMITS** — do not select it. +Review the titles in the output. Every agent name that appears in a PR title containing `[daily]` is **OFF LIMITS** — do not select it. ### COMMAND 2 — Check the task log for incomplete runs @@ -114,7 +109,7 @@ or: EXCLUDED AGENTS: (none) ``` -**If Command 1 failed** (network error, API limit, `gh`/`curl` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable. +**If Command 1 failed** (network error, API rate limit, `curl`/`jq` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable. **Do not proceed to Step 1 until you have pasted command outputs and written your exclusion list.** @@ -164,25 +159,19 @@ EXCLUDED AGENTS: (none) You must create a visible claim before doing any work. This claim is a **distributed lock** that prevents agents on other platforms (Claude Code, Codex, Jules) from picking up the same task. -### 2a. Create your working branch and claim via draft PR +### 2a. Create your working branch and push a claim 1. Create your working branch. 2. Make a minimal initial commit (e.g., create a new `context/CONTEXT_.md` with the task scope). -3. Push the branch and open a **draft PR**: - ```bash - gh pr create --draft \ - --title "[daily] : " \ - --body "Claimed by daily scheduler at $(date -u +%Y-%m-%dT%H:%M:%SZ). Work in progress." - ``` -4. Verify the draft PR was created successfully before proceeding. +3. Push the branch immediately to make it visible to other agents. ### 2b. Race condition check -After creating the draft PR, immediately re-check: +After pushing, re-check for competing claims: ```bash -gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt --limit 100 | grep -i "" +curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' ``` -If you see another PR for this agent that was created *before* yours (by a different agent instance), close your PR with `gh pr close ` and go back to Step 1 to select the next agent. +If you see another PR for this agent that was created *before* yours, abandon your branch and go back to Step 1 to select the next agent. ### 2c. Log "started" in the task log immediately @@ -209,7 +198,7 @@ Use the current UTC timestamp. The file content should be: Commit and push this log file to your branch. This `started` entry serves as a secondary lock: other scheduler instances will see it and skip this agent. -**If `gh` is unavailable:** You MUST still create the `started` log file and push it. The log file is your minimum viable claim. +**The `started` log file is your primary claim mechanism.** Push it immediately so other agents can see it. --- @@ -279,7 +268,7 @@ Use the current UTC timestamp (which will be later than the `started` file). The - If the agent prompt file is **empty or missing**, skip it, log the run as `failed` with summary `"Prompt file empty or missing"`, and proceed to the **next agent** in the roster. - If a task **fails mid-execution** (test failures, build errors), log the run as `failed` with a summary describing the failure. Still commit the log file and any partial artifacts. - If the task log directory is **missing**, create it: `mkdir -p docs/agents/task-logs/daily/`. -- If `gh` or `curl` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded. +- If `curl` or `jq` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded. --- @@ -287,9 +276,9 @@ Use the current UTC timestamp (which will be later than the `started` file). The | Layer | Mechanism | Catches | |-------|-----------|---------| -| **Pre-flight gate** | Scan ALL open `[daily]` PRs via `gh`/`curl` | Agents claimed by any platform | +| **Pre-flight gate** | Scan ALL open `[daily]` PRs via `curl` | Agents claimed by any platform | | **Pre-flight gate** | Check task log dir for `started` files | Agents in progress (even without PR) | -| **Step 2a** | Create draft PR as lock | Cross-platform visibility | +| **Step 2a** | Push branch with claim commit | Cross-platform visibility | | **Step 2b** | Race condition re-check | Simultaneous claims | | **Step 2c** | Create `started` log file immediately | Crash recovery — rotation advances | diff --git a/docs/agents/prompts/daily/bitvid-ci-health-agent.md b/docs/agents/prompts/daily/bitvid-ci-health-agent.md index 6e7b7718..59a3b5b6 100644 --- a/docs/agents/prompts/daily/bitvid-ci-health-agent.md +++ b/docs/agents/prompts/daily/bitvid-ci-health-agent.md @@ -77,7 +77,7 @@ WORKFLOW 2) CI health check (evidence gathering) - Gather recent CI run results using one of: - GitHub Actions UI/manual inspection, OR - - GitHub API / `gh` CLI (only if available; do not assume). + - GitHub API via `curl` (e.g., `curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/actions/runs?per_page=20"`). - Identify candidate flakes: - same test fails on one run but passes on another with no relevant code change - failures are timing-related, network-mocking-related, ordering-related diff --git a/docs/agents/prompts/weekly-scheduler.md b/docs/agents/prompts/weekly-scheduler.md index af0349c1..a0b7a718 100644 --- a/docs/agents/prompts/weekly-scheduler.md +++ b/docs/agents/prompts/weekly-scheduler.md @@ -76,17 +76,12 @@ If you arrived here from the meta prompt and already ran these commands and past Run this command: ```bash -gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt,author --limit 100 | grep -i "\[weekly\]" +curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' ``` -If `gh` is unavailable, use this fallback: -```bash -curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | grep -o '"title":"[^"]*\[weekly\][^"]*"' -``` +**Paste the complete raw output.** If the command returns nothing or errors, write: `OUTPUT: (empty — no results)` -**Paste the complete raw output.** If the command returns nothing, write: `OUTPUT: (empty — no results)` - -Every agent name that appears in these PR titles is **OFF LIMITS** — do not select it. +Review the titles in the output. Every agent name that appears in a PR title containing `[weekly]` is **OFF LIMITS** — do not select it. ### COMMAND 2 — Check the task log for incomplete runs @@ -114,7 +109,7 @@ or: EXCLUDED AGENTS: (none) ``` -**If Command 1 failed** (network error, API limit, `gh`/`curl` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable. +**If Command 1 failed** (network error, API rate limit, `curl`/`jq` unavailable): you MUST still check the task log directory (Command 2). Log a warning in your summary that PR-based claim checking was unavailable. **Do not proceed to Step 1 until you have pasted command outputs and written your exclusion list.** @@ -159,25 +154,19 @@ EXCLUDED AGENTS: (none) You must create a visible claim before doing any work. This claim is a **distributed lock** that prevents agents on other platforms (Claude Code, Codex, Jules) from picking up the same task. -### 2a. Create your working branch and claim via draft PR +### 2a. Create your working branch and push a claim 1. Create your working branch. 2. Make a minimal initial commit (e.g., create a new `context/CONTEXT_.md` with the task scope). -3. Push the branch and open a **draft PR**: - ```bash - gh pr create --draft \ - --title "[weekly] : " \ - --body "Claimed by weekly scheduler at $(date -u +%Y-%m-%dT%H:%M:%SZ). Work in progress." - ``` -4. Verify the draft PR was created successfully before proceeding. +3. Push the branch immediately to make it visible to other agents. ### 2b. Race condition check -After creating the draft PR, immediately re-check: +After pushing, re-check for competing claims: ```bash -gh pr list --repo PR0M3TH3AN/bitvid --state open --json number,title,createdAt --limit 100 | grep -i "" +curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' ``` -If you see another PR for this agent that was created *before* yours (by a different agent instance), close your PR with `gh pr close ` and go back to Step 1 to select the next agent. +If you see another PR for this agent that was created *before* yours, abandon your branch and go back to Step 1 to select the next agent. ### 2c. Log "started" in the task log immediately @@ -204,7 +193,7 @@ Use the current UTC timestamp. The file content should be: Commit and push this log file to your branch. This `started` entry serves as a secondary lock: other scheduler instances will see it and skip this agent. -**If `gh` is unavailable:** You MUST still create the `started` log file and push it. The log file is your minimum viable claim. +**The `started` log file is your primary claim mechanism.** Push it immediately so other agents can see it. --- @@ -276,7 +265,7 @@ Use the current UTC timestamp (which will be later than the `started` file). The - If the agent prompt file is **empty or missing**, skip it, log the run as `failed` with summary `"Prompt file empty or missing"`, and proceed to the **next agent** in the roster. - If a task **fails mid-execution** (test failures, build errors), log the run as `failed` with a summary describing the failure. Still commit the log file and any partial artifacts. - If the task log directory is **missing**, create it: `mkdir -p docs/agents/task-logs/weekly/`. -- If `gh` or `curl` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded. +- If `curl` or `jq` is **unavailable or errors**, fall back to log-file-only claiming (the `started` file). Log a warning in your summary that PR-based claim checking was degraded. --- @@ -284,9 +273,9 @@ Use the current UTC timestamp (which will be later than the `started` file). The | Layer | Mechanism | Catches | |-------|-----------|---------| -| **Pre-flight gate** | Scan ALL open `[weekly]` PRs via `gh`/`curl` | Agents claimed by any platform | +| **Pre-flight gate** | Scan ALL open `[weekly]` PRs via `curl` | Agents claimed by any platform | | **Pre-flight gate** | Check task log dir for `started` files | Agents in progress (even without PR) | -| **Step 2a** | Create draft PR as lock | Cross-platform visibility | +| **Step 2a** | Push branch with claim commit | Cross-platform visibility | | **Step 2b** | Race condition re-check | Simultaneous claims | | **Step 2c** | Create `started` log file immediately | Crash recovery — rotation advances | diff --git a/docs/agents/prompts/weekly/bitvid-changelog-agent.md b/docs/agents/prompts/weekly/bitvid-changelog-agent.md index 16d59352..bcb0a1fa 100644 --- a/docs/agents/prompts/weekly/bitvid-changelog-agent.md +++ b/docs/agents/prompts/weekly/bitvid-changelog-agent.md @@ -128,7 +128,7 @@ PR METADATA (PR number, author) — RULES Only include PR number and author if you can **verify** them via: - merge commit messages that include PR numbers, OR - - an available local tool/config that exposes PR metadata (e.g., `gh`) + - the GitHub API via `curl` (e.g., `curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=closed&per_page=50" | jq '[.[] | {number, title, merged_at: .merged_at}]'`) If not verifiable: - omit PR numbers/authors and keep bullets keyed to commit subjects/hashes. diff --git a/docs/agents/prompts/weekly/bitvid-pr-review-agent.md b/docs/agents/prompts/weekly/bitvid-pr-review-agent.md index ed524e3c..d693e2ae 100644 --- a/docs/agents/prompts/weekly/bitvid-pr-review-agent.md +++ b/docs/agents/prompts/weekly/bitvid-pr-review-agent.md @@ -73,21 +73,22 @@ WORKFLOW - security-sensitive boundaries and logging policy - Confirm tooling availability: - `npm` available - - PR checkout method available (`gh` CLI or equivalent) - If `gh` is not available, fall back to manual instructions in the audit log. + - `curl` and `jq` available for GitHub API queries + If `curl` is not available, document that PR enumeration was not possible in the audit log. 2) Enumerate open PRs - Preferred: `curl` command (works without gh auth): ```bash curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq -c '.[] | {number: .number, title: .title, created_at: .created_at, author: .user.login}' ``` - - Alternative: `gh pr list` (if available/configured). - Otherwise: document that PR enumeration was not possible in this environment. 3) For each PR: checkout and run verification Checkout: - - Preferred: `gh pr checkout ` - - Otherwise: fetch the PR branch via git remote refs (only if you can verify). + - Fetch the PR branch via git remote refs: + ```bash + git fetch origin pull//head:pr- && git checkout pr- + ``` Install + checks (verify the script names first): - `npm ci` (preferred) or `npm install` if CI install is not supported diff --git a/docs/agents/prompts/weekly/bitvid-weekly-synthesis-agent.md b/docs/agents/prompts/weekly/bitvid-weekly-synthesis-agent.md index b21c2c34..5d7d7e98 100644 --- a/docs/agents/prompts/weekly/bitvid-weekly-synthesis-agent.md +++ b/docs/agents/prompts/weekly/bitvid-weekly-synthesis-agent.md @@ -76,11 +76,16 @@ WORKFLOW - Gather branch refs: - `git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(refname:short)' refs/heads/ai` -Optional method (only if tooling is available and policy allows): - - Use `gh` CLI or other configured tooling to fetch: - - PR links/status - - issue links/priorities - If not available: do not guess links; report locally-derived identifiers. +Optional method (use curl to query the GitHub API): + - Fetch open PRs: + ``` + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100" | jq '{count: length, titles: [.[].title]}' + ``` + - Fetch recently closed/merged PRs: + ``` + curl -s "https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=closed&per_page=50&sort=updated&direction=desc" | jq '[.[] | {title: .title, merged: .merged_at, number: .number}]' + ``` + If curl is unavailable: do not guess links; report locally-derived identifiers. 3) Normalize items into report sections For each item discovered, capture: diff --git a/scripts/agent/review-open-prs.mjs b/scripts/agent/review-open-prs.mjs index 09b36e5f..e64b0c98 100644 --- a/scripts/agent/review-open-prs.mjs +++ b/scripts/agent/review-open-prs.mjs @@ -13,18 +13,25 @@ function runCommand(command, args = [], options = {}) { } function getOpenPRs() { - console.log('Fetching open PRs...'); + console.log('Fetching open PRs via GitHub API...'); try { - const res = spawnSync('gh', ['pr', 'list', '--json', 'number,headRefName,baseRefName,url'], { encoding: 'utf-8' }); + const res = spawnSync('curl', ['-s', 'https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100'], { encoding: 'utf-8' }); if (res.error) { - console.error('Error fetching PRs (gh CLI not installed?):', res.error.message); + console.error('Error fetching PRs (curl not available?):', res.error.message); return []; } if (res.status !== 0) { console.error('Error fetching PRs:', res.stderr); return []; } - return JSON.parse(res.stdout); + const apiPRs = JSON.parse(res.stdout); + // Map GitHub API response to the shape we need + return apiPRs.map(pr => ({ + number: pr.number, + headRefName: pr.head.ref, + baseRefName: pr.base.ref, + url: pr.html_url + })); } catch (e) { console.error('Exception fetching PRs:', e); return []; @@ -52,15 +59,16 @@ async function main() { for (const pr of openPRs) { console.log(`\n=== Processing PR #${pr.number}: ${pr.url} ===`); try { - // Checkout PR - runCommand('gh', ['pr', 'checkout', pr.number]); + // Checkout PR via git fetch + runCommand('git', ['fetch', 'origin', `pull/${pr.number}/head:pr-${pr.number}`]); + runCommand('git', ['checkout', `pr-${pr.number}`]); // Set Environment Variables const env = { ...process.env, PR_NUMBER: pr.number.toString(), GITHUB_BASE_REF: pr.baseRefName, - // Assuming origin is the base repo or gh pr checkout handled the remote setup. + // Assuming origin is the base repo. // automated-pr-review.mjs handles missing GITHUB_BASE_REPO_URL by defaulting to upstream/origin. }; diff --git a/scripts/automated-pr-review.mjs b/scripts/automated-pr-review.mjs index 3357aa24..84b29adf 100644 --- a/scripts/automated-pr-review.mjs +++ b/scripts/automated-pr-review.mjs @@ -258,16 +258,20 @@ async function main() { const isAll = process.argv.includes('--all'); if (isAll) { - console.log('Fetching all open PRs...'); - // Get list of open PRs - const listCmd = ['pr', 'list', '--state', 'open', '--json', 'number,baseRefName,headRefName']; - const result = spawnSync('gh', listCmd, { encoding: 'utf-8' }); + console.log('Fetching all open PRs via GitHub API...'); + // Get list of open PRs via curl (no gh dependency) + const result = spawnSync('curl', ['-s', 'https://api.github.com/repos/PR0M3TH3AN/bitvid/pulls?state=open&per_page=100'], { encoding: 'utf-8' }); if (result.error || result.status !== 0) { throw new Error(`Failed to list PRs: ${result.stderr || result.error?.message}`); } - const prs = JSON.parse(result.stdout); + const apiPRs = JSON.parse(result.stdout); + const prs = apiPRs.map(pr => ({ + number: pr.number, + baseRefName: pr.base.ref, + headRefName: pr.head.ref + })); console.log(`Found ${prs.length} open PRs.`); let hasGlobalFailures = false; @@ -284,8 +288,9 @@ async function main() { try { console.log(`\n=== Processing PR #${pr.number} ===`); - // Checkout PR - runCommand('gh', ['pr', 'checkout', pr.number]); + // Checkout PR via git fetch + runCommand('git', ['fetch', 'origin', `pull/${pr.number}/head:pr-${pr.number}`]); + runCommand('git', ['checkout', `pr-${pr.number}`]); // Run Review await reviewPR(pr.number, pr.baseRefName); @@ -296,7 +301,7 @@ async function main() { // Continue to next PR } finally { // Clean up or reset if needed? - // Since we use gh pr checkout, we are on a different branch. + // Since we fetch and checkout each PR branch, we are on a different branch. // Next iteration will checkout another branch. } }