Skip to content

fix(auth): a transient gh probe failure no longer looks like being signed out (ext 0.19.10) - #487

Merged
evemcgivern merged 2 commits into
mainfrom
dev
Aug 9, 2026
Merged

evemcgivern merged 2 commits into
mainfrom
dev

Conversation

@evemcgivern

Copy link
Copy Markdown
Contributor

Returning to a sleeping laptop could greet you with a "Not signed in to GitHub" banner and an empty tree while gh was perfectly authenticated. Fixes that at the root, in both the CLI and the viewer.

The bug

gh auth status validates your token over the network, so a reconnecting VPN or a waking machine makes it exit non-zero — and gh reports the cause as The token in keyring is invalid., which is untrue. The CLI read any non-zero exit as a logout, and the viewer marked that verdict authoritative, wiping the tree and prompting a sign-in nobody needed. The viewer's existing "transient probe error → keep the tree" guard could never fire, because the most common real-world failure was misfiled as a definitive logout.

The same defect meant a multi-account gh setup broke: gh exits non-zero if any configured account fails validation, so one stale account read as a logout of the healthy active one.

CLI

  • auth-status --json gains a probe_ok trust flag. Only two verdicts are authoritative: a clean exit 0, and the explicit "not logged into any GitHub hosts" message. Validation failures, timeouts, and unrecognised exits are indeterminate — unverified, not signed out.
  • New exit code 3 for an indeterminate probe (0/1/2 unchanged, so rc == 0 remains the usability gate).
  • Terminal output for that case no longer tells a signed-in user to run gh auth login; it relays gh's own diagnosis instead.

VS Code extension (0.19.10)

  • Honours probe_ok and stops discarding the CLI's error reason. When the field is absent it recognises gh's validation-failure wording directly, so the fix works against an already-installed CLI — MIN_CLI_VERSION deliberately stays at 2026.07.15.
  • The last-good tree now persists across window reloads (globalState, version-stamped, 7-day age cap, throttled to one write per minute, 4 MB size cap). Without this, a cold window had no cache to protect — which is why the banner returned every single time.
  • The "couldn't verify" banner and toasts lead with "you have not been signed out" instead of blaming missing CLI dependencies.
  • A genuine gh auth logout still shows the real sign-in banner.

Verification

Exercised against real gh (network blocked via an unreachable proxy; genuine logout via an isolated GH_CONFIG_DIR) through the extension's real checkAuth:

scenario authenticated probeOk banner tree
network up true true none shown
network blip false false couldn't-verify kept
real logout false true not-signed-in cleared

858 extension tests, 1449 + 21 Python tests, tsc --noEmit and production build clean.

Closes #485. Ships ext 0.19.10 + an npm CLI publish (CLI changed).

🤖 Generated with Claude Code

https://claude.ai/code/session_01R7g4UeZgVFkKymkM4Q7Zn6

evemcgivern and others added 2 commits August 9, 2026 10:39
…ut (#486)

* fix(auth): treat an unverifiable gh probe as unverified, not signed out

`gh auth status` validates the token over the network, so a momentary
network failure — a waking laptop, a reconnecting VPN — exits non-zero
and actively misreports the cause as "The token in keyring is invalid."
The CLI read any non-zero exit as a logout, and the viewer then marked
that verdict authoritative, wiping the tree and showing a sign-in banner
to someone who never signed out.

The guard for this already existed (tree.ts's "transient probe error +
last-good tree → keep tree") but could never fire, because the most
common real-world failure was misfiled as a definitive logout.

- github_state: only a clean exit 0 or an explicit "not logged into any
  hosts" message is authoritative; validation failures, timeouts and
  unrecognised exits are indeterminate. New `probe_ok` field, new exit 3.
  This also fixes multi-account setups, where one stale account made gh
  exit non-zero and read as a logout of a healthy active one.
- cli.ts: honour `probe_ok` and stop discarding the CLI's `error`. Falls
  back to recognising gh's validation-failure wording when the field is
  absent, so the fix works against an already-installed CLI.
- authCache: persist the last-good export in globalState, so a reload
  during a blip has a tree to keep. Version-stamped, age-capped, and
  drops anything malformed rather than risking a corrupt tree.
- Copy: the banner and toasts now lead with "you have not been signed
  out" instead of blaming missing CLI dependencies.

Verified against real gh: network up → signed in; blip → tree kept
behind a "couldn't verify" banner; `gh auth logout` → sign-in banner.

Closes #485

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R7g4UeZgVFkKymkM4Q7Zn6

* perf(auth): throttle and size-cap the last-good snapshot

A real multi-repo export is ~785 KB, so persisting on every refresh would
push that through globalState each time — and on a timer wherever
`workPlan.autoRefreshInterval` is set. The snapshot only has to be fresh
enough to survive a reload, so write at most once a minute, and refuse
anything over 4 MB rather than parking an unbounded blob in a shared
per-user store. An oversized export clears any prior snapshot instead of
leaving a stale tree we've stopped updating.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R7g4UeZgVFkKymkM4Q7Zn6

* docs(cli): correct the AuthState probeOk/error contract

probeOk is about trust, not parseability — a well-formed
authenticated:false can still be untrustworthy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R7g4UeZgVFkKymkM4Q7Zn6

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@evemcgivern
evemcgivern merged commit a68a27e into main Aug 9, 2026
20 checks passed
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.

fix(vscode): transient gh probe failure shows a false "Not signed in to GitHub" banner

1 participant