Part of #1367 (Phase 4 — Platform Reach). Unblocks #115 (GitLab) and #116 (Bitbucket) — CodeRabbit supports GitHub/GitLab/Azure DevOps/Bitbucket; Pullfrog is GitHub-only (a reach advantage for us over Pullfrog if we ship it).
Problem
GitProviderName is a single-member union — literally 'github' (src/types.ts:10) — and src/git/github-provider.ts (1566 lines) is the only implementation, but GitHub-isms leak everywhere:
src/buddy.tscalls GitHub-shaped methods and embeds GitHub URL/API assumptions in PR lifecycle logicsrc/setup.tsgenerates GitHub Actions workflows only; token guidance is PAT/GITHUB_TOKEN-specificsrc/dashboard/uses GitHub issues;bin/cli.tsreadsGITHUB_TOKEN/BUDDY_BOT_TOKEN- Endpoints resolution (
src/utils/endpoints.ts) handles GHES but nothing else
Adding GitLab today would mean forking half the codebase. This issue extracts the seam without implementing GitLab/Bitbucket (those remain #115/#116).
Spec
1. Interface extraction
Define a complete GitProvider interface in src/git/provider.ts from the actual call sites (audit every githubProvider. call in buddy.ts, cli.ts, dashboard, gates):
- Branch ops: create/delete/list, stale detection
- Commit ops: commit files (both local-git and API-tree paths), file contents at ref
- PR ops: create/update/close/reopen/merge/list, reviews, review comments, comments, labels, reviewers, draft state, auto-merge enablement (#1369)
- Issue ops: create/update/list, comments, labels, pin/unpin (GraphQL on GitHub; GitLab has native pinning differences — keep
pinoptional-capability) - Checks/statuses: check-run create/update (#1382), combined status read (#1369, #1381)
- Reactions, collaborator-permission lookup (#1376)
- Capability flags:
capabilities(): { pinIssues, checkRuns, suggestions, autoMergeNative, ... }so features degrade per-platform instead of assuming
2. Terminology & URL abstraction
- Neutral core vocabulary (PR vs MR handled at the provider edge)
- All web/API URL construction moves behind the provider (
prUrl(n),compareUrl(...)— auditsrc/pr/pr-generator.tsandrelease-notes-fetcher.tsfor hardcodedgithub.comlinks; release-notes fetching of dependency repos stays GitHub-centric and is fine) - CI generation:
src/setup.tsworkflow generation gains a provider dimension (GitHub Actions now; GitLab CI templates arrive with #115)
3. Config & auth
- Widen
GitProviderNameto'github' | 'gitlab' | 'bitbucket'with validation that rejects not-yet-implemented providers with a "tracked in #115/#116" message - Token resolution becomes provider-owned (
GITHUB_TOKEN/GITLAB_TOKEN/BITBUCKET_TOKENconventions)
Tasks
- Call-site audit →
GitProviderinterface + capability flags (document each method's contract) - Refactor
GitHubProviderto implement it; move GitHub-only helpers behind the interface - Provider factory (
createProvider(config)); thread throughBuddy, CLI, dashboard, setup - URL/terminology sweep with tests asserting no
github.comliterals outside the GitHub provider + release-notes fetcher - Conformance test suite (
test/git/provider-conformance.ts) any future provider must pass — this is the real deliverable for #115/#116 implementers - Docs:
docs/advanced/providers.mddescribing the interface and how to add a provider
Acceptance criteria
- Zero behavior change on GitHub (full regression suite green)
- A mock provider passing the conformance suite can run scan→PR→dashboard end-to-end in tests
- #115/#116 become "implement the interface + CI templates" tasks with a checklist, not archaeology