Skip to content

feat(cli): org-shared GitHub installations — void github join + non-owner connect - #251

Merged
Brooooooklyn merged 6 commits into
mainfrom
feat/org-shared-github-cli
Jul 5, 2026
Merged

Brooooooklyn merged 6 commits into
mainfrom
feat/org-shared-github-cli

Conversation

@Brooooooklyn

@Brooooooklyn Brooooooklyn commented Jul 4, 2026 •

Copy link
Copy Markdown
Member

Summary

The CLI half of Org-Shared GitHub App Installations (RFC 0077) — letting multiple Void users who are members of the same GitHub org each connect their own projects to repos under one shared org App installation, without a confused-deputy.

Pairs with the platform API PR (voidzero-dev/void-platform), which adds the server-side join / connect-authorize / revocation routes this CLI drives.

What's here (3 commits)

  • void github join — discovery + eligibility. Runs the GitHub user-OAuth authorize round-trip (PKCE + HMAC state, no token stored), and on callback confirms via GET /user/installations that the caller can manage the org installation, then upserts a TTL-cached membership. Afterwards void github installations lists the shared install and connect is eligible.
  • Connect-authorization round-trip for a non-owner member — a per-repo authorize round-trip whose callback verifies, with the connecting user's own token, that they can access the target repo, then mints a short-lived signed connect-grant the CLI redeems. A member can only connect a repo they personally can access.
  • Docs for the two flows.

Notes

  • Deferred-bind model reuses the RFC 0074 scaffold (PKCE + HMAC state, no Void user id in state).
  • Fails closed when the App's user-OAuth is not configured.
  • Non-TTY usage requires --branch (no interactive prompt).

🤖 Generated with Claude Code


Note

Medium Risk
Changes GitHub connect authorization and new OAuth round-trips; mistakes could block legitimate connects or weaken repo-access checks, though behavior is fail-closed and pairs with platform APIs.

Overview
Adds void github join so teammates can adopt org GitHub App installations someone else installed, via the same localhost + PKCE browser flow as void github link, backed by new platform join URL/complete APIs. Fails closed with a clear message when org-installation sharing is not enabled on the instance.

void github connect now handles non-owner org members: on 403 connect_authorization_required, it runs a per-repo authorize round-trip (grant returned in the callback), then retries connect once with connectGrant and codeVerifier. Non-TTY/CI exits immediately instead of hanging on a browser flow; retry 403s get auth-specific errors instead of the generic “no project access” message.

CLI wiring, help, and CLI reference docs document both flows. Unit tests cover argument parsing, PlatformClient calls, and command behavior for join and connect authorization.

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

Brooooooklyn and others added 3 commits July 3, 2026 23:55
…11/13)

Add the `void github join` command: an org member runs it to discover and
join the GitHub App installations they can access, gaining a TTL-cached
membership so `void github installations` lists them and `void github
connect` becomes eligible. Mirrors `void github link`'s localhost + PKCE
deferred-bind handshake against the platform JOIN routes
(join-url → join-callback → join/complete), fails closed with a friendly
message when org-sharing OAuth is not configured (503), and reports the
number of installations joined.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…sk 12/13)

When `void github connect` returns 403 connect_authorization_required
(the caller is an org member, not the installation owner), run a per-repo
authorize round-trip (getGithubConnectAuthorizeUrl → localhost callback
carrying connect_grant) and retry the connect exactly once with the
grant + PKCE verifier. The interception precedes the generic 403 handler
so a member is never wrongly told "no access to this project"; a rejected
grant (expired / identity mismatch) surfaces a clear retry message; the
owner path is unchanged. repo_not_accessible is surfaced with a friendly
per-repo message during the round-trip.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the `void github join` reference (discover + join a shared org's
GitHub App installations) and a "Connecting as an organization member"
note under `void github connect` describing the one-time per-repo browser
authorization a non-owner member completes before connecting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 4, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_faec2d08-58e7-442a-a584-4481f3011361)

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4588c40802

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/void/src/cli/github-cmd.ts
…b CLI conflicts)

Unions #247 (executor/workflow prompts + void github status) with the
org-shared additions (void github join + non-owner connect-authorize
round-trip) across cli.ts, github-args.ts, github-cmd.ts, help.ts,
cli.md, and github-args.test.ts. Also picks up v0.10.3/v0.10.4 version
bumps and the #249 R2 content-type fix from main.
@cursor

cursor Bot commented Jul 4, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_1f59f593-cbe8-4377-a0bc-af90e5c6d884)

Brooooooklyn and others added 2 commits July 4, 2026 20:38
A non-owner org member connecting a repo under a shared org installation gets
a 403 connect_authorization_required and runConnect starts an interactive
authorize round-trip. That flow opens a browser and blocks on a localhost
callback (auth.ts, ~5-min timeout) with no TTY guard, so a non-interactive
`void github connect --repo o/r --branch main` in CI hung for 5 minutes then
died instead of failing closed like the --branch / --repo non-TTY guards.

Guard the round-trip on isTTY: in a non-interactive shell, fail closed
immediately with an actionable "run locally to authorize" message. Migrate the
three round-trip unit tests to the interactive (isTTY=true) path they actually
exercise and add a regression test for the non-TTY fail-closed behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 4, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_bdb2a114-e388-46a8-af9b-2533ce44f687)

@Brooooooklyn
Brooooooklyn merged commit f50b223 into main Jul 5, 2026
8 checks passed
@Brooooooklyn
Brooooooklyn deleted the feat/org-shared-github-cli branch July 5, 2026 08:43
cpojer pushed a commit that referenced this pull request Sep 11, 2026
CI has been red on main since #249. `vp install --frozen-lockfile`
resolves two copies of @voidzero-dev/vite-plus-core and the rolldown
native binding then fails to load:

  Error: Cannot find native binding
  ERR_PACKAGE_PATH_NOT_EXPORTED: './binding' is not defined by "exports"
  Cannot find module '../rolldown-binding.linux-x64-gnu.node'

The catalog pins two things that must move together:

  overrides:  vite: 'catalog:'                          -> forces every
  catalog:    vite: npm:...vite-plus-core@0.2.6            vite to 0.2.6
              vite-plus: ^0.2.0                          -> floated to 0.2.8

vite-plus@0.2.8 depends on @voidzero-dev/vite-plus-core@0.2.8 exactly, so
bumping only `vite-plus` leaves both 0.2.6 and 0.2.8 in the tree. This is
the same trap the `hono` comment three lines above warns about.

After the bump the tree resolves to a single core (0.2.8); the lockfile
delta is purely that dedup (-112/+28).


Claude-Session: https://claude.ai/code/session_01Guv3pkFxhXReNWJ2Z2Luxg

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.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.

1 participant