一键导入
dev-review-pr
Handle automated PR review feedback and merge when ready
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Handle automated PR review feedback and merge when ready
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Add PBR texture loading with separate roughness/metallic support to an SDL GPU project using forge_scene.h
Add Cook-Torrance PBR shading with GGX, Schlick-GGX, and Schlick Fresnel to an SDL GPU project alongside forge_scene.h
Add instanced grass rendering with segmented blades, wind animation, LOD density rings, and terrain LOD with geomorphing to an SDL GPU project
Add procedural noise texture generation to the asset pipeline — C tool, Python plugin, web UI with live preview
Add an asset pipeline lesson — hybrid Python + C track for asset processing, procedural geometry, and web frontend
Add an audio lesson — sound playback, mixing, spatial audio, DSP effects, with SDL GPU scenes and forge UI
| name | dev-review-pr |
| description | Handle automated PR review feedback and merge when ready |
| argument-hint | [pr-number] |
| disable-model-invocation | false |
Check GitHub Actions status, review feedback from automated reviewers (Code Rabbit, Claude), implement or respond to feedback, and merge the PR when all feedback is resolved.
MANDATORY: Run
/dev-local-reviewbefore every commit and push. This applies to step 5 (commit and push fixes) and any other commit made during this workflow. Do NOT push code that has not passed a local review. Skipping this step wastes a GitHub review round on issues that could have been caught locally for free.
The user provides:
Use gh pr checks <pr-number> to see if automated reviews are complete.
Important: This command returns exit code 8 if any checks are pending, and
outputs them to stderr. Handle both stdout and stderr to capture all check
statuses. Output format: check-name status duration url
If any checks are still running (pending):
If checks failed:
If all checks passed:
If the "Markdown Lint" check failed:
Run locally to see errors:
npx markdownlint-cli2 "**/*.md"
Attempt auto-fix:
npx markdownlint-cli2 --fix "**/*.md"
Manually fix remaining errors (especially MD040 - missing language tags)
Verify all errors resolved:
npx markdownlint-cli2 "**/*.md"
Commit and push fixes:
git add <fixed-files>
git commit -m "Fix markdown linting errors
Co-Authored-By: Claude <noreply@anthropic.com>"
git push
Exit and wait for checks to re-run — user should invoke /dev-review-pr again after checks pass
CodeRabbit is configured to auto-pause after the first reviewed commit
(reviews.auto_review.auto_pause_after_reviewed_commits: 1 in .coderabbit.yaml). This means
after every push, CodeRabbit reviews once and then pauses. The "Reviews paused"
banner in the PR comment is normal and expected — it does NOT mean something
went wrong or that the review is missing.
Key insight: CodeRabbit completes its review before pausing. The review comments and review body are already available.
How to check:
Look at the CodeRabbit check status from step 1:
pass — the review is done. Proceed directly to
step 2 to fetch the review comments. Ignore the "Reviews paused"
banner — it just means future commits won't be auto-reviewed.pending or no CodeRabbit check yet — the review
hasn't started or is still running. Exit and ask the user to re-run later.After implementing feedback and pushing fixes (step 5):
Since auto-pause is on, CodeRabbit will NOT automatically review the new commit. Post a single comment to request a fresh review:
gh pr comment <pr-number> --body "@coderabbitai review"
Do NOT post @coderabbitai resume — we want it to stay paused
after each review to avoid review thrashing from rapid commits.
If CodeRabbit shows "Currently processing new changes":
After CodeRabbit re-reviews a fix commit, it sometimes finds nothing new to
flag. When this happens, CodeRabbit does not post an APPROVED review.
Instead, it posts an issue comment (not a review comment) containing:
No actionable comments were generated in the recent review.
The review state from step 6 may still show CHANGES_REQUESTED or
COMMENTED from a previous round — that's stale and misleading.
How to detect:
# Get the latest "no actionable comments" timestamp
NO_ACTION_TS=$(gh api repos/{owner}/{repo}/issues/{pr-number}/comments --paginate \
| jq -r -s '(add // []) | map(select(.user.login == "coderabbitai[bot]"
and (.body | contains("No actionable comments"))))
| sort_by(.created_at) | last | .created_at // empty')
# Get the latest CHANGES_REQUESTED or COMMENTED review timestamp
LAST_REVIEW_TS=$(gh api repos/{owner}/{repo}/pulls/{pr-number}/reviews --paginate \
| jq -r -s '(add // []) | map(select(.user.login == "coderabbitai[bot]"
and (.state == "CHANGES_REQUESTED" or .state == "COMMENTED")))
| sort_by(.submitted_at) | last | .submitted_at // empty')
# Compare timestamps (lexicographic works for ISO 8601 dates)
if [[ -z "$NO_ACTION_TS" ]]; then
echo "No 'no actionable comments' signal found"
elif [[ -z "$LAST_REVIEW_TS" || "$NO_ACTION_TS" > "$LAST_REVIEW_TS" ]]; then
echo "Clean re-review detected — proceeding to step 6b"
else
echo "Review feedback still pending"
fi
If the "no actionable comments" comment is newer than the last review with feedback, CodeRabbit is satisfied.
When detected, skip straight to step 6b (pre-merge branch update and resolve). Do not loop back to step 2 looking for feedback that does not exist.
Important: Inline review comments (the "tasks" users see in the GitHub UI)
are NOT returned by gh pr view --json comments. You must use the API directly:
gh api repos/{owner}/{repo}/pulls/{pr-number}/comments
This returns an array of review comment objects with:
path — file pathline / start_line — line numbersbody — comment body (markdown, may include severity, suggestions)html_url — link to view the conversationuser.login — reviewer (e.g., "coderabbitai[bot]", "claude-code[bot]")CodeRabbit comment format:
_⚠️ Potential issue_ | _🟠 Major_, _🟡 Minor_, or other markers<details><summary>Suggested fix</summary> blocks<!-- suggestion_start --> markersParse and categorize feedback by:
Present ALL comments to the user sorted by severity (Major → Minor → Nitpick) so security/critical issues are addressed first.
CRITICAL — this is the #1 cause of missed feedback. Do NOT filter comments
by original_commit_id to find "new" comments. CodeRabbit posts comments
against various commit SHAs depending on diff positioning, and a comment on
commit A may actually be new feedback triggered by commit B's review.
The correct approach: use the review ID, not the commit ID.
First, fetch all reviews and find the latest CodeRabbit review:
REVIEW_ID=$(gh api --paginate repos/{owner}/{repo}/pulls/{pr-number}/reviews \
| jq -s 'add | map(select(.user.login == "coderabbitai[bot]"))
| sort_by(.submitted_at) | last | .id')
echo "Latest CodeRabbit review: $REVIEW_ID"
Then, fetch comments and match them to reviews by pull_request_review_id:
gh api --paginate repos/{owner}/{repo}/pulls/{pr-number}/comments \
| jq -s --argjson rid "$REVIEW_ID" \
'add | map(select(.pull_request_review_id == $rid))
| map({id, path, line, body: .body[:200]})'
Comments from the latest review are the new comments for this round. Comments from earlier reviews that were NOT auto-resolved are carried forward and still need action.
Why original_commit_id filtering is wrong:
original_commit_id
valuesAlternative quick approach: If you don't want to join on review IDs, simply fetch ALL CodeRabbit comments, exclude those that have a human reply dismissing them (user said "out of scope"), and present the rest grouped by file. Let the user decide which are new vs. already handled.
Critical: CodeRabbit embeds additional feedback directly in review bodies — not as separate inline comment threads. These appear in collapsible sections titled "Duplicate comments" and "Nitpick comments" within the review. They do NOT create their own threads, so they will be missed if you only fetch inline comments.
Fetch review bodies from CodeRabbit:
gh api --paginate repos/{owner}/{repo}/pulls/{pr-number}/reviews \
| jq -s 'add
| map(select(.user.login == "coderabbitai[bot]"))
| sort_by(.submitted_at)
| map({id: .id, state: .state, body: .body, date: .submitted_at})'
Look for these sections in the review body:
♻️ Duplicate comments — Issues raised previously that CodeRabbit still
considers unresolved after re-review. These are NOT resolved just because
the original thread was addressed — CodeRabbit is saying the fix was
incomplete or the issue persists. Treat these as active feedback.🧹 Nitpick comments — Low-severity suggestions that didn't warrant a
blocking review thread. Still present them to the user.For each duplicate/nitpick comment found:
When a review body contains duplicate comments but no new inline threads:
COMMENTED (not CHANGES_REQUESTED)Sort comments by severity: Major → Minor → Nitpick/Style, so critical issues (especially security) are addressed first.
Show the user the raw feedback list, then group comments into themes. A theme is a class of issue that may have multiple instances across the codebase. Examples:
| Raw comments | Theme |
|---|---|
| "Docs say circles but widget draws rectangles" × 3 files | Doc/code mismatch: shape description |
| "No error check after fclose" in writer A | Unchecked I/O pattern |
| "No error check after fclose" in writer B | (same theme) |
| "Test only checks return value, not side effects" × 4 tests | Weak test assertions |
| "Division by zero if rect width is 0" | Missing zero-guard pattern |
| "fabsf() should be SDL_fabsf()" × 5 files | Bare C stdlib calls (portability) |
## PR Review Feedback Summary
### Pending conversations: X (grouped into Y themes)
**Theme 1: [description] (N comments, severity)**
- file.c:123 — [specific instance]
- file.c:456 — [specific instance]
- README.md:78 — [specific instance]
**Theme 2: [description] (N comments, severity)**
- ...
### Resolved conversations: Z
If no pending conversations, skip to step 6.
This is the step that prevents 10+ round feedback loops. Before touching any code, build a comprehensive plan for each theme. The goal: fix every instance in one pass so CodeRabbit sees zero duplicates on re-review.
For each theme, before writing any fix, spawn an analysis agent
(subagent_type: "Explore") to answer:
Where else does this pattern appear? Search all files changed in this PR for the same class of issue — not just the line CodeRabbit flagged. Use grep/glob to find every instance.
Examples of what "same pattern" means:
.md,
.h, and .c files touched by this PRfclose call in
the file and check if any are uncheckedfabsf, sinf, cosf, sqrtf, memset, memcpy,
strcmp, strlen, malloc, free) across every .c and .h file
in the PR — this is a critical cross-platform portability issueWhat documentation describes this code? Identify every README, API doc, header comment, and inline comment that references the behavior being changed. These MUST be updated when the code changes.
What tests cover this code? Identify existing tests. If the fix changes behavior, those tests must be updated. If no test exists, one must be written.
Why did we get this wrong? Understanding the root cause prevents adjacent bugs:
For each theme, produce a checklist:
Theme: "Radio button shape — docs say circles, code draws rectangles"
Root cause: Copy-pasted checkbox description without adapting for radio buttons
Code fixes:
[ ] common/ui/forge_ui.h:234 — change "circle" to "rectangle" in header doc
[ ] common/ui/README.md:89 — update radio button description
[ ] lessons/ui/15-dev-ui/README.md:156 — fix shape description
[ ] OR: actually make radio buttons round in forge_ui_ctx_radio()
Doc sync:
[ ] Verify all 3 doc locations match after fix
[ ] Check if any diagram shows radio buttons (update if so)
Tests:
[ ] Add test asserting radio button geometry is rectangular (or round)
[ ] Verify existing radio button tests still pass
Grep verification:
[ ] grep -r "circle" across all files in this PR — zero false matches remain
Present the full plan to the user before executing. The user may spot things the analysis missed or may prefer a different approach (e.g. "just make it round" vs "fix all the docs").
For each theme that the user approves, spawn agents in parallel to handle the three concerns simultaneously:
Code agent (subagent_type: "coder", run_in_background: true) —
Fix the code issue across ALL instances found in the impact analysis.
Not just the line CodeRabbit pointed at — every instance of the pattern.
Test agent (subagent_type: "tester", run_in_background: true) —
Write or update tests for the fix. For library changes in common/,
this is mandatory. The test should:
Doc agent (subagent_type: "coder", run_in_background: true) —
Update ALL documentation that describes the changed behavior:
common/*/README.md.h filesAll three agents work from the same verification plan. Give each agent the full plan so they understand the scope, but assign them their specific section (code, tests, docs).
After all agents complete, review their changes together. Check:
After all theme fixes are applied, run a final verification:
Grep check: For each theme, re-run the grep queries from the impact analysis. Every instance should be resolved. If any remain, fix them before proceeding.
Build check: Build the project to catch compile errors.
cmake --build build 2>&1 | tail -20
Test check: Run relevant tests to catch regressions.
ctest --test-dir build -R <relevant-test> # C tests
uv run pytest tests/pipeline/ -v # Python tests (if applicable)
Doc consistency check: For each file pair (code + doc), verify the doc accurately describes the current code behavior. Read both files and confirm they agree.
Markdown lint:
npx markdownlint-cli2 "**/*.md"
Python lint (if Python files changed):
uv run ruff check && uv run ruff format --check
If any check fails, fix the issue before proceeding. Do NOT push code that fails tests or lint.
STOP. You MUST run
/dev-local-reviewhere. This is not optional. If you skip this step, the push will contain avoidable issues that waste a GitHub review round. No exceptions.
After all cross-verification checks pass, run /dev-local-review to catch
any issues the theme-based fixes may have introduced. This is a mandatory
gate — do NOT proceed to step 5 (commit and push) until the local review
completes with zero findings.
This prevents burning a GitHub review round on issues that could have been
caught locally for free. The local review loop follows its own strict rules
(see /dev-local-review skill) — it must run until zero findings or until
the user explicitly agrees to stop.
After ALL themes are resolved and ALL checks pass:
Stage all changed files by explicit name (never git add -A):
git add <file1> <file2> ...
Create a single commit summarizing all fixes:
git commit -m "$(cat <<'EOF'
Address PR feedback: [summary]
Themes addressed:
- [Theme 1]: [what was fixed, how many instances]
- [Theme 2]: [what was fixed, how many instances]
Verification:
- All instances found via grep — none remaining
- Tests added/updated for each fix
- Documentation synced with code changes
- Build and tests pass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
EOF
)"
Push once to the PR branch:
git push
Request CodeRabbit re-review:
gh pr comment <pr-number> --body "@coderabbitai review"
Do NOT use @coderabbitai resume — we want auto-pause to stay active.
Exit with: "Changes pushed. Run this skill again after checks complete."
On next run after CodeRabbit re-reviews:
If the same theme has appeared as a duplicate comment in 3 or more review rounds, the point-fix approach has failed. Escalate:
Stop fixing symptoms. Read the entire function or module that keeps getting flagged. Understand the design, not just the flagged line.
Identify the root cause. Common patterns:
Propose a design fix to the user. This may be a small refactor — extract a shared constant, change a type at its declaration, unify two code paths. Present it as: "This has been flagged N times because [root cause]. I recommend [design fix] instead of patching individual lines."
Implement the design fix with full test coverage and doc updates. This replaces the point-fix cycle with a single structural change.
Check two things: the PR-level review decision AND individual reviews.
# PR-level decision (may lag behind individual reviews)
gh pr view <pr-number> --json reviewDecision,statusCheckRollup
# Individual reviews — check the LATEST review from each reviewer
gh api --paginate repos/{owner}/{repo}/pulls/{pr-number}/reviews \
| jq -s 'add | [.[] | {user: .user.login, state: .state, date: .submitted_at}]
| group_by(.user)
| map(sort_by(.date) | last)'
Important: reviewDecision can show CHANGES_REQUESTED even after a
reviewer has submitted a newer APPROVED review. This happens because GitHub
tracks the earliest unresolved review, not the latest. Always check the
latest review from each reviewer — if their most recent review is APPROVED,
the PR is approved regardless of what reviewDecision says.
Verify:
APPROVEDIf the latest review is CHANGES_REQUESTED:
If the latest review is COMMENTED:
COMMENTED is not an approval — do NOT proceed to merge.If the latest review is APPROVED:
When the latest review from a reviewer is COMMENTED, it means they left
non-blocking feedback but did not approve. This typically happens when:
Workflow:
Read every comment in the COMMENTED review (inline threads, review
body nitpicks, and duplicate comments). Present each to the user with
context.
For each comment, ask the user: implement the suggestion, or skip it?
If the user wants to implement: Fix the issue, commit, push, and
request re-review (@coderabbitai review). Exit and wait for the next
review round.
If the user wants to skip: Run /dev-resolve-feedback to ask
CodeRabbit to verify each thread individually and resolve if fixed.
NEVER post @coderabbitai resolve as a general PR comment. That
force-resolves all threads — including ones with genuinely unaddressed
feedback. Instead, /dev-resolve-feedback replies to each thread
individually, letting CodeRabbit decide per-thread whether to resolve.
CRITICAL: No commits after resolve. Any new commit on the branch — your own code, a merge from main, a rebase — dismisses the approval that CodeRabbit grants when it resolves threads. This forces you to start the cycle over.
Also do NOT request another review (@coderabbitai review) — that
triggers a new feedback round.
Update the branch before requesting resolve. Any commit after resolve — including a merge from main — dismisses the approval. So update the branch first, then resolve, then merge the PR.
Practical workflow:
a. Push all local changes first (if any). Wait for checks to pass.
b. Check if the branch is behind main:
gh pr view <pr-number> --json mergeStateStatus \
--jq '.mergeStateStatus'
c. If BEHIND, merge main and push before requesting resolve:
git fetch origin main
git merge origin/main --no-edit
git push
Wait for checks to pass on the updated branch. CodeRabbit's auto-pause prevents the main merge from triggering new review feedback.
d. Once the branch is up to date and checks pass, run
/dev-resolve-feedback to ask CodeRabbit to verify and resolve
each thread individually.
e. After CodeRabbit resolves the threads and posts an APPROVED
review, merge immediately:
gh pr merge <pr-number> --squash --delete-branch
No --admin needed because the branch is already up to date and
no commits were made after the resolve.
Fallback — if you already resolved before updating the branch:
If the approval was dismissed by a main merge, use --admin to merge:
gh pr merge <pr-number> --squash --delete-branch --admin
Only use --admin when: the nitpick was intentionally skipped
with user confirmation, all checks are green, and the only reason
for the missing approval is the main merge dismissing it. Present
this to the user for confirmation.
When all feedback is addressed (either via fixes or the "no actionable comments" signal from step 1.7a), prepare the branch for merge:
Check if the branch is behind main:
gh pr view <pr-number> --json mergeStateStatus \
--jq '.mergeStateStatus'
If BEHIND, update the branch first:
git fetch origin main
git merge origin/main --no-edit
git push
Wait for all checks to pass on the updated branch. CodeRabbit's auto-pause prevents the main merge from triggering new review feedback.
Once the branch is up to date and checks pass, run
/dev-resolve-feedback to ask CodeRabbit to verify each unresolved
thread individually and resolve if the issue is fixed.
NEVER post @coderabbitai resolve as a general PR comment. That
force-resolves all threads — including ones with genuinely unaddressed
feedback. The per-thread approach lets CodeRabbit decide independently
whether each issue was actually fixed.
After CodeRabbit resolves the threads and posts an APPROVED
review, proceed to step 7.
Why this order matters: Any commit after CodeRabbit resolves threads
(including a merge from main) dismisses the approval. By merging main
before resolving, the approval sticks and you can merge the PR normally
without --admin.
Ask user for confirmation:
✅ All feedback resolved, all checks passing, PR approved.
Ready to merge PR #X: "Title"
Branch: lesson-03-uniforms-and-motion → main
Merge method:
1. Squash and merge (recommended for lessons)
2. Merge commit
3. Rebase and merge
After user confirmation:
gh pr merge <pr-number> --squash --delete-branch
Show success message with merged commit SHA.
# Check PR status (exit code 8 if any checks are pending)
gh pr checks <pr-number>
# Get inline review comments (the "tasks" shown in GitHub UI)
# IMPORTANT: This is the correct way to fetch review feedback
gh api repos/{owner}/{repo}/pulls/{pr-number}/comments
# View PR details (does NOT include inline review comments)
gh pr view <pr-number> --json reviewDecision,statusCheckRollup
# View specific workflow run
gh run view <run-id>
# Reply to a specific review comment thread (CORRECT - creates nested reply)
# Use this to respond to CodeRabbit/Claude feedback on specific lines
# IMPORTANT: Must include PR number in path - repos/{owner}/{repo}/pulls/{pr-number}/comments/{comment-id}/replies
# Example: gh api repos/RosyGameStudio/forge-gpu/pulls/1/comments/2807683534/replies
gh api repos/{owner}/{repo}/pulls/{pr-number}/comments/{comment-id}/replies \
-f body="response text"
# Post a general PR comment (AVOID - doesn't thread properly with review feedback)
# This creates a standalone comment, not a reply to a review thread
gh pr comment <pr-number> --body "response text"
# Ask CodeRabbit to verify/resolve after implementing a fix (reply to the comment thread)
# IMPORTANT: Must include PR number in the path (not just comment ID)
gh api repos/{owner}/{repo}/pulls/{pr-number}/comments/{comment-id}/replies \
-f body="@coderabbitai I've implemented your suggestion in commit ABC123. Can you verify and resolve this conversation?"
# Resolve a review thread manually
# Note: GitHub CLI doesn't directly support this - may need gh api or manual UI resolution
# Usually let CodeRabbit auto-resolve when it re-reviews
# Merge PR
gh pr merge <pr-number> --squash --delete-branch
Fix-the-line-not-the-pattern is the #1 cause of 10+ round review cycles. It looks like this:
The correct response to step 1 is: grep for "circle" across every file in the PR, fix all of them, update all docs, add a test, and push once.
Every piece of feedback is a signal about a class of issue, not just a single line. Treat it that way.
gh api repos/{owner}/{repo}/pulls/{pr-number}/commentsreviews.auto_review.auto_pause_after_reviewed_commits: 1). The "Reviews paused" banner is normal — it means CodeRabbit already completed its review and is waiting. Do NOT post @coderabbitai resume — we want it paused to prevent review thrashing. After pushing fixes, request a single fresh review with @coderabbitai review. If CodeRabbit shows "Currently processing new changes", wait for it to finish before fetching comments.♻️ Duplicate comments and 🧹 Nitpick comments sections and treat them as active feedback requiring action.gh api repos/{owner}/{repo}/pulls/{pr-number}/comments/{comment-id}/replies to reply to specific review comments. This keeps conversations threaded. Do NOT use gh pr comment for replies—it creates unthreaded general comments.
repos/{owner}/{repo}/pulls/comments/{id}/replies won't work—must be pulls/{pr-number}/comments/{id}/replies)common/, you MUST spawn separate agents for code, tests, and docs.
A single agent making all changes will miss the cross-cutting concerns
that cause duplicate comments.common/, tests are non-negotiable.COMMENTED or CHANGES_REQUESTED from the
previous round — do not wait for an APPROVED review that will never
come. Detect this comment (step 1.7a) and proceed to step 6b.@coderabbitai resolve as a general PR comment. This
force-resolves all threads, including ones with genuinely unaddressed
feedback. Always use /dev-resolve-feedback instead, which replies to
each thread individually and lets CodeRabbit decide per-thread whether
the issue was actually fixed./dev-resolve-feedback (step 6b). This avoids
the catch-22 of needing --admin to merge.gh CLI is not installed or not authenticated, provide clear setup instructionsRunning dev-review-pr for PR #224...
✓ All GitHub Actions checks passed
✓ Found 6 pending conversations
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Grouped into 3 themes:
Theme 1: Doc/code mismatch — radio button shape (3 comments, Minor)
- common/ui/forge_ui.h:234 — header says "circle"
- common/ui/README.md:89 — API docs say "circular"
- lessons/ui/15-dev-ui/README.md:156 — lesson says "round"
Theme 2: Unchecked division by zero (2 comments, Major)
- forge_ui.h:1200 — sv_rect.w can be 0
- forge_ui.h:1240 — hue_rect.w can be 0
Theme 3: Weak test assertions (1 comment, Minor)
- test_ui_controls.c:89 — only checks return, not side effects
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Impact analysis for Theme 1:
grep found 5 additional instances of "circle/circular/round"
in radio button context across the PR files:
- forge_ui.h line 198 (function doc)
- forge_ui.h line 892 (inline comment)
- README.md line 34 (widget table)
- README.md line 201 (API section)
- SKILL.md line 45 (skill description)
Root cause: checkbox description was copy-pasted for radio
buttons without adapting the shape description.
Verification plan:
Code: fix all 8 instances (3 flagged + 5 found)
Docs: verify all docs agree after fix
Tests: add assertion for radio button draw data
Grep: re-run "circle" search — expect 0 matches
[User approves plan]
[Spawns code + test + doc agents in parallel]
[All agents complete]
[Cross-verification: grep confirms 0 remaining, tests pass]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
All 3 themes resolved. Building... ✓ Tests... ✓ Lint... ✓
✓ Committed: "Address PR feedback: fix radio shape docs (8 instances),
add zero-guards to color picker (3 divisions), strengthen test assertions
(6 widget tests)"
✓ Pushed (single push)
✓ Requested CodeRabbit re-review
Run this skill again after checks complete.