Skip to content

fix(auth): gh-reuse — validate before reboot + refresh discovery on focus#113

Merged
stuffbucket merged 1 commit into
mainfrom
fix/gh-reuse-preflight-and-refresh
Jun 11, 2026
Merged

fix(auth): gh-reuse — validate before reboot + refresh discovery on focus#113
stuffbucket merged 1 commit into
mainfrom
fix/gh-reuse-preflight-and-refresh

Conversation

@stuffbucket

Copy link
Copy Markdown
Owner

Brings the gh-reuse feature to a clean state — the error-precision and discovery-freshness gaps we'd been circling.

1. Errors handled precisely, before the reboot

A stale or no-Copilot gh account used to be written + rebooted-into, then surfaced a generic "came back unauthenticated" ~20s later (the reason was lost on the boot-degrade path). Now POST /gh/use pre-flights the token against Copilot (/copilot_internal/user) before writing + rebooting and returns a specific 422:

  • 401 → "GitHub rejected {login}'s token — it may be expired or revoked…"
  • 403/404 → "{login} doesn't have access to GitHub Copilot…"
  • else → "Couldn't verify {login} with GitHub (HTTP n)…"

The shell extracts {error:{message}} and shows it immediately — no wasted reboot. Also closes the getModels timeout gap (it was missing from #110's guarded set; cacheModels is on the boot critical path).

2. Discovery refreshes on attention, not on a poll

gh accounts were only re-read on entering the Account section — adding an account in gh while Settings was already open didn't appear. Now refreshes on window focus / visibilitychange (the "switched back from the terminal after gh auth login" moment) plus a quiet Refresh button. No polling (gh auth status touches the keyring).

Validation

+6 pre-flight unit tests (status→message, DI'd usage fn — no mock.module leak). Full suite green (824); a valid account still imports (200 — no happy-path regression); check:fast + shell tsc clean.

Multi-account persistence + the quick-switch list (with merge/remove/needs-reauth and the boot-degrade reason-preservation) remain the separate next project; this is the per-feature clean-up.

…ocus

Completes the gh-reuse feature to a clean state. Two gaps:

1. Errors were handled safely but imprecisely: a stale/no-subscription gh
   account got written + rebooted into, then surfaced a generic 'came back
   unauthenticated' ~20s later. Now POST /gh/use PRE-FLIGHTS the token against
   Copilot (/copilot_internal/user) BEFORE writing/rebooting and returns a
   specific 422 — 'token expired or revoked' (401) vs 'no Copilot subscription'
   (403/404) vs a network message — which the UI shows immediately, no reboot.
   The shell now extracts {error:{message}} so the specific reason renders.
   Also closes the getModels timeout gap (it was missing from the #110 set;
   cacheModels is on the boot critical path).

2. gh discovery was only refreshed on entering the Account section — adding an
   account in gh while settings was already open didn't show up. Now refreshes
   on window focus / visibilitychange (the natural 'returned from the terminal'
   moment) + a manual Refresh button. No polling (gh auth status hits the
   keyring).

+6 pre-flight unit tests (status→message mapping, DI'd usage fn — no
mock.module). Full suite green (824); valid-account import still 200 (no
happy-path regression); shell tsc clean.
@stuffbucket stuffbucket merged commit 33ab9e7 into main Jun 11, 2026
4 checks passed
@stuffbucket stuffbucket deleted the fix/gh-reuse-preflight-and-refresh branch June 11, 2026 20:07
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