skills/iterate/SKILL.md
Iterate on a GitHub pull request — drive it through CI, code review, and QA until it is merge-ready. Poll verification layers with `gh` CLI, diagnose and fix CI failures, address review feedback, retry flaky checks, push fixes, and repeat. The agent is the orchestration loop.
npx skillsauth add openhands/extensions iterateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Iterate on a pull request until it passes all verification layers. You push, poll, fix, and push again — the loop only ends when the PR is green or a blocker requires human help.
No scripts — you are the orchestration loop. Uses only standard gh CLI
commands that work on any GitHub repo.
Requires: gh CLI authenticated with repo access, a PR branch.
Not every repo has all three verification layers. Before entering the loop, check which ones exist. Only poll layers that are actually set up.
gh workflow list --json name --jq '.[].name'
gh pr checks returns results, CI is present..github/workflows/pr-review*.yml in the repo. If it's not there, the repo doesn't have automated PR review. Skip step 3 entirely.A repo might have only CI. Or CI + review. Or all three. Your "all passed" condition is: every present layer is green. Don't block waiting for layers that don't exist.
IMPORTANT: pushing a fix is NOT the end. After every fix+push you MUST re-request review from the review bot (if present) and go back to step 2. The loop only ends when the verifiers pass on your latest SHA. Addressing feedback and pushing a commit is just one iteration — the bot needs to review the new code too.
Do not stop to ask the user whether to continue polling; continue autonomously until a strict stop condition is met or the user interrupts.
Create the PR as a draft. This prevents repo automations (merge workflows, artifact cleanup, auto-merge) from triggering while you're still iterating. You mark it ready only after all verification layers pass.
git push origin HEAD
gh pr create --fill --draft 2>/dev/null || true
gh pr view --json number,url,headRefOid,isDraft --jq '"\(.number) \(.url) \(.headRefOid) draft=\(.isDraft)"'
If the PR already exists and is not a draft, convert it:
gh pr ready --undo
gh pr checks --json name,state,bucket --jq '
{ passed: [.[] | select(.bucket=="pass")] | length,
failed: [.[] | select(.bucket=="fail")] | length,
pending: [.[] | select(.bucket=="pending")] | length }'
To inspect a failure:
SHA=$(gh pr view --json headRefOid --jq .headRefOid)
gh run list --commit "$SHA" --status failure --json databaseId,name,conclusion \
--jq '.[] | "\(.databaseId)\t\(.name)\t\(.conclusion)"'
gh run view <run-id> --log-failed
Skip this step if the repo has no review bot.
gh pr view --json reviews --jq '
[.reviews[] | select(
.authorAssociation == "OWNER" or
.authorAssociation == "MEMBER" or
.authorAssociation == "COLLABORATOR" or
(.author.login | test("openhands|all-hands-bot"; "i"))
)] | last | { state: .state, reviewer: .author.login, body: .body[0:300] }'
APPROVED → review passed.CHANGES_REQUESTED → read the body and inline comments, fix code.COMMENTED → may have actionable suggestions; read and decide.Inline review comments (when changes requested):
gh api "repos/{owner}/{repo}/pulls/{number}/comments" \
--jq '.[] | select(.user.login | test("openhands|all-hands-bot"; "i"))
| { path: .path, line: .line, body: .body[0:200] }'
On a fresh iteration, existing pending review feedback should be checked immediately — not only comments that arrive after monitoring starts. Already-open review comments must not be missed.
Skip this step if the repo has no QA bot.
QA reports are PR issue comments with a status line like Status: PASS.
gh api "repos/{owner}/{repo}/issues/{number}/comments" --paginate \
--jq '[.[] | select(
(.user.login | test("openhands|all-hands-bot"; "i")) and
(.body | test("Status:\\s*(PASS|FAIL|PARTIAL)"; "i"))
)] | last | { author: .user.login, body: .body[0:500], url: .html_url }'
PASS → QA passed.FAIL → read details, fix code.PARTIAL → some passed, some failed; read details.For each present layer, check its status. If a layer is not present in the repo, treat it as passing.
Priority rule: when both review feedback and flaky CI failures are present, prioritize review feedback first. A new commit will retrigger CI, so avoid rerunning flaky checks on the old SHA when you're about to push a review fix.
After fixing, commit, push, AND re-request review:
git add -A
git commit -m "fix: address <CI failure | review feedback | QA failure>"
git push origin HEAD
# Re-request review from the bot so it reviews the new SHA:
gh pr comment --body "Addressed feedback in $(git rev-parse --short HEAD). Ready for another look."
gh api -X POST "repos/{owner}/{repo}/pulls/{number}/requested_reviewers" \
-f 'reviewers[]=all-hands-bot'
Then go back to step 2. You are not done until the bot reviews the new SHA and all present layers pass.
Use gh commands to inspect failed runs before deciding to rerun:
gh run view <run-id> --json jobs,name,workflowName,conclusion,status,url,headSha
gh run view <run-id> --log-failed
Branch-related (fix the code):
Flaky / unrelated (rerun the jobs):
If classification is ambiguous, perform one manual diagnosis attempt (inspect logs) before choosing rerun.
Rerun: gh run rerun <run-id> --failed
Retry budget: at most 3 reruns per SHA. After that, treat as real.
Read references/heuristics.md for a concise decision tree.
The review polling in Step 3 surfaces feedback from trusted sources: human reviewers (OWNER/MEMBER/COLLABORATOR) and approved review bots (openhands, all-hands-bot, etc.). Ignore unrelated bot noise.
Review items come from:
When a comment is actionable and correct:
chore: address PR review feedback (#<n>).When a comment is non-actionable, already addressed, or you disagree: reply briefly explaining why, then resolve the thread. Do not leave threads dangling without a response.
If a review thread is already resolved in GitHub, ignore it unless new unresolved follow-up appears.
Every inline review comment creates a thread. After addressing a comment (or deciding it's non-actionable), you must:
Reply to the thread so the reviewer can see how you addressed it:
gh api "repos/{owner}/{repo}/pulls/{number}/comments" \
-F "body=Fixed — <describe what you changed>" \
-F "in_reply_to=<comment_database_id>"
Use -F (not -f) for in_reply_to so it is sent as a number.
Resolve the thread via GraphQL:
gh api graphql \
-f query='mutation($id: ID!) {
resolveReviewThread(input: { threadId: $id }) {
thread { isResolved }
}
}' \
-f id="<thread_node_id>"
To discover unresolved threads and their IDs:
gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(last: 100) {
nodes {
id
isResolved
path
line
comments(first: 1) {
nodes { databaseId author { login } body }
}
}
}
}
}
}' -f owner="{owner}" -f repo="{repo}" -F pr="{number}" \
--jq '.data.repository.pullRequest.reviewThreads.nodes[]
| select(.isResolved == false)'
Rules:
If the PR is green but blocked on review approval and you've addressed all feedback, you can request another look — but only when the user explicitly asks, or after confirming with them (avoid spamming humans):
Leave a brief PR comment summarizing what changed:
gh pr comment <pr> --body "Addressed the requested changes in <sha>. Could you take another look?"
Do NOT tag humans.
Re-request reviewers via the GitHub API:
gh api -X POST repos/{owner}/{repo}/pulls/{number}/requested_reviewers \
-f reviewers[]=<reviewer>
Prefer requesting review only once per new head SHA. If the API returns an error indicating reviewers are already requested, treat it as non-fatal.
Stop only when:
Not a stop condition:
REVIEW_REQUIRED); continue
polling and surface new review comments without asking for confirmation.Once all present verification layers pass on the current SHA:
gh pr ready
Only do this at the very end, after the loop exits successfully.
Commit message defaults:
fix: CI failure on PR #<n>chore: address PR review feedback (#<n>)Provide concise progress updates during monitoring:
🚀 CI is all green! 33/33 passed. Still watching for review.Final summary should include:
references/verification.mdreferences/heuristics.mdtools
Create an automation that reviews GitHub pull requests when a configurable trigger label is applied. Polls GitHub deterministically, starts one OpenHands review conversation per label event, inspects full repository and PR context, and posts the final review comment back to GitHub.
tools
This skill should be used when the user asks to "monitor a Slack channel", "watch Slack for messages", "create a Slack bot that responds to mentions", "set up an OpenHands Slack integration", "trigger OpenHands from Slack", "respond to @openhands in Slack", or "poll Slack channels for a trigger phrase". Guides the user through creating a cron automation that watches up to 10 Slack channels and starts an OpenHands conversation whenever a configurable trigger phrase is detected.
tools
Reference skill for the OpenHands Software Agent SDK - the Python framework for building AI agents that write software. Use when you need to build agents with the SDK, create custom tools, configure LLMs, manage conversations, delegate to sub-agents, or deploy agents locally or remotely.
tools
This skill should be used when the user asks to "monitor a GitHub repository", "watch GitHub for issues or PRs", "respond to @OpenHands mentions on GitHub", "set up an OpenHands GitHub integration", "trigger OpenHands from a GitHub comment", or "poll a GitHub repo for a trigger phrase". Guides the user through creating a cron automation that polls a single repository and starts an OpenHands conversation whenever a configurable trigger phrase is detected in an issue or PR comment.