Skip to content

jmprieur/pr-inbox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

141 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pr-inbox

A personal command-line PR review inbox across GitHub.com, GitHub Enterprise, and Azure DevOps. Aggregates assigned PRs, tracks per-PR review state across sessions, and bootstraps a Copilot review session with full context.

Status: v0.2 License: MIT .NET 10 Tests: 425

pr-inbox is the harness for review-at-scale. It does not review code itself — it tells you which PRs need attention, what changed since the last time you looked, and hands a fully-bootstrapped brief to the Copilot session that will run the actual dual-model-review.

PR Inbox — one triage inbox across GitHub.com, GitHub Enterprise, and Azure DevOps. Repo, title, and author columns are redacted.

Looking for the "what can I do, when, why" tour?USER_GUIDE.md — end-to-end walkthroughs of every surface.


Why this exists

Reviewing many PRs at scale across three platforms with two identities is manual. The pain is not the review skill itself — that's mature (dual-model-review with Opus 4.7 + GPT-5.5, asymmetry pattern stable at N=6). The pain is:

Pain What pr-inbox does about it
No single inbox across GitHub.com / GHE / ADO sync pulls all sources; list shows one unified view
Per-PR state lost between sessions (last reviewed SHA, posted comments, resolved threads) Local SQLite registry; immutable snapshots; never hard-deletes
Re-entry cost — "let me check that PR again" rebuilds context from zero review produces an immutable brief.md with diff-since-last + open threads + recent bot comments
Curation tracking (the 95%+ inline filter) is in your head only Each review creates a recorded review run; curation lands in v0.2
Convergence/asymmetry telemetry hand-counted Append-only schema captures the data; queries land in v0.3

Status

v0.2 — working. Daily-driver against ~60 real PRs/day across GitHub.com, GitHub Enterprise, and Azure DevOps. Multi-identity GitHub.com (e.g. a personal + an EMU account) is supported via the Web UI Settings picker. The surface-by-surface walkthrough — CLI verbs, Web UI pages, publisher — lives in USER_GUIDE.md.

Out of scope (deferred): followup verb, convergence/asymmetry telemetry dashboards (data is captured, queries land in v0.3).


How it works

flowchart TD
    subgraph adapters ["Source adapters · IPrReadSource"]
        direction LR
        GH["GitHub.com"]
        GHE["GitHub Enterprise"]
        ADO["Azure DevOps"]
    end

    subgraph registry ["SQLite registry · %APPDATA%\PrInbox\pr-inbox.db"]
        Tables["pull_requests · pr_source_bindings · pr_snapshots<br/>observed_threads · review_runs · posted_reviews<br/>sync_runs · ui_preferences"]
    end

    subgraph verbs ["Verbs"]
        direction LR
        Sync["sync<br/>refresh registry"]
        List["list<br/>triage table"]
        Review["review<br/>brief.md + immutable run dir"]
        Config["config<br/>identities · projects · doctor"]
    end

    adapters --> registry
    registry --> verbs
Loading

Credentials — delegate, never store

pr-inbox does not store tokens, ever. It delegates to the credential authorities you already use:

Source Token path
GitHub.com (default identity) gh auth token --hostname github.com
GitHub.com (explicit identity) gh auth token --hostname github.com --user <login>
GitHub Enterprise gh auth token --hostname <ghe-host> (with --user <login> for explicit identity)
Azure DevOps Azure.Identity.AzureCliCredential (uses az under the hood; resource 499b84ac-1321-427f-aa17-267ca6975798)

Why: no PATs to manage, no secret storage to harden, no leakage risk. Tokens are minted on demand and never written to disk by this tool. When a gh.com source is bound to an explicit identity, the token provider pins gh auth token to that login so two same-host sources (e.g. personal + EMU) fetch with the correct credentials independently.

Per-PR identity

Platform Display identity Stable identity (durable key)
GitHub.com gh.com:owner/repo#N gh.com:<repo_id>#<pr_id>
GitHub Enterprise ghe.<host>:owner/repo#N ghe.<host>:<repo_id>#<pr_id>
Azure DevOps ado:<org>/<project>/<repo>#N ado:<org>/<projectGuid>/<repoGuid>#N

Display id is what humans/commands use. Stable id is the join key the registry trusts when repos/projects rename.

Review handoff

pr-inbox review <id> and the Web UI's Review button do the same work: refresh that one PR's snapshot, compute what's new since the last brief, write an immutable run directory containing brief.md

  • metadata.json, then hand it to a Copilot session. Re-reviewing appends a new run dir — nothing is ever overwritten. In the Web UI each review opens in its own Windows Terminal window by default; the One tab per review setting groups them as tabs in a single window instead. Step-by-step walkthrough lives in USER_GUIDE.md § What "Review" actually does.

Install

Required to build, sync, and list

  • .NET 10 SDK
  • gh — GitHub CLI, authenticated for github.com and any GHE host you use (gh auth login --hostname github.com)
  • az — Azure CLI, signed in (az login) — only needed if you add ADO sources

Required to click "Review" (launcher tab)

  • PowerShell 7+ (pwsh) — tools/launch-review.ps1 runs under it
  • Windows Terminal (wt.exe) — each Review opens in its own window by default (or as a tab, with One tab per review)
  • GitHub Copilot CLI (copilot) on PATH, authenticated to your model provider — the launcher invokes it. Microsoft users: set the launch command to agency copilot … (Settings → Review launcher, or PRINBOX_REVIEW_COMMAND) to drive it through the internal agency wrapper.
  • Read access to the plugin source. Default is the dual-review plugin published from this repo (market:dual-review@jmprieur/pr-inbox). To use a local clone or a different plugin, point PRINBOX_REVIEW_PLUGIN at it (see Review launcher overrides)

From source (until published to NuGet):

git clone <repo-or-path>
cd pr-inbox
dotnet pack -c Release src/PrInbox.Cli/PrInbox.Cli.csproj
dotnet tool install --global --add-source src/PrInbox.Cli/nupkg JmPrieur.PrInbox

Verify:

pr-inbox --help
pr-inbox config doctor   # checks gh + az auth, ADO project access

Quick start

Option 0 — Fresh clone, one click (recommended for new users)

Double-click Start.bat in the repo root. It builds PrInbox.slnx and launches the PR Inbox tray app — a small "PR" icon in the Windows notification area (click the ^ arrow near the clock if you don't see it). The tray starts the web server hidden (no console window) and opens your default browser to the Inbox. On first run the browser lands on /settings; add a source and you're going.

Right-click the tray icon for Open PR Inbox, Restart, View log, and Stop & Exit (which shuts the server down gracefully). Double-click the icon to reopen the dashboard.

Profiles (clean vs. internal). The shipped defaults are generic — just a Public identity class on github.com and the public copilot review command; nothing Microsoft-specific is in the box. To switch modes:

Both just wrap pr-inbox config import <file>, which only ever rewrites the identity classes, review command, and model — your sources / ADO references are never touched. Import any org's profile the same way: pr-inbox config import <file>.

Option A — Web UI, manually

# 1. Build
dotnet build PrInbox.slnx

# 2. Start the web UI. On first run, it routes you to /settings to
# add at least one source (no CLI required).
$env:ASPNETCORE_URLS = "http://localhost:7341"
dotnet run --project src/PrInbox.Web

# 3. Open http://localhost:7341 — you'll be redirected to /settings.
# Click "Add GitHub.com" (one click) and/or "Add GitHub Enterprise…"
# and/or "Add ADO project…". Run the "Doctor" check to verify auth.
# Then go back to the Inbox tab and click Review on any row.

Option B — CLI

# 1. Initialize config (one time)
pr-inbox config init

# 2. Add the sources you want to track
pr-inbox config add-source github github.com
pr-inbox config add-source github-enterprise <your-host>   # optional
pr-inbox config add-ado-project mseng Context       # one per ADO project

# 3. Verify auth is working
pr-inbox config doctor

# 4. Pull your inbox
pr-inbox sync

# 5. See what needs attention
pr-inbox list

# 6. Start a review session on a specific PR
pr-inbox review https://github.com/agency-microsoft/playground/pull/4248
# Prints: brief path + recommended `copilot` invocation

Both surfaces read/write the same %APPDATA%\PrInbox\config.json. Use whichever feels right; the Web UI's Settings page additionally supports multi-identity GitHub.com (one source per gh login, e.g. personal + EMU) via an inline picker on + Add GitHub.com — the CLI's config add-source still defaults to a single default-identity source.


Review launcher overrides

The review launch command is configurable in the web UI under Settings → Review launcher → Launch command. It defaults to the public GitHub Copilot CLI, which loads the dual-review plugin from a local directory (--plugin-dir) and selects its agent by id. Placeholders: {plugindir} (the bundled plugin path, resolved automatically), {plugin}, {model}, {agent}:

copilot --plugin-dir {plugindir} --model {model} --agent {agent}

Microsoft users point it at the agency wrapper, which uses the marketplace plugin spec and wrapper-only flags such as --mcp:

agency copilot --mcp workiq --mcp teams --plugin {plugin} --model {model} --agent {agent}

tools/launch-review.ps1 also honours these env vars (Settings takes precedence when launching from the web UI):

Variable Default Purpose
PRINBOX_REVIEW_COMMAND copilot --plugin-dir {plugindir} --model {model} --agent {agent} Launch command template (owns the CLI + flag syntax)
PRINBOX_REVIEW_AGENT dual-review:dual-model-review Value for the {agent} placeholder
PRINBOX_REVIEW_PLUGIN market:dual-review@jmprieur/pr-inbox Value for the {plugin} placeholder (agency marketplace spec)
PRINBOX_REVIEW_MODEL claude-opus-4.8 Value for the {model} placeholder
PRINBOX_PLUGIN_DIR (auto-resolved) Overrides the {plugindir} path (bundled plugins/dual-review)

First-run troubleshooting

Symptom Likely cause Fix
config doctor red on GitHub Not signed in to gh gh auth login --hostname github.com
config doctor red on Azure DevOps az login expired, or you don't actually have an ADO source az login, or skip the ADO step
sync runs but inbox is empty gh identity differs from the login the PRs are assigned to config doctor prints the identity it's using; compare with PR assignee. If you have multiple gh logins, add each as its own source via Settings → + Add GitHub.com
Review tab opens then exits immediately with "copilot: command not found" Review CLI not on PATH Install the GitHub Copilot CLI, or set the launch command to a CLI you have (Settings → Review launcher; Microsoft: agency copilot …)
Review tab opens but plugin fetch fails No access to the configured plugin source Point PRINBOX_REVIEW_PLUGIN at a local clone or a plugin you can reach
Review tab opens but model call fails Review CLI not authenticated to the chosen model Authenticate your CLI to its providers, or change PRINBOX_REVIEW_MODEL
Web UI says port already in use Another instance running, or stale Kestrel Get-NetTCPConnection -LocalPort 7341 | Stop-Process -Force

Configuration

%APPDATA%\PrInbox\config.json — managed via pr-inbox config verbs. Holds source definitions + ADO project list + bot login overrides. Never contains tokens.

Example:

{
  "schemaVersion": 1,
  "sources": [
    { "id": "gh.com", "kind": "github", "host": "github.com", "identity": "default" },
    { "id": "gh.com:jenny_microsoft", "kind": "github", "host": "github.com", "identity": "jenny_microsoft" },
    { "id": "ghe.contoso", "kind": "github-enterprise", "host": "github.contoso.com", "identity": "default" }
  ],
  "ado": {
    "projects": [
      { "org": "mseng", "project": "Context" }
    ]
  },
  "bots": {
    "extraLogins": ["Copilot"]
  }
}

identity of "default" means "use whichever gh account is active for the host at sync time." Any other value pins the source to a specific gh login — the token provider passes gh auth token --user <identity>. Add identity-bound sources via the Web UI's Settings → + Add GitHub.com picker. Two sources for the same host with different identities sync independently and surface under distinct chips in the Inbox.


Repository layout

pr-inbox/
├── src/
│   ├── PrInbox.Cli/         # global tool entry point (pr-inbox verbs)
│   ├── PrInbox.Core/        # domain, storage, migrations, credentials
│   ├── PrInbox.Sources/     # GitHub + GHE + ADO read adapters; fake source
│   ├── PrInbox.Publishers/  # GitHub + ADO review publishers (write side)
│   └── PrInbox.Web/         # Blazor Server inbox + review launcher
├── tests/
│   ├── PrInbox.Tests/             # xUnit + FluentAssertions, in-memory SQLite
│   └── PrInbox.Publishers.Tests/  # publisher round-trip tests
├── tools/
│   └── launch-review.ps1    # spawned by ReviewLauncher inside each wt tab
├── README.md                # this file
├── ARCHITECTURE.md          # design rationale + rubber-duck critique log
├── AMBIGUITIES.md           # open design decisions (read first in the morning)
├── LICENSE                  # MIT
├── global.json              # pins .NET 10.0.202
├── Directory.Build.props    # nullable, implicit usings, treat warnings as errors
├── Directory.Packages.props # central package management
├── NuGet.config             # nuget.org only
└── PrInbox.slnx             # .NET 10 XML solution

Development

dotnet restore PrInbox.slnx
dotnet build PrInbox.slnx
dotnet test PrInbox.slnx

Conventions:

  • C# 13, nullable enabled, implicit usings, file-scoped namespaces
  • Treat warnings as errors (CI build matches local build)
  • xUnit + FluentAssertions; in-memory SQLite for storage tests
  • Async + cancellation tokens everywhere
  • Logging via Microsoft.Extensions.Logging (Serilog file sink under %APPDATA%\PrInbox\logs\)

License

MIT. See LICENSE.


Acknowledgements

Co-created by Jean-Marc Prieur and Ember (GitHub Copilot CLI), 2026-05-13 onward. Plan and rubber-duck critique in ARCHITECTURE.md; open design decisions in AMBIGUITIES.md.

About

Personal command-line PR review inbox across GitHub.com, GHE, and Azure DevOps

Resources

License

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors