Skip to content

feat: gh-prs-ready-need-review — GitHub PR counters to Gather#11

Open
yaustar wants to merge 8 commits into
mainfrom
steven/github-in-out
Open

feat: gh-prs-ready-need-review — GitHub PR counters to Gather#11
yaustar wants to merge 8 commits into
mainfrom
steven/github-in-out

Conversation

@yaustar

@yaustar yaustar commented Jul 1, 2026

Copy link
Copy Markdown

Summary

  • Adds @webhook-objects/gh-prs-ready-need-review, a polling bot that mirrors two GitHub PR metrics to Gather Smart Object counter presets via @webhook-objects/client
  • Tracks open ready-for-review PRs you authored or are assigned to (14-day window) and unapproved direct review requests naming you directly (7-day window)
  • TypeScript package with start, ping, and reset scripts; config via packages/gh-prs-ready-need-review/.env (see .env.example)
  • Uses --env-file-if-exists=.env so missing .env fails with a clear config error instead of Node exit code 9
  • Vitest coverage for config parsing and GitHub search date cutoffs

Test plan

  • Copy .env.example to .env and fill in GitHub + Gather webhook credentials
  • pnpm --filter @webhook-objects/gh-prs-ready-need-review ping — both objects respond to webhook.ping
  • pnpm --filter @webhook-objects/gh-prs-ready-need-review reset — legacy activity slots cleared, counters reset
  • pnpm --filter @webhook-objects/gh-prs-ready-need-review start — poll cycle logs PR counts and pushes counter.set
  • pnpm --filter @webhook-objects/gh-prs-ready-need-review test — unit tests pass

Note

Low Risk
Self-contained new package with read-only GitHub API usage and outbound signed webhooks; secrets stay in local .env with no server-side deployment in this diff.

Overview
Adds @webhook-objects/gh-prs-ready-need-review, a long-running poller that pushes two GitHub PR counts to separate Gather Smart Object counter presets via @gathertown/webhook-object-sdk (Octokit search API, not gh CLI).

Open PRs (14-day window): non-draft open PRs in GITHUB_REPO where the authenticated user is author or assignee—two searches merged and deduped because search cannot OR user qualifiers.

Review requests (7-day window): open PRs with a direct user-review-requested for the user, no review:approved, created in the last week.

Config is env-based (.env.example, validated URLs/secrets, POLL_INTERVAL_MS ≥ 10s). Scripts: start (poll loop), ping, reset (clears legacy activity slots and counter.reset for migration off inbox-style publishing). Vitest covers repo parsing and cutoff dates. Root .gitignore adds .DS_Store and .env; pnpm-workspace.yaml exempts Gather webhook SDK packages from minimum release age.

Reviewed by Cursor Bugbot for commit 8ec3e8f. Bugbot is set up for automated code reviews on this repo. Configure here.

Steven Yau and others added 4 commits July 1, 2026 18:08
Comment thread packages/gh-prs-ready-need-review/src/github/client.ts Outdated
Comment thread packages/gh-prs-ready-need-review/README.md
Comment thread packages/gh-prs-ready-need-review/package.json Outdated
@bgreenier

Copy link
Copy Markdown
Collaborator

btw - https://github.com/gathertown/webhook-objects/tree/main/packages/gh-prs-inbox isn't that far off from this, from what i'm seeing. Yours is more robust for sure

Replace raw fetch calls with the octokit SDK and add --coverage to the
package test script per review feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread packages/gh-prs-ready-need-review/src/index.ts Outdated
Comment thread packages/gh-prs-ready-need-review/.env.example Outdated
Comment thread packages/gh-prs-ready-need-review/.env.example Outdated

@bgreenier bgreenier left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks like a little bit of lockfile hell here - can you nuke all the *lock* json/yaml files and then pnpm i

Remove explicit SIGINT handler, use production URLs in .env.example,
and regenerate lockfiles (drop stray package-lock.json).

Co-authored-by: Cursor <cursoragent@cursor.com>
@yaustar

yaustar commented Jul 1, 2026

Copy link
Copy Markdown
Author

[felix] Nuked package-lock.json and the branch lockfile, regenerated pnpm-lock.yaml via pnpm install --merge-git-branch-lockfiles in 0fd0edd.

@yaustar
yaustar marked this pull request as ready for review July 2, 2026 10:40

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0fd0edd. Configure here.

q: query,
per_page: perPage,
});
return (data.items ?? []) as GitHubPullRequest[];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Search capped at one page

Medium Severity

searchIssues calls GitHub issue search once with per_page 100 and returns only data.items, with no pagination. When a query matches more than 100 PRs, extra results are dropped, so listOpenPrsForUser and listOpenReviewRequestedPrsForUser can under-report counts pushed via counter.set.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0fd0edd. Configure here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is fine. If we have more than 100 items, then we've gone past the size of the inbox anyway.

The workspace @webhook-objects/client is being removed in favor of the
npm-published SDK (see #15): createWebhookObjectClient replaces new
Client, send takes (type, data) and stamps the timestamp itself, ping()
replaces requestMetadata(), and the client type is WebhookObjectClient.
The @gathertown packages join the minimumReleaseAge exclusions since
they are first-party.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

3 participants