Bump @earendil-works/pi-coding-agent, pi-ai, and pi-agent-core to 0.82.1
together and raise the peer range to >=0.82.1 <0.83. All three must move in
lockstep: bumping only two leaves a duplicate pi-ai copy in the tree, which
surfaces as misleading type-identity errors rather than real API breaks.
Pi 0.82 removed ModelRuntime.reloadConfig() and merged it into refresh(),
which now does ModelConfig.load, configureRadiusProviders, and rebuildProviders
before refreshing. Port the five production call sites literally, passing no
options so refresh() keeps defaulting allowNetwork to modelNetworkEnabled --
which the shared runtime pins to false by constructing under PI_OFFLINE. No
call site passes allowNetwork: true.
The auth tests lose reloadConfig() as an observation seam, so the offline
regression cases now drive removeRuntimeApiKey(), the surviving public mutation
that still forwards the construction-time network flag to refresh().
The reworked assertion ran under the file-level PI_OFFLINE=1 stub, so the
runtime was offline whether or not createOfflineModelRuntime forced it and
the test passed with the fix fully removed. Clear the stub for that case,
and rewrap a docblock line.
Finding 6: serialize createOfflineModelRuntime so overlapping calls cannot
interleave their PI_OFFLINE save/restore pairs and leave the process offline,
and name the process-wide visibility of that window in the docblock.
Finding 7: assert the offline construction through the public refresh seam via
reloadConfig() — the request path that regressed — instead of reading upstream's
private modelNetworkEnabled field.
Finding 8.4/8.5: document the background provider-catalog refresh in
docs/config.md and docs/config.html (cadence, timeout, single retry, offline
opt-out via PI_WEB_OFFLINE / PI_OFFLINE only), and update the changeset to
match the behavior after the earlier fixes.
The shared ModelRuntime was constructed with network refreshes enabled, so
reloadConfig()/login()/logout() — called on the model picker, session model
changes, and auth dialogs — performed unbounded provider-catalog fetches.
A single stalled fetch blocked those requests for minutes and, through pi's
coalesced per-provider refresh, dragged session creation along with it.
Construct the runtime with PI_OFFLINE forced so every runtime-driven refresh
stays local, and add ModelCatalogRefresher as the single deliberate network
path: bounded by an abort timeout, serialized through one in-flight run,
scheduled in the background, and triggered after provider auth changes.
Replace AuthStorage.inMemory / ModelRegistry.create|inMemory across all test
and support code with the pi-ai InMemoryCredentialStore + async
ModelRuntime.create({ credentials }). Add shared test-runtime seams
(createTestModelRuntime, testModelRuntime, seedCredential) in testSupport.ts
and thread modelRuntime into fakeRuntime and every PiSessionService
construction (now a required dependency). Rework the anthropic subscription
warning tests onto a temp auth.json seam read via readStoredCredential, and
the auth-loss warning test onto a live credential store + runtime refresh.
Make getLoginProviderOptions synchronous and fix associated await/lint sites.
npm run verify green (typecheck + lint + knip + 1390 tests).