Skip to content

refactor: split SherpaOnnxManager + extract magic numbers (P0-2, P1-4) #37

refactor: split SherpaOnnxManager + extract magic numbers (P0-2, P1-4)

refactor: split SherpaOnnxManager + extract magic numbers (P0-2, P1-4) #37

Workflow file for this run

# Claude Code Review - Automated PR Reviews
#
# Triggers on every PR to main.
# Uses Anthropic API via custom proxy (ANTHROPIC_BASE_URL).
#
# Features:
# - Smart skip: rebase, WIP, trivial changes, version bumps
# - Comment dedup: avoids repeating bot/human comments on synchronize
# - Auto-resolve: resolves bot comments that have been addressed by new pushes
#
# Prerequisites:
# 1. Install GitHub App: https://github.com/apps/claude (or create custom app)
# 2. Add repo secrets:
# - ANTHROPIC_PROXY_URL: your proxy base URL (e.g. https://xxx.ngrok-free.dev/api/anthropic)
# - ANTHROPIC_PROXY_KEY: your proxy authentication key
# 3. (Optional) If using custom GitHub App, add APP_ID and APP_PRIVATE_KEY secrets
name: Claude Code Review
permissions:
contents: read
pull-requests: write
id-token: write
on:
pull_request:
types: [opened, synchronize]
branches:
- main
# Prevent concurrent reviews for the same PR
concurrency:
group: claude-review-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
review:
name: AI Code Review
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Fetch origin main
run: git fetch origin main
# --- Option A: Use official Claude GitHub App (simplest) ---
# Just install https://github.com/apps/claude
# and the action uses the default GITHUB_TOKEN.
# --- Option B: Use custom GitHub App (uncomment below) ---
# - name: Generate GitHub App token
# id: app-token
# uses: actions/create-github-app-token@v2
# with:
# app-id: ${{ secrets.APP_ID }}
# private-key: ${{ secrets.APP_PRIVATE_KEY }}
# ---- Auto-resolve: check if previous bot comments have been addressed ----
- name: Fetch unresolved bot comments
if: github.event.action == 'synchronize'
id: fetch-threads
env:
GH_TOKEN: ${{ github.token }}
run: |
THREADS=$(gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(last: 50) {
nodes {
id
isResolved
path
line
comments(first: 1) {
nodes {
author { login }
body
}
}
}
}
}
}
}' \
-F owner="${{ github.repository_owner }}" \
-F repo="${{ github.event.repository.name }}" \
-F pr="${{ github.event.pull_request.number }}" \
--jq '[.data.repository.pullRequest.reviewThreads.nodes[]
| select(.isResolved == false)
| select(.comments.nodes | length > 0)
| select(.comments.nodes[0].author != null)
| select(.comments.nodes[0].author.login == "claude")]' 2>/dev/null || echo '[]')
THREAD_COUNT=$(echo "$THREADS" | jq 'length')
echo "Found $THREAD_COUNT unresolved bot comments"
echo "unresolved_threads<<EOF" >> $GITHUB_OUTPUT
echo "$THREADS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "thread_count=$THREAD_COUNT" >> $GITHUB_OUTPUT
- name: Auto-resolve addressed comments
if: |
github.event.action == 'synchronize' &&
steps.fetch-threads.outputs.thread_count != '0'
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_PROXY_KEY }}
use_sticky_comment: false
claude_args: >-
--model claude-opus-4-6
--max-turns 20
--allowedTools Bash(gh api repos:*),Bash(gh api graphql:*),Bash(git diff:*),Bash(git log:*),Read
prompt: |
You are analyzing previously flagged review comments to determine if they've been addressed in the latest push.
## Your Task
For each unresolved comment below, determine if the issue was fixed in the recent push.
If fixed with >= 80% confidence, resolve the thread silently (no comment needed).
## Unresolved Comments to Analyze
${{ steps.fetch-threads.outputs.unresolved_threads }}
## Recent Changes
Use: `git diff origin/main...HEAD -- <file>` to see all PR changes.
## Decision Criteria
- RESOLVE if: code was modified AND the modification addresses the concern (>= 80% confidence)
- KEEP OPEN if: code unchanged, fix incomplete, or you're uncertain
## How to Resolve a Thread
```bash
gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: "THREAD_ID"}) { thread { isResolved } } }'
```
## Instructions
1. For each thread, check if the file at `path` was modified in the diff
2. If modified, read the diff and compare to the original concern in `body`
3. If confident (>= 80%), execute the resolve mutation
4. Report summary: "Auto-resolved X of Y comments"
Be conservative - when in doubt, leave the thread open.
env:
ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_PROXY_URL }}
GH_TOKEN: ${{ github.token }}
continue-on-error: true
# ---- Comment dedup: fetch existing comments to avoid duplicates ----
- name: Fetch existing review comments for dedup
if: github.event.action == 'synchronize'
id: fetch-existing-comments
env:
GH_TOKEN: ${{ github.token }}
run: |
RESPONSE=$(gh api graphql -f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviewThreads(last: 100) {
nodes {
isResolved
path
line
comments(first: 1) {
nodes {
author { login }
body
}
}
}
}
}
}
}' \
-F owner="${{ github.repository_owner }}" \
-F repo="${{ github.event.repository.name }}" \
-F pr="${{ github.event.pull_request.number }}" 2>/dev/null || echo '{}')
BOT_COMMENTS=$(echo "$RESPONSE" | jq -c '
[.data.repository.pullRequest.reviewThreads.nodes // []
| .[]
| select(.comments.nodes | length > 0)
| select(.comments.nodes[0].author != null)
| select(.comments.nodes[0].author.login == "claude")
| {
path,
line,
resolved: .isResolved,
body: (.comments.nodes[0].body | split("\n")[0][:200])
}]' 2>/dev/null || echo '[]')
HUMAN_COMMENTS=$(echo "$RESPONSE" | jq -c '
[.data.repository.pullRequest.reviewThreads.nodes // []
| .[]
| select(.comments.nodes | length > 0)
| select(.comments.nodes[0].author != null)
| select(.comments.nodes[0].author.login != "claude")
| {
user: .comments.nodes[0].author.login,
path,
line,
body: (.comments.nodes[0].body | split("\n")[0][:200])
}]' 2>/dev/null || echo '[]')
BOT_COUNT=$(echo "$BOT_COMMENTS" | jq 'length')
HUMAN_COUNT=$(echo "$HUMAN_COMMENTS" | jq 'length')
echo "Found $BOT_COUNT existing bot comments and $HUMAN_COUNT human comments"
{
echo "bot_comments<<EOF"
echo "$BOT_COMMENTS"
echo "EOF"
echo "human_comments<<EOF"
echo "$HUMAN_COMMENTS"
echo "EOF"
} >> "$GITHUB_OUTPUT"
continue-on-error: true
# ---- Main review ----
- name: Claude Code Review
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_PROXY_KEY }}
use_sticky_comment: true
show_full_output: true
claude_args: >-
--model claude-opus-4-6
--max-turns 50
--allowedTools Task,Read,Glob,Grep,Bash(git diff:*),Bash(git show:*),Bash(gh pr view:*),mcp__github_comment__create_or_update_comment,mcp__github_comment__create_comment,mcp__github_comment__update_claude_comment,mcp__github_inline_comment__create_inline_comment,mcp__github_inline_comment__create_review
prompt: |
You are reviewing a pull request for the Typeless project - a macOS ASR (Automatic Speech Recognition) app built with Swift.
The codebase uses sherpa-onnx and QwenASR for speech recognition.
## Step 0: Check Skip Conditions
Before reviewing, determine if this PR should be skipped:
### Change-Based
- Skip if the PR contains only merge commits or rebase operations (no net code changes)
- Skip if only whitespace, formatting, or line ending changes
- Skip if only version bumps (project.pbxproj version fields, package versions, etc.)
### Author Intent
- Skip if PR title/description contains keywords: "rebase", "merge conflict", "typo", "formatting", "version bump"
- Skip if PR title contains "WIP" or "Do Not Review"
### Frequency-Based
- Use `gh pr view ${{ github.event.pull_request.number }} --json reviews` to check past reviews
- Skip if the bot reviewed within 15 minutes and no substantial code changes occurred
If any skip condition is met, respond "Skipped: [reason]" and stop.
If conditions are borderline, proceed with the review.
## Step 1: Code Review
Perform a focused code review. Only flag issues you are confident about (85%+ confidence).
### Review Focus
- **Bugs & Logic Errors**: Incorrect logic, off-by-one errors, race conditions, nil/optional mishandling
- **Security Issues**: Hardcoded secrets, unsafe file operations, injection risks
- **Performance**: Memory leaks, unnecessary allocations, blocking main thread
- **Concurrency**: Data races, incorrect async/await usage, actor isolation issues
- **Swift Best Practices**: Force unwraps in production code, missing error handling at system boundaries
### Do NOT Flag
- Style preferences or formatting (handled by linter)
- Missing comments or documentation
- Trailing newlines or whitespace
- Suggestions to add extra validation or defensive coding unless there's a real risk
- Compilation errors (CI catches these)
- Pattern consistency claims without verification
## Output Rules
- Post your review using the MCP tools provided (create_review, create_inline_comment, create_or_update_comment)
- Use inline comments on specific lines for actionable issues
- Each inline comment must identify a problem, ask a question, or flag a risk
- Do NOT post praise-only or observational comments ("Good change", "Looks correct")
- Post a summary comment on the PR with your overall review
- Flag each unique issue ONCE; do not repeat across files
- Be direct and concise
- Do NOT include "Fix This" links or claude.ai URLs
## Context
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
The PR branch is pre-checked out. Use 'origin/main' as the base branch for diff comparisons.
Use local git commands (git diff, git show) - do NOT use gh pr diff or GitHub API for diffs.
<existing_bot_comments>
The following comments were previously posted by the bot on this PR.
DO NOT post new comments that duplicate these. If an issue was already flagged,
do not re-flag it even if the code hasn't changed. Only comment on NEW issues
not covered by previous comments.
${{ steps.fetch-existing-comments.outputs.bot_comments }}
</existing_bot_comments>
<existing_human_comments>
These are comments from HUMAN reviewers on this PR.
DO NOT duplicate their feedback. If a human already flagged an issue, skip it entirely.
${{ steps.fetch-existing-comments.outputs.human_comments }}
</existing_human_comments>
env:
ANTHROPIC_BASE_URL: ${{ secrets.ANTHROPIC_PROXY_URL }}
GH_TOKEN: ${{ github.token }}