Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .claude/commands/pre-pr.md
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.
93 changes: 93 additions & 0 deletions .claude/commands/triage-dedupe.md
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.
66 changes: 66 additions & 0 deletions .claude/commands/triage-find-duplicate-prs.md
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).
Comment on lines +42 to +45

Copy link
Copy Markdown

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=labeled to 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
- anything; post at most one comment, and none at all when nothing was found.
+ anything; post at most one comment. For no matches, post nothing on
+ `TRIGGER=opened`; on `TRIGGER=labeled`, follow the explicit refresh
+ behavior above.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/commands/triage-find-duplicate-prs.md around lines 42 - 45, Clarify
the trigger-specific behavior in the duplicate PR handling instructions: when no
credible duplicates are found, TRIGGER=opened must remain completely silent,
while TRIGGER=labeled must post or refresh the single-line “No duplicate PRs
found.” comment with the marker. Update the conflicting rule near the “nothing
was found” guidance so this labeled-trigger exception is explicit and preserves
idempotent refresh behavior.


## 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.
78 changes: 78 additions & 0 deletions .claude/commands/triage-find-issues.md
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.
Loading
Loading