Skip to content

gui: take the credential read off the Servers page's first paint - #210

Merged
dinstein merged 2 commits into
mainfrom
gui-servers-first-paint
Aug 7, 2026
Merged

gui: take the credential read off the Servers page's first paint#210
dinstein merged 2 commits into
mainfrom
gui-servers-first-paint

Conversation

@dinstein

@dinstein dinstein commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Opening the Servers page held a skeleton ("Reading the registry…") until BOTH the
registry read and a full credential-metadata read had answered. The second one costs
a keychain lookup per stored entry — a /usr/bin/security subprocess each, on macOS —
serialized under the secrets chain's lock. On a seven-server registry that measured
~120ms of subprocess time in front of the first paint, on every navigation to the page,
because the router builds a fresh page instance per mount and nothing is cached across
one.

The list itself never needed it. Credential state reaches only two surfaces, and both
are now covered by the row signature, so a late answer repaints exactly the rows it
changes.

  • 1. Carry the stored-credential boolean in rowSignature, so a row whose
    credential state changed is rebuilt even while collapsed
  • 2. Take the credential read off the first-paint path: fire it beside the fleet
    probe and repaint when it lands

dinstein and others added 2 commits August 7, 2026 09:17
rowSignature decided whether to rebuild a server row, and it read the
stored credential only while the row was expanded. The row menu reads it
too, and that menu is on every row: Log out OAuth appears exactly when a
credential is stored. So dropping a credential while the row was
collapsed changed nothing the signature could see, the cached node was
reused, and the menu went on offering to log out of a server with
nothing left to log out of.

Disabled servers took that path directly — logoutCredential repaints
instead of probing when the server is off — and it is also the shape any
future non-probing refresh of credential state would hit.

The signature now carries hasStoredCredential unconditionally. The full
status stays gated on expanded on purpose: the daemon computes
expires_in per request, so an unconditional status entry would rebuild
every row on every read for a countdown only the open panel draws.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Opening Servers held the "Reading the registry…" skeleton until both the
registry read and a full credential-metadata read had answered. Only the
first one describes the list. The second walks every server and reads its
OAuth state and access token out of the secrets chain, which on macOS is
a `security` subprocess per entry, run under one lock.

Measured against a headless daemon on a seven-server registry with three
authorized servers: GET /v1/servers answers in 0.1-0.4ms, GET /v1/auth in
120-137ms. The page paid the second on every navigation, because the
router builds a fresh page per mount and this cache is page-local.

The read now runs beside the fleet probe and repaints when it lands. The
two surfaces that read a status are the expanded Authorization panel and
the row menu's Log out item, and rowSignature covers both, so the late
answer rebuilds exactly the rows it changes. Overlapping reads are
ordered by epoch — a page-entry refresh and the read a completed login
runs are both legitimate, and the older must not restore what the newer
replaced — and a second draw arriving inside the window joins rather than
starting a duplicate, while an explicit Refresh still re-asks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dinstein
dinstein marked this pull request as ready for review August 7, 2026 01:23
@dinstein
dinstein merged commit f776bc8 into main Aug 7, 2026
3 checks passed
@dinstein
dinstein deleted the gui-servers-first-paint branch August 7, 2026 01:27
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