Skip to content

chore(ci): bring ClawReview πŸ¦€ mascot + triage to beta#250

Merged
KrasimirKralev merged 5 commits into
ID-Robots:betafrom
KrasimirKralev:chore/clawreview-beta-sync
Jul 5, 2026
Merged

chore(ci): bring ClawReview πŸ¦€ mascot + triage to beta#250
KrasimirKralev merged 5 commits into
ID-Robots:betafrom
KrasimirKralev:chore/clawreview-beta-sync

Conversation

@KrasimirKralev

@KrasimirKralev KrasimirKralev commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Brings both bots to beta so beta-targeting PRs/issues (most of our volume) trigger them β€” pull_request_target and issues workflows run from the base branch.

Carries the same code as the main-side mascot PR (#252):

  • New: scripts/pr-review.mjs + .github/workflows/pr-review.yml β€” the ClawReview mascot (informative orientation, not a code reviewer)
  • Updated: scripts/issue-triage.mjs + .github/workflows/issue-triage.yml β€” same crab mascot voice + OAuth subscription transport (SDK lazy-loaded)

CI-only files, no device code. CONTRIBUTING.md not synced (read from the default branch only).

pull_request_target and issues-triggered workflows run from the PR's/issue's
BASE branch, so the bots must exist on beta too β€” otherwise beta-targeting
PRs (most of our volume) never trigger ClawReview. Brings the exact CI files
from main (ID-Robots#248): the new pr-review bot, plus the OAuth-transport + sync
updates to the issue-triage bot. CI-only files, identical to main.
@KrasimirKralev
KrasimirKralev requested a review from a team as a code owner July 5, 2026 09:27
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@KrasimirKralev, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 32 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
βš™οΈ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: c583441a-bdf2-4f85-8202-bb05638398e8

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 11f1140 and 1a1a746.

πŸ“’ Files selected for processing (5)
  • .github/workflows/issue-triage.yml
  • .github/workflows/pr-review.yml
  • scripts/issue-triage.mjs
  • scripts/lib/ai-backend.mjs
  • scripts/pr-review.mjs
πŸ“ Walkthrough

Walkthrough

Adds a new "ClawReview" GitHub Actions workflow and scripts/pr-review.mjs bot that performs non-blocking automated PR reviews using Claude CLI or Anthropic SDK, deterministic policy checks, comment upsert, and area labeling. Updates issue-triage.yml and scripts/issue-triage.mjs to support the same dual-backend pattern and optional GitHub App token minting.

Changes

ClawReview PR Review Bot

Layer / File(s) Summary
Workflow trigger and setup
.github/workflows/pr-review.yml
New workflow triggers on pull_request_target, restricts permissions, skips draft/bot PRs, checks out base repo only, installs Claude CLI or Anthropic SDK conditionally, and mints a GitHub App token.
PR data gathering and policy checks
scripts/pr-review.mjs
Gathers PR metadata, diff, linked issues, and other open PRs; runs deterministic checks for release conventions, dependency/lockfile consistency, title format, churn heuristics, and security-sensitive paths.
AI review, comment, and labeling
scripts/pr-review.mjs
Builds a strict JSON schema prompt sent to Claude, parses the response, composes/upserts a marker comment, and applies area:* labels; wraps execution with dry-run/review-only modes and non-blocking error handling.

Issue Triage Dual-Backend Support

Layer / File(s) Summary
Workflow conditional install and token minting
.github/workflows/issue-triage.yml
Installs Claude Code CLI or Anthropic SDK based on OAuth token presence, mints a GitHub App token when configured, and updates triage step environment variables.
Script dual classification backends
scripts/issue-triage.mjs
Adds gh helper, parseModelJson, and classifyViaClaudeCli/classifyViaSdk functions; main selects backend based on OAuth token availability.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHub
  participant Workflow as pr-review.yml
  participant Script as pr-review.mjs
  participant Claude as Claude CLI/SDK
  participant PRComment as GitHub PR

  GitHub->>Workflow: pull_request_target event
  Workflow->>Workflow: skip if draft or bot author
  Workflow->>Script: run scripts/pr-review.mjs
  Script->>Script: gather PR metadata, diff, linked issues
  Script->>Script: run deterministic policy checks
  Script->>Claude: send prompt for structured review
  Claude-->>Script: JSON verdict and findings
  Script->>PRComment: upsert review comment
  Script->>PRComment: apply area:* labels
Loading

Possibly related PRs

  • ID-Robots/clawbox#221: Prior refactor of scripts/issue-triage.mjs and issue-triage.yml introducing the same Claude CLI vs Anthropic SDK dual-backend classification pattern extended in this PR.
πŸš₯ Pre-merge checks | βœ… 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main goal, but it does not follow the required template sections or include testing, checklist, or screenshots. Rewrite it using the repo template: add Summary, Type of change, How was this tested, Checklist, and Screenshots/logs sections, with concrete entries for each.
βœ… Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check βœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check βœ… Passed Check skipped because no linked issues were found for this pull request.
Title check βœ… Passed The title is concise and accurately summarizes the beta sync for ClawReview and issue triage.
✨ Finishing Touches
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

πŸ€– Prompt for all review comments with 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.

Inline comments:
In @.github/workflows/issue-triage.yml:
- Around line 59-72: The Mint ClawReview app token step is gated by a value it
sets on itself, so the condition in issue-triage.yml never evaluates as
intended. Update the guard on the app-token step to check
secrets.CLAWREVIEW_APP_ID directly rather than env.HAS_APP, and keep the
existing create-github-app-token usage tied to that secret. If the step remains,
also restrict the resulting token to only the permissions needed by the triage
workflow instead of using the full installation scope.

In @.github/workflows/pr-review.yml:
- Around line 61-74: The Mint ClawReview app token step is gated by an `if`
condition that references `env.HAS_APP` before that step’s own `env:` is
available, so the token minting always skips. Fix the `app-token` step in
`pr-review.yml` by moving `HAS_APP` to a job-level `env` or deriving it from a
previous step output, then keep the `if` check on that accessible value so the
`actions/create-github-app-token` step can run when the ClawReview secrets are
present.

In `@scripts/issue-triage.mjs`:
- Around line 45-92: The parsing and backend invocation logic in issue-triage is
duplicated from the review script, so refactor it into a shared helper module
and reuse it from both places. Extract the common behavior from parseModelJson,
classifyViaClaudeCli, and classifyViaSdk into a generic
scripts/lib/ai-backend.mjs helper that accepts the system prompt, schema, model,
and any transport-specific limits. Update the call sites in issue-triage.mjs to
import and use those shared helpers so future changes stay synchronized with the
matching review flow.

In `@scripts/pr-review.mjs`:
- Around line 9-11: The top-level `Anthropic` import in `scripts/pr-review.mjs`
can break the OAuth flow before the fallback runs because the SDK is only
installed on the non-OAuth path. Move the `@anthropic-ai/sdk` import into
`reviewViaSdk()` (or lazily load it inside that function) so the CLI fallback
can still execute when `CLAUDE_CODE_OAUTH_TOKEN` is set, while keeping the
existing `reviewViaSdk` and fallback logic intact.
πŸͺ„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5300f5e1-56b0-47ed-aafa-2cb3ef8fcfa5

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 981c094 and 11f1140.

πŸ“’ Files selected for processing (4)
  • .github/workflows/issue-triage.yml
  • .github/workflows/pr-review.yml
  • scripts/issue-triage.mjs
  • scripts/pr-review.mjs

Comment thread .github/workflows/issue-triage.yml
Comment thread .github/workflows/pr-review.yml
Comment thread scripts/issue-triage.mjs Outdated
Comment thread scripts/pr-review.mjs Outdated
The OAuth transport installs only the Claude Code CLI, not @anthropic-ai/sdk,
but both scripts had a static top-level 'import Anthropic from
@anthropic-ai/sdk' β€” evaluated at module load regardless of transport β€” so
the review job crashed with ERR_MODULE_NOT_FOUND before running (passed my
local test only because the SDK was left installed there). Moved the import
into a dynamic import() inside reviewViaSdk/classifyViaSdk, reached only on
the API-key fallback. Verified by running the OAuth path with node_modules
removed.
Per direction: ClawReview should be a knowledgeable, friendly crab mascot that
greets and orients on issues/PRs β€” NOT a code reviewer racing CodeRabbit.

PR bot (pr-review.mjs):
- Dropped severity findings (P1/P2/P3) and pass/fail verdicts β€” that was the
  CodeRabbit-racing part. Schema is now summary + kind + touches + neutral
  'highlights' (helpful heads-ups, never bug reports) + duplicate hint.
- System prompt recast: 'you are the mascot, not a reviewer; CodeRabbit does
  the line-by-line; produce orientation, never verdicts'. Empty highlights is
  normal and encouraged.
- Comment is now: greeting -> plain-language summary -> 'At a glance'
  (kind/touches/base/surface + deterministic policy heads-ups) -> optional
  'Good to know' -> sign-off that explicitly defers to CodeRabbit.

Issue bot (issue-triage.mjs):
- Rebranded the triage comment as the same crab mascot (one character across
  issues + PRs): friendly greeting + summary + at-a-glance labels + next step.
- Added DRY_RUN (prints the comment, skips label writes) for local testing.

Deterministic policy checks stay β€” they're genuine ClawBox-specific value
(beta-first, bun.lock, sensitive paths) CodeRabbit can't provide β€” but are
now framed as friendly context, not a verdict. Validated end-to-end via the
OAuth CLI transport on PR ID-Robots#227 and issue ID-Robots#232.
@KrasimirKralev KrasimirKralev changed the title chore(ci): sync ClawReview πŸ¦€ + triage bots to beta chore(ci): bring ClawReview πŸ¦€ mascot + triage to beta Jul 5, 2026
CodeRabbit's 4 actionable findings on the bots:

1+2. app-token step's `if: env.HAS_APP` (both workflows) referenced env the
     step sets on ITSELF β€” a step's if can't see its own step-level env, so
     the App token would NEVER mint even with the secrets set. Hoisted
     HAS_APP to job-level env (visible to the step if), and scoped the minted
     token to only the permissions each bot needs (pull-requests+issues for
     review, issues for triage) instead of the full installation grant.

3.   parseModelJson + the two transports (CLI/SDK) were duplicated across
     pr-review.mjs and issue-triage.mjs. Extracted to scripts/lib/
     ai-backend.mjs (callClaude); both bots import it, so the transport stays
     in sync. This is the 'first SDK-shape change' trigger the earlier reuse
     analysis set for extraction.

4.   Static @anthropic-ai/sdk import breaking the OAuth path β€” already fixed
     (lazy import); the shared backend now owns the sole lazy import, so
     pr-review.mjs no longer imports the SDK at all.

Validated via the OAuth CLI transport with node_modules removed: both bots
produce their mascot output through the shared backend.
@KrasimirKralev

Copy link
Copy Markdown
Contributor Author

Thanks @coderabbitai β€” all 4 addressed in the latest push (identical fix on the main-side PR #252):

  1. issue-triage.yml app-token if βœ… β€” real bug. HAS_APP hoisted to job-level env (a step can't read env it sets on itself), and the minted token is now scoped to issues: write only.
  2. pr-review.yml app-token if βœ… β€” same fix; token scoped to pull-requests: write + issues: write.
  3. Duplicated backend logic βœ… β€” extracted parseModelJson + both transports into scripts/lib/ai-backend.mjs (callClaude); both bots import it, so the transport stays in sync.
  4. Static @anthropic-ai/sdk import βœ… (already resolved) β€” it was made lazy earlier; after the extraction the SDK's sole lazy import lives in the shared backend and pr-review.mjs no longer imports it at all.

Validated end-to-end via the OAuth CLI transport with node_modules removed β€” both bots produce their output through the shared backend.

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
gh pr diff 250 --repo ID-Robots/clawbox > /tmp/pr250.diff || true
wc -l /tmp/pr250.diff
grep -n "HAS_APP" -A3 -B3 /tmp/pr250.diff | head -100
echo "-----ai-backend-----"
fd -a ai-backend.mjs
</bash>

Length of output: 2103


🏁 Script executed:

#!/bin/bash
set -euo pipefail
grep -n "permissions" -A5 /tmp/pr250.diff | head -60
echo "----imports----"
grep -n "ai-backend" -R scripts/*.mjs
echo "----ai-backend content----"
sed -n '1,50p' scripts/lib/ai-backend.mjs

Length of output: 3129


All confirmed β€” the latest push looks solid.

  1. HAS_APP is now correctly hoisted to job-level env in both issue-triage.yml and pr-review.yml, and the app-token step's if: env.HAS_APP != '' correctly reads it.
  2. Token scoping is properly narrowed (issues: write for triage; pull-requests: write + issues: write for PR review).
  3. scripts/lib/ai-backend.mjs now cleanly centralizes parseModelJson plus both viaClaudeCli/viaSdk transports behind callClaude, and both scripts/pr-review.mjs and scripts/issue-triage.mjs import from it β€” no more duplicated logic.
  4. The @anthropic-ai/sdk import is lazy (await import(...) inside viaSdk), so the OAuth-only CLI path won't require the SDK to be installed, and pr-review.mjs no longer imports it directly.

Nice work consolidating the shared backend β€” that'll make future transport changes much easier to keep in sync across both bots.

(=^β€’ Ο‰ β€’^=) purring approval

…y dry-run

- ai-backend.mjs: viaSdk now uses parseModelJson (tolerant of fenced/wrapped
  JSON) instead of a bare JSON.parse, matching the CLI path.
- issue-triage.mjs: DRY_RUN now gates the whole label block (ensure() +
  gh issue edit), not just the edit β€” a dry run is fully read-only.
KrasimirKralev added a commit that referenced this pull request Jul 5, 2026
…#252)

* fix(ci): lazy-load the Anthropic SDK so the OAuth path needs no SDK

The OAuth transport (shipped in #248) installs only the Claude Code CLI, not
@anthropic-ai/sdk, but both bot scripts had a static top-level 'import
Anthropic from @anthropic-ai/sdk' evaluated at module load regardless of
transport β€” so the live bots on main crash with ERR_MODULE_NOT_FOUND before
running. Moved the import into a dynamic import() inside
reviewViaSdk/classifyViaSdk, reached only on the API-key fallback. Verified
by running the OAuth path with node_modules removed. Same fix rides to beta
in #250.

* feat(ci): reshape ClawReview into an informative mascot (not a reviewer)

Per direction: ClawReview should be a knowledgeable, friendly crab mascot that
greets and orients on issues/PRs β€” NOT a code reviewer racing CodeRabbit.

PR bot (pr-review.mjs):
- Dropped severity findings (P1/P2/P3) and pass/fail verdicts β€” that was the
  CodeRabbit-racing part. Schema is now summary + kind + touches + neutral
  'highlights' (helpful heads-ups, never bug reports) + duplicate hint.
- System prompt recast: 'you are the mascot, not a reviewer; CodeRabbit does
  the line-by-line; produce orientation, never verdicts'. Empty highlights is
  normal and encouraged.
- Comment is now: greeting -> plain-language summary -> 'At a glance'
  (kind/touches/base/surface + deterministic policy heads-ups) -> optional
  'Good to know' -> sign-off that explicitly defers to CodeRabbit.

Issue bot (issue-triage.mjs):
- Rebranded the triage comment as the same crab mascot (one character across
  issues + PRs): friendly greeting + summary + at-a-glance labels + next step.
- Added DRY_RUN (prints the comment, skips label writes) for local testing.

Deterministic policy checks stay β€” they're genuine ClawBox-specific value
(beta-first, bun.lock, sensitive paths) CodeRabbit can't provide β€” but are
now framed as friendly context, not a verdict. Validated end-to-end via the
OAuth CLI transport on PR #227 and issue #232.

* chore(assets): add square crab avatar for the ClawReview GitHub App

512x512 crab-only crop of the ClawBox logo (wordmark removed, padded so a
circular avatar mask keeps the claws). This is the image to upload when
creating the ClawReview GitHub App β€” a stable raw URL beats the earlier
non-square 87x128 crab PNG.

* fix(ci): apply CodeRabbit review β€” app-token if-guard + shared backend

CodeRabbit's 4 actionable findings on the bots:

1+2. app-token step's `if: env.HAS_APP` (both workflows) referenced env the
     step sets on ITSELF β€” a step's if can't see its own step-level env, so
     the App token would NEVER mint even with the secrets set. Hoisted
     HAS_APP to job-level env (visible to the step if), and scoped the minted
     token to only the permissions each bot needs (pull-requests+issues for
     review, issues for triage) instead of the full installation grant.

3.   parseModelJson + the two transports (CLI/SDK) were duplicated across
     pr-review.mjs and issue-triage.mjs. Extracted to scripts/lib/
     ai-backend.mjs (callClaude); both bots import it, so the transport stays
     in sync. This is the 'first SDK-shape change' trigger the earlier reuse
     analysis set for extraction.

4.   Static @anthropic-ai/sdk import breaking the OAuth path β€” already fixed
     (lazy import); the shared backend now owns the sole lazy import, so
     pr-review.mjs no longer imports the SDK at all.

Validated via the OAuth CLI transport with node_modules removed: both bots
produce their mascot output through the shared backend.

* fix(ci): address CodeRabbit re-review β€” tolerant SDK parse + read-only dry-run

- ai-backend.mjs: viaSdk now uses parseModelJson (tolerant of fenced/wrapped
  JSON) instead of a bare JSON.parse, matching the CLI path.
- issue-triage.mjs: DRY_RUN now gates the whole label block (ensure() +
  gh issue edit), not just the edit β€” a dry run is fully read-only.
@KrasimirKralev
KrasimirKralev merged commit 7d7bf64 into ID-Robots:beta Jul 5, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant