A browser extension that guides you through pull requests with live, LLM-powered explanations as you review code. Renders a sidebar with layered progressive disclosure: PR summary, file-level explanations, and hunk-level detail.
When you open a GitHub PR's "Files changed" tab, Sherpa:
- Summarizes the PR — one LLM call using the title, description, commit messages, and file list
- Explains files on demand — click or scroll to a file to get a contextual explanation using the full diff and file content
- Explains hunks on demand — drill into individual code changes for line-level detail
Explanations are streamed in real time and cached locally so revisiting a PR is instant. API keys are obfuscated at rest (AES-GCM-based, not true encryption) and only held in memory during the active session.
See ARCHITECTURE.md for a detailed breakdown of the extension's internals.
See SECURITY.md for details on how Sherpa handles API keys, OAuth tokens, and other security considerations.
| Layer | Technology |
|---|---|
| Extension framework | WXT (Manifest V3, Vite-based) |
| Side panel UI | Preact + Tailwind CSS |
| LLM | Vercel AI SDK with provider adapters |
| Backend | Cloudflare Worker (OAuth + explanation cache) |
| Language | TypeScript |
| Tests | Vitest |
For a complete step-by-step guide covering the extension, Cloudflare Worker, GitHub App, and LLM provider setup, see SETUP.md.
Requires mise for tool management (installs node + pnpm from .mise.toml). After installing mise, activate it in your shell:
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc # or bash/fish — see mise docsQuick start for development:
mise install # install node + pnpm (from .mise.toml)
pnpm install
cp browser/.env.example browser/.env # edit with your values
cd browser && pnpm run dev # opens Chrome with hot reload| Variable | Description | Required |
|---|---|---|
VITE_WORKER_URL |
Cloudflare Worker URL (or http://localhost:8787 for local dev) |
Yes |
VITE_GITHUB_CLIENT_ID |
GitHub App client ID | Yes |
cd browser
pnpm run build # builds to .output/chrome-mv3/
pnpm run zip # builds and creates a zip for distribution
pnpm test # run testsTo run the full stack locally you need two terminals — one for the extension and one for the Cloudflare Worker.
mise install # install node + pnpm (one-time)
pnpm install # from root — installs all workspace deps
cd browser
pnpm run devThis starts the WXT dev server with hot reload and opens Chrome with the extension loaded. Note your extension ID from chrome://extensions.
cd worker
pnpm run dev # starts wrangler dev on localhost:8787Create a worker/.dev.vars file with your secrets:
GITHUB_CLIENT_ID=your_github_app_client_id
GITHUB_CLIENT_SECRET=your_github_app_client_secret
EXTENSION_ID=your_chrome_extension_id
Set EXTENSION_ID to the value from chrome://extensions so that CORS allows requests from your local extension.
Set VITE_WORKER_URL in your browser/.env file:
VITE_WORKER_URL=http://localhost:8787
Alternatively, you can change the Worker URL in the extension's settings panel after loading it.
GitHub OAuth requires a publicly reachable callback URL, so you need to tunnel your local worker. Using Cloudflare Tunnel:
cloudflared tunnel --url http://localhost:8787Or with ngrok:
ngrok http 8787Then:
- Set
VITE_WORKER_URLin yourbrowser/.envto the tunnel URL (e.g.https://abc123.trycloudflare.com) - Update your GitHub App's Authorization callback URL to
<tunnel-url>/callback - Restart
pnpm run dev(inbrowser/) so the extension picks up the new URL
For a ~2400-line, 30-file PR, a full read-through costs roughly $0.10–0.30 depending on the LLM provider. Lazy loading means most reviews cost far less since you won't expand every file and hunk.
Generated and lock files (e.g. package-lock.json, yarn.lock, *.min.js) are automatically kept collapsed during scroll sync so they don't clutter the sidebar. A small "gen" badge appears next to their filename. You can still expand them manually by clicking.
Default patterns:
package-lock.jsonyarn.lockpnpm-lock.yaml*.lockgo.sum*.min.js*.min.css*.generated.**.g.dart*.pb.go
- GitHub DOM fragility — The content script relies on GitHub's CSS class names, which are not a stable API. All selectors are isolated in
browser/src/providers/github/selectors.tsfor easy updates when GitHub changes their markup. A validation check on load warns if expected elements aren't found. - Token budget — Very large PRs with full file context can approach provider token limits. Mitigated by lazy loading at the file/hunk level rather than sending entire PRs.
- GitHub only — The provider abstraction (
CodeReviewProvider+DOMAdapter) is designed for adding GitLab and other platforms, but only GitHub is implemented today.
