pr_files inserts were running before the PR row was created via
runBatch, causing FOREIGN KEY constraint failures for all new PRs.
Moving the DELETE + INSERT into the batch ensures proper ordering.
Co-Authored-By: Paperclip <[email protected]>
When octokit.paginate returns partial results (due to rate limits or
API pagination limits), the stale PR detection would check each
"missing" PR via pulls.get but then incorrectly mark it as closed
even if data.state was still 'open'. This caused ~half of all open
PRs to be missing from the triage database.
Now checks data.state before updating and leaves open PRs alone.
Also avoids assuming closed on API errors.
Co-Authored-By: Paperclip <[email protected]>
Move the SVG import out of app.ts (tsx can't handle raw .svg imports)
and pass it as a parameter instead. worker.ts uses wrangler's bundled
import, server.ts reads from disk.
- Create merge-branch SVG icon at src/web/favicon.svg
- Serve /favicon.svg and /favicon.ico (redirect) routes in app.ts
- Add <link rel="icon"> to dashboard HTML head
- Add SVG type declaration for TypeScript imports
- Add *.svg to wrangler text rules for Cloudflare Worker
Co-Authored-By: Paperclip <[email protected]>
When running locally (via server.ts), a "Sync Now" button appears in the
stats bar. It probes GET /api/sync to detect the local server, then
POST /api/sync triggers a full GitHub sync with mutex protection.
The button is hidden on the Cloudflare Worker deployment.
- Add Deploying section to README with wrangler setup steps
- Add deployment info to CLAUDE.md for agent context
- Add .dev.vars to .gitignore (stores API token + account ID)
- Remove account_id from wrangler.toml (loaded from env instead)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Ensures agents updating src/scoring.ts also update README.md,
and adds a reminder in the README itself for human contributors.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Explains the PR triage dashboard, links to the live deployment,
and describes all ten scoring signals in plain English so
contributors can understand how their PRs are ranked.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Moves all scoring constants, thresholds, detection patterns, and
scoring functions out of routes.ts into a dedicated scoring module.
This makes scoring changes self-contained and easier to review.
No functional changes — routes.ts and filter.ts now import from scoring.ts.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Extends the composite scoring from 6 to 10 signals (max 180):
- Issue link detection: +10 for PRs linking GitHub issues (closes/fixes/resolves #)
- Freshness scoring: 0-10 tiered by age (<1d=10, 1-3d=8, 3-7d=5, 1-2w=2)
- Test file detection: +10 for PRs including test files
- Thinking Path detection: +10 for PRs with "Thinking Path" in description
- Smooth merge rate gradient: <20%=-30, 20-39%=-15, 40-59%=0, 60-79%=+5, 80%+=+10
- Remove Labels column from list view
- Add all 10 scoring components to hover tooltip and detail breakdown
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Contributor score now affects composite ranking as a centered +/- factor
(-25 to +25) instead of always-positive. Authors with low merge rates
get penalized, dropping them in the list. Hovering over the Score column
shows a breakdown table of all six scoring components. Also fixes the
stats header showing total PRs instead of open PRs count.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sync recent merged/closed PRs during sync to build author history.
Compute a contributor priority score (0-100) based on: newcomer bonus
for first-time contributors, track record from merged PRs, merge rate
quality signal, and open PR load for active contributors needing review
bandwidth. Display as a card on the PR detail page with score breakdown.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Adds a SKILL.md under .claude/skills/pr-triage/ so agents can discover
and use the PR Triage API endpoints. Updates .gitignore to allow
.claude/skills/ to be tracked.
Co-Authored-By: Paperclip <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Detect related and potentially copied PRs on each PR detail page using
Jaccard similarity on title word sets and body text trigram shingles.
During sync, changed files per PR are fetched via GitHub's listFiles API
and stored for display. The similar PRs table shows title/body match
percentages, file overlap counts, and color-coded relationship labels
(potential copy, likely duplicate, similar topic, related). Each row
links to both the internal detail page and the GitHub PR.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Adds a new LOC component (0-15 points) to the composite score using
logarithmic decay: small PRs (~50 LOC) earn ~12pts, medium (~200 LOC)
~8pts, large (~1000 LOC) ~6pts. Max score is now 115.
Updated scoring in filter.ts, routes.ts, scoreBreakdown, the /scoring
endpoint docs, and the dashboard UI. Added 7 new tests.
Co-Authored-By: Paperclip <[email protected]>
Needed to backfill data when new columns (like LOC) are added after
PRs were already cached.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The D1 REST /query endpoint only accepts a single statement per request,
not an array. The native D1 binding supports .batch() but the HTTP client
needs sequential calls.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Skip detail fetches for PRs unchanged since last sync, batch all DB
writes per PR into a single round-trip, and avoid mergeable retry
delays when head_sha hasn't changed.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Store additions, deletions, and changed_files from GitHub API in the
pull_requests table. Display as +N -N in a new sortable LOC column
between Labels and Conflicts.
Co-Authored-By: Paperclip <[email protected]>
The detail endpoint was changed to return a flat object with computed
fields (compositeScore, ciStatus, labels, scoreBreakdown) but the
frontend template still referenced the old nested shape (d.pr, d.scores).
Also improved detail view to show score breakdown card and labels.
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Human comment count in composite scoring (excludes bots)
- FTS5 full-text search for PR comments with BM25 ranking
- PR state tracking (open/merged/closed) with sync detection
- GitHub labels synced and displayed with matching colors
- Pagination (25 per page) on PR list
- Search bar on main page, search as shareable page with query string
- Last activity column (latest of code push or comment) with time-ago display
- CI column compacted to colored dots
- Full agent-friendly API: /labels, /authors, /scoring, filters (author, label, sort)
- PR detail endpoint with score breakdown
- SKILL.md documenting all API endpoints for agent consumption
Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Async DbClient interface with three backends: SQLite (local), D1 REST
API (CLI remote), and D1 Worker binding (deployed, no tokens exposed)
- Hono web dashboard with PR list, filters, sorting, and detail views
- Deploy to Cloudflare Workers via wrangler (D1 binding, read-only)
- Fix greptile parser to handle HTML <h3> format from bot comments
- Make GITHUB_TOKEN and ANTHROPIC_API_KEY optional (only required for
sync and review commands respectively)
- Add dotenv for .env loading, docker wrapper script
- Optimize list query from N+1 to single SQL (48s -> 0.7s on D1)
Co-Authored-By: Claude Opus 4.6 <[email protected]>
GitHub sync with rate-limited Octokit, greptile score parsing, CI status
aggregation, composite scoring/filtering, and LLM review pipeline with
prompt injection defenses (random boundary delimiters, output validation).
Co-Authored-By: Claude Opus 4.6 <[email protected]>