English | 日本語
An AI review-fix loop for GitHub pull requests. LoopPilot asks Codex to review a PR, lets Claude fix the findings, runs your checks, and repeats until the PR is clean.
LoopPilot runs as GitHub Actions reusable workflows. You do not host a service, run a server, or install anything in production. The recommended setup path is the gh looppilot CLI.
The GitHub Marketplace listing is a discoverability front door, not the way to run LoopPilot. LoopPilot is event-driven and runs as reusable workflows, so it is not a step you add to a job. Do not write
uses: team-yubune/loop-pilot@v1in a job — that root action only prints setup guidance and exits. Install with thegh looppilotCLI (below), or use the manual reusable-workflow callers (team-yubune/loop-pilot/.github/workflows/{init,loop}.yml@v1).
# 1. Install once. Requires Node >= 20 and an authenticated GitHub CLI.
gh extension install team-yubune/gh-looppilot
# 2. Run inside the repository where you want LoopPilot.
cd path/to/your-repo
gh looppilot init
# 3. Check the setup after adding the required manual secrets.
gh looppilot doctorAfter gh looppilot init, complete the two manual steps below: connect the Codex GitHub App and add one Claude credential. Then open a PR and add the loop-pilot label.
- A PR is opened with the
loop-pilotlabel. - LoopPilot posts
@codex review. - Codex reviews the PR and reports findings.
- Claude fixes the findings through
anthropics/claude-code-action. - LoopPilot runs
CHECK_COMMAND, checks scope and secrets, commits the fix, and asks Codex to review again. - The loop ends as
donewhen findings are gone, orstoppedwhen a guard, limit, or validation failure needs human attention.
Safety guards are built in: fork PRs are ignored, .github/ is locked, changes are scope-checked, secrets are scanned, and every fix must pass your configured validation command.
| Requirement | Why it matters |
|---|---|
| GitHub Actions enabled | LoopPilot runs entirely in Actions. |
| Same-repository PR branches | Fork PRs are intentionally blocked for security. |
| ChatGPT Codex GitHub integration | @codex review must trigger Codex in the target repo. |
| One Claude credential | Set ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN. |
| A validation command | Default is npm run check; customize with CHECK_COMMAND. |
gh looppilot init is the preferred installer. It:
- detects your toolchain and suggests
CHECK_COMMAND - creates
.github/workflows/looppilot-init.yml - creates
.github/workflows/looppilot-loop.yml - creates the
loop-pilotgate label - prints the manual steps that GitHub does not allow the CLI to complete
- runs a pre-flight check
Use gh looppilot doctor any time to re-check configuration. Add --json for machine-readable output.
Open ChatGPT Codex, connect GitHub, and grant the Codex GitHub App access to the target repository. Confirm that chatgpt-codex-connector[bot] can act on the repo.
Without this, LoopPilot can post @codex review, but no Codex review will arrive.
For a first test PR, one Claude credential is enough:
gh secret set ANTHROPIC_API_KEY --repo <owner>/<repo>
# or:
gh secret set CLAUDE_CODE_OAUTH_TOKEN --repo <owner>/<repo>For production, add the two GitHub PATs shown below.
| Secret | Required? | Purpose |
|---|---|---|
ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN |
Required, exactly one | Lets claude-code-action perform fixes. |
CODEX_REVIEW_REQUEST_TOKEN |
Required | Posts @codex review as a Codex-integrated user. |
LOOPPILOT_PUSH_TOKEN |
Required | Pushes repair commits as a non-GITHUB_TOKEN actor so required checks re-run. |
GITHUB_TOKEN |
Automatic | GitHub Actions injects it. You do not create or store it. |
CODEX_REVIEW_REQUEST_TOKEN and LOOPPILOT_PUSH_TOKEN are GitHub fine-grained personal access tokens (PATs). If you have never made one, follow GitHub's official guide first: Creating a fine-grained personal access token.
For each token:
-
Open Settings → Developer settings → Fine-grained tokens → Generate new token (or use the link above).
-
Under Repository access, choose Only select repositories and pick the target repository only.
-
Under Permissions → Repository permissions, grant exactly the scopes for that token:
Token Repository permissions CODEX_REVIEW_REQUEST_TOKENPull requests: Read and write,Issues: Read and writeLOOPPILOT_PUSH_TOKENContents: Read and write -
Generate the token, copy it, and store it as a repository secret:
gh secret set CODEX_REVIEW_REQUEST_TOKEN --repo <owner>/<repo> gh secret set LOOPPILOT_PUSH_TOKEN --repo <owner>/<repo>
Notes:
- Issue
CODEX_REVIEW_REQUEST_TOKENfrom a user whose GitHub account is connected to Codex, otherwise@codex reviewwill not start a review. LOOPPILOT_PUSH_TOKENmust belong to an actor other thanGITHUB_TOKEN(a dedicated machine user or GitHub App token is recommended) so that its pushes re-trigger required checks.- Keep the two tokens separate — do not give the review token push access.
Token scopes and security details are in docs/operations/security.md.
- Run
gh looppilot doctorand confirmerror = 0. - Open a PR from a branch in the same repository.
- Add the
loop-pilotlabel, unless you enabled full-auto mode. - Watch for the LoopPilot status comment and the first
@codex review. - When the loop finishes, check the final state:
doneorstopped.
Set these as GitHub Actions repository variables in the target repository.
| Variable | Default | Use when |
|---|---|---|
CHECK_COMMAND |
npm run check |
Your validation command is not npm run check. |
BUILD_COMMAND |
empty | You commit generated files such as dist/ and need them refreshed before commit. |
LOOPPILOT_LABEL |
loop-pilot |
You want a different gate label. |
LOOPPILOT_FULL_AUTO |
false |
You want LoopPilot on every non-fork PR. |
MAX_REVIEW_ITERATIONS |
20 |
You want a lower or higher loop limit. |
LOOPPILOT_SEVERITY_THRESHOLD |
P3 |
You want to skip lower-severity Codex findings. |
LOOPPILOT_AUTO_MERGE |
false |
You want LoopPilot to squash-merge when it reaches done / no_findings. |
LOOPPILOT_BLOCK_PATHS |
empty | You want to block extra paths from auto-fix changes. |
LOOPPILOT_SCOPE_MAX_FILES |
20 |
A faithful repair legitimately needs to touch more files than the default. |
LOOPPILOT_SCOPE_MAX_LINES |
1000 |
A faithful repair legitimately needs more changed lines than the default. |
CODEX_ACK_TIMEOUT_SECONDS |
90 |
Tune how long LoopPilot waits for Codex to acknowledge an @codex review (👀) before re-requesting; 0 disables the ACK watchdog. |
CODEX_ACK_MAX_REPOSTS |
2 |
Tune how many times LoopPilot re-requests @codex review when Codex does not respond, before stopping with codex_request_failed. |
CLAUDE_CODE_MAX_TURNS |
40 |
Tune the max agent turns per fix attempt, forwarded to claude-code-action's --max-turns. |
All inputs are documented in loop/action.yml and init/action.yml.
Use this only when the CLI is not available.
Show the two workflow callers
name: LoopPilot Init
on:
pull_request:
types: [opened, ready_for_review, labeled]
jobs:
init:
permissions:
contents: read
pull-requests: write
issues: write
uses: team-yubune/loop-pilot/.github/workflows/init.yml@v1
secrets:
CODEX_REVIEW_REQUEST_TOKEN: ${{ secrets.CODEX_REVIEW_REQUEST_TOKEN }}name: LoopPilot Loop
on:
issue_comment:
types: [created]
pull_request_review:
types: [submitted]
jobs:
loop:
permissions:
contents: write
pull-requests: write
issues: write
actions: read
uses: team-yubune/loop-pilot/.github/workflows/loop.yml@v1
secrets:
CODEX_REVIEW_REQUEST_TOKEN: ${{ secrets.CODEX_REVIEW_REQUEST_TOKEN }}
LOOPPILOT_PUSH_TOKEN: ${{ secrets.LOOPPILOT_PUSH_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
with:
language: node # node | python | go | rust | noneCreate the gate label unless you enable full-auto mode:
gh label create loop-pilot \
--color BFD4F2 \
--description "Run LoopPilot on this PR"- Documentation index
- System overview
- Flow and state
- Security and token permissions
- Stop and recovery
- Scope policy
- Release procedure
npm ci
npm run check
npm run bundleCI checks typecheck, tests, and dist/ drift. After changing src/, run npm run bundle and commit the regenerated dist/ files.