Repository navigation
ci: ai-triage v2 — fan-out commands, always-on with budget, config modes (#289) #292
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
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| --- | ||
| description: Run the full pre-PR gate (pnpm all) and self-review the diff against the component checklist | ||
| allowed-tools: Read, Bash(pnpm all), Bash(pnpm run:*), Bash(pnpm exec:*), Bash(git status:*), Bash(git diff:*), Bash(git log:*) | ||
| --- | ||
|
|
||
| # /pre-pr — gate + self-review before opening a PR | ||
|
|
||
| 1. Run `pnpm all` (build, typecheck, test+coverage, bundle:stats, lint, | ||
| format:check, storybook build). If it fails, report the failing task and | ||
| stop — fix before reviewing. | ||
| 2. Read the working diff (`git status`, `git diff main...HEAD` plus any | ||
| uncommitted changes). If the diff touches `bulma-ui/src` components, | ||
| stories, SCSS, or `skills/`, review it against the checklist in | ||
| `CONTRIBUTING-COMPONENTS.md` (repo root — Read it), focusing on what CI | ||
| can NOT catch: | ||
| - prop-level changes without matching story/docs/skills updates | ||
| - missing listing surfaces (guide page section, homepage card — step 2) | ||
| - skills sync for themeable or shared-helper changes (step 3) | ||
| For diffs that don't touch components (docs-only, tooling, workflows), | ||
| SKIP the component checklist and just review the diff generally. | ||
| Always check commit message type/scope (`feat|fix|perf|refactor|style` | ||
| need scope `bulma-ui|docs|create-bestax`). | ||
| 3. Report a short summary: gate result, then each checklist gap with the | ||
| file to touch. Do not fix anything — this command only reviews. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| --- | ||
| description: Find likely duplicates of an issue with 5 parallel search agents and post one triage comment | ||
| allowed-tools: Task, Bash(gh issue view:*), Bash(gh issue list:*), Bash(gh pr list:*), Bash(gh search:*), Bash(gh issue comment:*) | ||
| --- | ||
|
|
||
| # /triage-dedupe — duplicate search for an issue | ||
|
|
||
| Find likely duplicates of the target issue and post EXACTLY ONE comment (or | ||
| nothing — see pre-checks). Context comes from the caller (the ai-triage | ||
| workflow prompt, or the user when run locally): `REPO` (owner/repo), `NUMBER` | ||
| (the target issue), `TRIGGER` (`opened` or `labeled`; assume `labeled` when | ||
| run locally), and `AUTOCLOSE` (`active` or `off`; assume `off` locally). If | ||
| `NUMBER` is missing, ask — never guess. | ||
|
|
||
| ## Pre-checks (in order; each exit is SILENT — post nothing) | ||
|
|
||
| 1. `gh issue view NUMBER --repo REPO --json state,title,body,comments` — if | ||
| the issue is not open, stop. | ||
| 2. Marker check — does any existing comment by a claude bot account contain | ||
| `<!-- ai-triage:dedupe -->`? | ||
| - `TRIGGER=opened` and marker present → stop (already triaged). | ||
| - `TRIGGER=labeled` and marker present → continue; at the end REFRESH | ||
| that comment instead of posting a new one: if it is your most recent | ||
| comment on the issue, use | ||
| `gh issue comment NUMBER --repo REPO --edit-last --body ...`; | ||
| otherwise post a fresh comment (the old one stays as history). | ||
| 3. If the issue is too vague to search meaningfully (no error text, no | ||
| component or file name, no concrete behavior), stop. | ||
|
|
||
| ## Search — 5 parallel agents | ||
|
|
||
| Summarize the issue first: symptoms, component/file names, API/prop names, | ||
| exact error strings, and the general area. Then fan out FIVE Task agents in | ||
| a single message, each pursuing ONE distinct strategy: | ||
|
|
||
| 1. **Error strings** — exact quoted messages, stack-trace lines, warning text. | ||
| 2. **Component + file names** — `Button`, `Modal`, `useConfig`, source paths. | ||
| 3. **API + prop names** — prop names, exported symbols, CSS class names. | ||
| 4. **Title keywords** — the strongest 2–4 words of the title, plus synonyms. | ||
| 5. **Broad area terms** — the general feature area (theming, SSR, a11y, docs). | ||
|
|
||
| Rules for every agent: | ||
|
|
||
| - EVERY search is scoped to this repository: `repo:REPO` in the query (or | ||
| the `--repo REPO` flag). Never search outside it. | ||
| - Use `gh search issues`, `gh issue list --search`; include closed issues | ||
| (a duplicate of a closed issue is still a duplicate). | ||
| - Return candidate numbers with title and a one-line justification each. | ||
|
|
||
| ## Filter pass (you, not the agents) | ||
|
|
||
| Judge every candidate against the target: same root cause or clearly the | ||
| same feature request = duplicate; same area or a blocking relationship = | ||
| related. DROP weak keyword-only matches — an empty result beats a wrong one. | ||
| Read the top candidates with `gh issue view` when unsure. | ||
|
|
||
| ## Post ONE comment | ||
|
|
||
| Via `gh issue comment NUMBER --repo REPO --body ...` (or the refresh path | ||
| from pre-check 2), formatted exactly like this: | ||
|
|
||
| ```markdown | ||
| ### AI triage | ||
|
|
||
| **Likely duplicates** | ||
|
|
||
| - #N — <title>: <one-line reason> | ||
| - (at most 3 entries, best match first) | ||
|
|
||
| Duplicate of #N | ||
|
|
||
| **Related** (optional, at most 3) | ||
|
|
||
| - #M — <title>: <one-line reason> | ||
|
|
||
| <!-- ai-triage:dedupe --> | ||
| ``` | ||
|
|
||
| - The line `Duplicate of #N` — with N the single best duplicate — must use | ||
| THIS EXACT FORMAT on its own line: the auto-close cron machine-parses it. | ||
| Include it only when you found at least one credible duplicate. | ||
| - If `AUTOCLOSE=active`, add this sentence directly after the | ||
| `Duplicate of #N` line: "This issue may be auto-closed in 14 days unless | ||
| someone objects (comment or 👎)." If `AUTOCLOSE=off`, omit it. | ||
| - The marker `<!-- ai-triage:dedupe -->` goes on its own line at the end. | ||
| - No credible duplicates → post "No duplicates found." under the heading, | ||
| plus the marker, WITHOUT any `Duplicate of #N` line or auto-close notice. | ||
|
|
||
| ## Hard rules | ||
|
|
||
| Never apply or remove labels; never close, merge, push, or resolve | ||
| anything; never write "@claude" or "@coderabbitai" in any text; post at | ||
| most one comment and nothing else. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| --- | ||
| description: Find open PRs that duplicate a PR with 3 parallel search agents; silent when none found | ||
| allowed-tools: Task, Bash(gh pr view:*), Bash(gh pr diff:*), Bash(gh pr list:*), Bash(gh search:*), Bash(gh pr comment:*) | ||
| --- | ||
|
|
||
| # /triage-find-duplicate-prs — overlapping-work check for a PR | ||
|
|
||
| Find OPEN, unmerged PRs that duplicate or overlap the target PR. SILENT by | ||
| default: when nothing credible turns up, post NOTHING. Context from the | ||
| caller: `REPO`, `NUMBER` (the target PR), `TRIGGER` (`opened`/`labeled`; | ||
| assume `labeled` locally). If `NUMBER` is missing, ask. | ||
|
|
||
| ## Pre-checks (each exit is SILENT) | ||
|
|
||
| 1. `gh pr view NUMBER --repo REPO --json state,title,body,files,comments` — | ||
| if the PR is not open, stop. | ||
| 2. Marker check — a claude-bot comment containing | ||
| `<!-- ai-triage:find-duplicate-prs -->`: | ||
| - `TRIGGER=opened` and marker present → stop. | ||
| - `TRIGGER=labeled` and marker present → continue; at the end refresh | ||
| that comment (`gh pr comment NUMBER --repo REPO --edit-last --body ...` | ||
| if it is your most recent comment on the PR; otherwise post fresh). | ||
|
|
||
| ## Search — 3 parallel agents | ||
|
|
||
| Read the PR title, body, and changed file list, then fan out THREE Task | ||
| agents in a single message, one strategy each: | ||
|
|
||
| 1. **Changed files** — other PRs touching the same components or paths. | ||
| 2. **Title + body keywords** — the strongest words plus synonyms. | ||
| 3. **Feature/fix intent** — what the PR accomplishes, phrased differently. | ||
|
|
||
| Rules for every agent: EVERY search scoped | ||
| `repo:REPO is:pr is:open is:unmerged` (via `gh search prs` or | ||
| `gh pr list --search`); exclude the target PR itself and draft PRs; return | ||
| numbers + titles + a one-line justification. | ||
|
|
||
| ## Filter pass | ||
|
|
||
| A duplicate solves the same problem or implements the same feature — same | ||
| files alone is NOT enough. Compare diffs (`gh pr diff`) when unsure. Drop | ||
| weak matches. Zero credible duplicates: on `TRIGGER=opened`, stop SILENTLY | ||
| — no comment, no marker; on `TRIGGER=labeled` (an explicit human request), | ||
| post/refresh the comment with the single line "No duplicate PRs found." | ||
| plus the marker (matches the pre-check refresh path). | ||
|
|
||
| ## Post ONE comment (when duplicates exist, or on a labeled rerun) | ||
|
|
||
| Via `gh pr comment NUMBER --repo REPO --body ...` (or the refresh path): | ||
|
|
||
| ```markdown | ||
| ### AI triage — possible duplicate PRs | ||
|
|
||
| - #N — <title>: <one-line reason> (at most 3, best match first) | ||
|
|
||
| <!-- ai-triage:find-duplicate-prs --> | ||
| ``` | ||
|
|
||
| The marker `<!-- ai-triage:find-duplicate-prs -->` goes on its own line at | ||
| the end. | ||
|
|
||
| ## Hard rules | ||
|
|
||
| Never apply or remove labels; never close, merge, push, or resolve | ||
| anything; never write "@claude" or "@coderabbitai" in any text; post at | ||
| most one comment, and none at all when nothing was found. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| --- | ||
| description: Find open issues a PR likely resolves with 5 parallel search agents and post one triage comment | ||
| allowed-tools: Task, Bash(gh pr view:*), Bash(gh pr diff:*), Bash(gh issue view:*), Bash(gh issue list:*), Bash(gh search:*), Bash(gh pr comment:*) | ||
| --- | ||
|
|
||
| # /triage-find-issues — link a PR to the issues it resolves | ||
|
|
||
| Find OPEN issues the target PR likely resolves or relates to, and post | ||
| EXACTLY ONE comment (or nothing). Context from the caller: `REPO`, `NUMBER` | ||
| (the target PR), `TRIGGER` (`opened`/`labeled`; assume `labeled` locally), | ||
| `AUTOCLOSE` (unused here). If `NUMBER` is missing, ask. | ||
|
|
||
| ## Pre-checks (each exit is SILENT) | ||
|
|
||
| 1. `gh pr view NUMBER --repo REPO --json state,title,body,comments` — if the | ||
| PR is not open, stop. | ||
| 2. Marker check — a claude-bot comment containing | ||
| `<!-- ai-triage:find-issues -->`: | ||
| - `TRIGGER=opened` and marker present → stop. | ||
| - `TRIGGER=labeled` and marker present → continue; at the end refresh | ||
| that comment (`gh pr comment NUMBER --repo REPO --edit-last --body ...` | ||
| if it is your most recent comment on the PR; otherwise post fresh). | ||
| 3. Note every issue already referenced in the PR body (`#N`, `Fixes #N`, | ||
| `Closes #N`, full URLs) — those are EXCLUDED from the results. | ||
|
|
||
| ## Search — 5 parallel agents | ||
|
|
||
| Read the PR title, body, and `gh pr diff NUMBER --repo REPO` (never check | ||
| out or execute its code). Extract signals, then fan out FIVE Task agents in | ||
| a single message, one strategy each: | ||
|
|
||
| 1. **Error strings** — messages or test names the diff fixes or touches. | ||
| 2. **Component + file names** — components and paths the diff changes. | ||
| 3. **API + prop names** — props, exports, and CSS classes the diff touches. | ||
| 4. **Title keywords** — the strongest words of the PR title, plus synonyms. | ||
| 5. **Broad area terms** — the feature area of the change. | ||
|
|
||
| Rules for every agent: scope EVERY search to this repository | ||
| (`repo:REPO` or `--repo REPO`); OPEN issues only (`is:open` / | ||
| `--state open`); return numbers + titles + a one-line justification. | ||
|
|
||
| ## Filter pass | ||
|
|
||
| Keep only issues this PR plausibly resolves (the diff addresses the issue's | ||
| root cause) or directly relates to. Exclude everything already linked in | ||
| the PR body (pre-check 3). Drop weak keyword-only matches. If nothing | ||
| credible remains: on `TRIGGER=opened`, stop SILENTLY — no comment, no | ||
| marker; on `TRIGGER=labeled` (an explicit human request — silence would | ||
| read as a malfunction), post/refresh the comment with the single line | ||
| "No open issues found that this PR resolves." plus the marker (matches | ||
| pre-check 2's refresh path). | ||
|
|
||
| ## Post ONE comment | ||
|
|
||
| Via `gh pr comment NUMBER --repo REPO --body ...` (or the refresh path): | ||
|
|
||
| ````markdown | ||
| ### AI triage — issues this PR may resolve | ||
|
|
||
| - #N — <title>: <one-line reason> (best match first, at most 5) | ||
|
|
||
| If this PR resolves one of these, add the line below to the PR description | ||
| so the issue closes on merge: | ||
|
|
||
| ``` | ||
| Fixes #N | ||
| ``` | ||
|
|
||
| <!-- ai-triage:find-issues --> | ||
| ```` | ||
|
|
||
| The marker `<!-- ai-triage:find-issues -->` goes on its own line at the end. | ||
|
|
||
| ## Hard rules | ||
|
|
||
| Never apply or remove labels; never close, merge, push, or resolve | ||
| anything; never edit the PR body yourself — only suggest; never write | ||
| "@claude" or "@coderabbitai" in any text; post at most one comment. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Resolve the contradiction with the hard rules.
These lines require
TRIGGER=labeledto post or refresh “No duplicate PRs found.”, but Line 66 says to post no comment whenever nothing was found. An agent may follow the hard rule and suppress the required labeled rerun comment, breaking the documented idempotency contract.Proposed clarification
🤖 Prompt for AI Agents