Skip to content

fix(auth): prime models cache after device-flow sign-in#177

Merged
stuffbucket merged 2 commits into
mainfrom
fix/models-prime-on-signin
Jun 24, 2026
Merged

fix(auth): prime models cache after device-flow sign-in#177
stuffbucket merged 2 commits into
mainfrom
fix/models-prime-on-signin

Conversation

@stuffbucket

Copy link
Copy Markdown
Owner

Problem

On a fresh install, signing in via the GUI device-code flow leaves the models list empty — the catalog is never pulled down until something forces a refresh. Reported on Windows (a fresh install signs in via device flow for the first time), but the bug is cross-platform logic, not Windows-specific code.

Root cause

Two paths can prime the models cache, and the sign-in path was missing the call:

  • Cold boot with a token (src/lib/start/bootstrap.ts): logUser()setupCopilotToken()cacheModels()
  • Device-flow sign-in (src/lib/auth-controller.ts): addAccount()setupCopilotToken()setAuthState(signed-in)no cacheModels()

The lazy staleRefreshMiddleware (src/lib/refresh-models.ts) can't cover the gap: it's stale-while-revalidate and explicitly no-ops on an unprimed cache (loadedAtMs === null → "not_primed"). So the chain on a fresh box is:

  1. Boot with no token → bootstrap skips the if (state.githubToken) block → cacheModels() never runs → cache loadedAtMs === null.
  2. Device-flow sign-in → mints Copilot token, latches signed-in, but never primes models → cache still null.
  3. Lazy middleware → not_primed → never fires.
  4. Settings UI GET /settings/api/models is read-only (only POST forces a refresh) → shows empty.

macOS users rarely hit it because they usually boot with a token (boot primes), so the device-flow-on-fresh-install case is unusual there.

Fix

Prime the models cache right after the Copilot token is minted in the device-flow sign-in path, mirroring bootstrap.ts. Best-effort + isolated try/catch (same pattern as the setupCopilotToken call beside it) so a /models hiccup never blocks reaching the signed-in state.

Tests

tests/auth-controller.test.ts:

  • new: primes the models cache after a successful device-flow sign-in (asserts cacheModels called once + authenticated).
  • new: a models-cache failure does not fail sign-in (best-effort — cacheModels rejects, sign-in still reaches authenticated).
  • harness: stub/count cacheModels via mock.module("~/lib/utils", …) (spreads the real namespace) so the success path no longer makes a real Copilot /models fetch.

31 pass / 0 fail; tsc --noEmit clean; eslint clean.

@stuffbucket stuffbucket merged commit 8259883 into main Jun 24, 2026
4 checks passed
@stuffbucket stuffbucket deleted the fix/models-prime-on-signin branch June 24, 2026 19:22
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