Repository navigation
feat(cli): void github link — connect GitHub from any login provider (RFC 0074) - #230
Merged
Merged
Conversation
Adds `void github link`, which links the logged-in Void account to a GitHub identity by driving the platform's 3-endpoint link flow with a localhost + PKCE handshake (mirrors `void auth login`). - Extract the inline localhost-callback server from `runLogin` into a shared, exported `awaitBrowserCallback` helper; refactor `runLogin` to use it (behavior-preserving). Export the PKCE helpers `createCodeVerifier` / `createCodeChallenge`. - Add `PlatformClient.getGithubLinkUrl` and `completeGithubLink`. - Add `runGithubLink(root, client)`; wire `link` into github args, dispatch, CLI hint, help, and docs. - New tests: `auth-callback.test.ts` (real coverage of the previously-untested localhost flow) and `github-link-cmd.test.ts` (conflict/missing-code paths), plus client + args coverage. Regression gate `auth-login` stays green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When `void github install` returns a 403 with the stable code `github_identity_required`, run the GitHub link flow inline and retry the install URL exactly once instead of telling the user to `void auth login` (which risks forking into a second account). The link step is injectable (`runInstall(root, client, linkIdentity)`) so tests can supply a fake linker without a real localhost server or browser. Only a `github_identity_required` 403 triggers the auto-link; every other error is rethrown unchanged. If the post-link retry still fails, exit(1) with actionable guidance. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ovider void github install now auto-runs the link flow on github_identity_required (RFC 0074), so the install/link cross-references were stale. Clarify that Deploy-on-GitHub works from any login provider after a one-time identity link. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ty_conflict The link-complete server now returns two distinct 409 codes (RFC 0074 F1): github_identity_conflict (the GitHub account belongs to another Void account) vs github_already_linked (your account already has a different GitHub identity). runGithubLink mapped any 409 to the former's wording; key on err.code so each case shows the right message. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tall retry errors F3: awaitBrowserCallback now runs a generic finalize() hook inside the request handler before the success page. On finalize success it shows the success page and resolves with the result; on finalize throw it shows the failure page and rejects. This restores base runLogin behavior (exchange in the request path, failure page on exchange failure) and makes `void github link` show success only after completeGithubLink succeeds. runLogin and runGithubLink refactored onto the hook. F4: runInstall's post-link retry no longer swallows all errors — it only keeps the actionable link/install guidance when the retry is still a 403 github_identity_required, and rethrows every other failure (401/426/500/other). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
void github linkand makesvoid github installwork for any Void login (Google, GitHub, SSO) — the CLI side of RFC 0074 (decouple GitHub-for-deploys from the login provider). Pairs with the platform PR (void-platform) that adds the link routes; this PR is the framework/CLI half.Changes
void github link— links the current Void account to a GitHub identity via a localhost + PKCE handshake (mirrorsvoid auth login). Drives the platform's 3-endpoint flow:GET /github/link-url(authed) →GET /github/link-callback(public, returns a PKCE-boundlink_codeto localhost) →POST /github/link/complete(authed, binds to the bearer-token holder).void github installauto-links — on agithub_identity_required403 it runs the link flow then retries once; any other error surfaces normally. Removes the old "runvoid auth loginand choose GitHub" message (which risked forking a second account).awaitBrowserCallback— extracted the localhost OAuth callback server fromrunLogininto a shared, tested helper with afinalizehook (the token/identity exchange runs in the request path, so the browser only shows success after it actually succeeds).runLoginis behavior-preserving.getGithubLinkUrl/completeGithubLink;linkwired into args/help/CLI;docs/reference/cli.mdupdated.Security
The link flow uses deferred bind: the public callback never binds an identity — it only mints a stateless, PKCE-bound
link_codedelivered to the initiator's own localhost; the bind happens in the authenticated/completekeyed on the token holder. This defeats the account-linking confused-deputy (an attacker can only ever link their own identity). Reviewed viacodex adversarial-review; findings fixed and test-pinned.Tests
Feature unit tests green (auth-callback, auth-login regression, github-link/install/args/client). The repo's browser-based integration tests require Playwright browsers (unrelated to this CLI-only change).
Note
Requires the paired platform change; deploy needs
<API>/github/link-callbackregistered as a GitHub App callback URL.🤖 Generated with Claude Code
Note
Medium Risk
Touches account-linking and localhost OAuth callback behavior; mistakes could affect login UX or identity binding, though behavior is heavily unit-tested and defers binding to authenticated
/complete.Overview
Adds
void github linkso users logged in with Google or other SSO can bind a GitHub identity to their Void account via localhost + PKCE (same pattern asvoid auth login), using new platform APIsgetGithubLinkUrl/completeGithubLink. 409 conflicts get clear messages for “GitHub already on another Void account” vs “Void account already has a different GitHub.”void github installno longer tells users to re-login with GitHub ongithub_identity_required. It runs the link flow inline and retries the install URL once; other errors after linking still propagate normally.Refactors OAuth localhost handling into shared
awaitBrowserCallbackwith afinalizehook so token/link exchange runs in the request path before the browser sees success;runLoginis rewired on top with preserved?token=/ missing-code behavior. ExportscreateCodeVerifier/createCodeChallengefor the link flow.Wires
linkthrough args, help, and CLI docs; adds unit tests for the callback helper, login exchange failure, install auto-link, link command, and client methods.Reviewed by Cursor Bugbot for commit 63bd41b. Bugbot is set up for automated code reviews on this repo. Configure here.