Skip to content

fix(dev-platform): wire GitHub-App onboarding + device-flow into the composition root#497

Open
Weegy wants to merge 2 commits into
mainfrom
fix/dev-platform-github-app-device-wiring
Open

fix(dev-platform): wire GitHub-App onboarding + device-flow into the composition root#497
Weegy wants to merge 2 commits into
mainfrom
fix/dev-platform-github-app-device-wiring

Conversation

@Weegy

@Weegy Weegy commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Wire the GitHub-App onboarding router + device-flow provider into the composition root

The GitHub-App onboarding router and the device-flow provider are fully implemented (routes, manifest flow, stores, tests) but were never instantiated in index.ts. As a result, on every deploy:

  • The entire GitHub-App admin area 404screateDevPlatformGithubAppRouter / ManifestFlowStore are never called, so the router is never mounted. The apps tab, "Create GitHub App", app list, and repo binding all fail.
  • The device-token flow returns 503 devplatform.device_flow_unconfiguredassembleDevPlatform(...) was called with no deviceFlow argument, so the repos router's /github/connect/{start,poll} hit their if (!df) guard.

PAT was the only wired credential path. This is a pure composition-root wiring gap — no logic changes.

Changes

  1. Device flow — build a provider from DEV_PLATFORM_GITHUB_CLIENT_ID ?? GITHUB_OAUTH_CLIENT_ID via the existing createGitHubDeviceProvider, and pass deviceFlow: { provider, store } into assembleDevPlatform (conditionally — only when the provider resolves non-null, mirroring the surrounding optional-dep spread style). This clears the 503 guard. (Note: DEV_PLATFORM_GITHUB_CLIENT_ID was a declared-but-unused config knob — it is now live.)

  2. GitHub App — instantiate ManifestFlowStore + a DevGithubAppStore and mount createDevPlatformGithubAppRouter:

    • .admin behind requireAuth at /api/v1/admin/dev-platform (same boundary as the sibling admin routers).
    • .public (state-token auth only, no session) at /api/v1/dev-platform — the path GitHub's manifest redirect_url / setup_url resolve to after the web-ui /bot-api/api rewrite.
    • The router's repo-binding and repo-lookup deps are wired to the dev-platform repo store.
  3. Public paths — allow the GitHub-App callback / setup paths through the session guard (auth/publicPaths.ts) so GitHub's post-creation browser redirect can reach the public router.

Verification (against a running local omadia-dev stack)

  • Full middleware image build (compile + typecheck) passes.
  • Boot log now shows both new mount lines (github-app admin router mounted … (requireAuth), github-app public router mounted … (state-token auth only)).
  • Endpoint probes: …/admin/dev-platform/github-apps and …/github-app/manifest/start return 401 (mounted, was 404); the public …/dev-platform/github-app/callback and …/setup handlers are reached (400 on missing state token, was 404).
  • Device + GitHub-App wiring tests green (17 tests).

Follow-ups (out of scope, non-blocking)

  • The wizard's "GitHub App (soon)" radio card in CredentialStep.tsx stays disabled — a separate UX task. The real entry points (apps-tab GithubAppsPanel and the wizard's device-flow card) work once this wiring lands.
  • Runtime prerequisites to actually complete a flow (config, not code): PUBLIC_BASE_URL must be a public HTTPS origin GitHub can redirect to (already set on the hosted deploy), and the baked-in OAuth App used by the device flow must have "Device flow" enabled + repo scope at GitHub.

Follow-up commit — device-flow retry no longer requires re-authorizing

Field-testing the wired device flow surfaced a second defect: after the device flow authorized and staged the token, adding a private repo the credential can't reach (GitHub returns 404 on the access probe) failed with repo_access_failed and destroyed the staged authorization (clearPending). The retry then reported the misleading no_pending_device_flow ("connect first") even though the operator had just completed the flow.

Fix: keep the parked device-flow token on a probe failure so the operator can fix access (approve the OAuth App for the org, correct the owner/name, or switch credential) and retry with one click — no full re-auth. The parked token is the operator's own credential, encrypted under their sub, overwritten by the next connect and consumed by the next successful add. The repo_access_failed message now names the likely causes (private repo needs the OAuth App approved for the org, a PAT with repo scope, or the GitHub App installed). Regression test added; 31 devplatform-routes tests green.

Note: the underlying reason a private org repo can't be added via device flow is GitHub-side authorization (the OAuth App must be approved for the org, or use a PAT / the GitHub App install) — not a middleware defect.

Weegy added 2 commits July 17, 2026 09:33
…ovider into the composition root

The GitHub-App onboarding router and the device-flow provider were fully
implemented but never instantiated in index.ts, so the entire GitHub-App
admin area 404'd and the device-token flow returned 503
('device_flow_unconfigured'). PAT was the only wired credential path.

- Device flow: pass a deviceFlow provider into assembleDevPlatform, built
  from DEV_PLATFORM_GITHUB_CLIENT_ID ?? GITHUB_OAUTH_CLIENT_ID via
  createGitHubDeviceProvider (conditionally, only when the provider resolves
  non-null). This clears the 'if (!df)' 503 guard in the repos router's
  /github/connect/{start,poll}.
- GitHub App: instantiate ManifestFlowStore + a DevGithubAppStore and mount
  createDevPlatformGithubAppRouter — .admin behind requireAuth at
  /api/v1/admin/dev-platform, .public (state-token only) at /api/v1/dev-platform
  (the path GitHub's manifest redirect_url/setup_url resolve to via the web-ui
  /bot-api -> /api rewrite). The repo-binding + repo-lookup deps are wired to
  the dev-platform repo store.
- Allow the public GitHub-App callback/setup paths through the session guard
  (auth/publicPaths.ts) so GitHub's post-creation redirect can reach them.

Verified against a running local omadia-dev stack: the full middleware image
build (compile + typecheck) passes; boot log shows both new mount lines; the
github-app admin endpoints return 401 (mounted, was 404) and the public
callback/setup handlers are reached (400 on missing state, was 404). Device
+ github-app wiring tests green (17 tests).
… probe fails

Adding a repo with a device-flow credential probes repo access first. On a
probe denial the handler dropped the parked pending token (clearPending),
which forced the operator to re-run the ENTIRE device flow to retry and
surfaced a misleading 'no_pending_device_flow' on the next attempt — even
though a probe denial is usually fixable without re-auth (mistyped
owner/name, or a private repo the OAuth App / account cannot yet reach).

Keep the parked token on a probe failure so the operator can fix access and
retry with one click; it is their own credential, encrypted under their sub,
overwritten by the next connect and consumed by the next successful add. Also
make the error explain the likely causes (private repo needs the OAuth App
approved for the org, a PAT with repo scope, or the GitHub App installed).

Regression test: a device-flow probe denial preserves resolvePending.
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