{{ message }}
Repository navigation
Conversation
On airgapped or degraded networks (hanging DNS, black-holed TCP) TUI startup stalled on unbounded waits: plugin installs ran npm's full retry ladder with no opencode-side deadline while the first frame and plugin activation awaited them, and the pre-paint location lookup, URL skill index fetch, remote instruction fetch, OAuth refresh, and Console config load all had no timeout. Bound Arborist reify and the registry check in Npm (2m install / 15s check through an overridable Context.Reference), abort the TUI pre-paint requests after 10s and fall back to the client directory, bound the skill catalog client, Console config pipeline, and credential refresh, and fork the initial remote-instruction fetch off plugin activation the way later refreshes already run. Staging-directory cleanup on interrupt is preserved, and hung-registry and hung-catalog behavior is covered by deterministic loopback tests. Refs anomalyco#2224 Refs anomalyco#19197 Refs anomalyco#51022 Co-Authored-By: Claude Mythos 5 <noreply@anthropic.com>
On airgapped or degraded networks a cold plugin install can hang in npm's retry ladder for minutes, and both the TUI first frame and the server plugin-activation latch waited on it without a bound. Stop gating TUI readiness on the first reconcile after 10 seconds while it keeps running in the background, so plugins still activate when it finishes. Bound each plugin setup at 15 seconds through the existing failed-slot path so activation always settles, and bound the per-package install await at 30 seconds so an unreachable registry fails that plugin and the rest of the generation proceeds. Config changes and the periodic re-check retry failed installs as before, and hung setups and installs are covered by deterministic tests. Refs anomalyco#2224 Refs anomalyco#19197 Co-Authored-By: Claude Mythos 5 <noreply@anthropic.com>
PJ-Zetier
force-pushed
the
startup-network-bounds
branch
from
October 21, 2026 15:21
c871fe7 to
76450ed
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Issue for this PR
Closes #57742
Related: #2224, #19197
Type of change
What does this PR do?
On hosts where connections hang instead of failing fast (airgapped/firewalled networks), startup stalls for minutes because several awaited operations have no bound. Two commits:
fix: bound startup-path network waits for offline hosts— Arborist installs get a timeout (2 min install / 15 s freshness check, via a test-overridableNpm.Timeoutsreference) surfaced asInstallFailedError, with the staging-dir cleanup proven to still run on interrupt; the TUI's pre-rendererfile.listcall gets a 10 s abort with aprocess.cwd()fallback instead of a frozen blank terminal; URL skill sources get a 10 s client bound; the initial remote-instruction fetch is forked like the later refreshes; OAuth refresh and the Console config fetch get 10 s / 5 s bounds flowing into their existing failure paths.fix: do not gate TUI/server readiness on plugin installs— the TUI ready gate opens after 10 s while reconcile keeps running in the background (plugins activate late instead of blocking first use), and the server's plugin activation latch bounds each plugin setup (15 s, interruptible acquire so promise-based plugins can't wedge it) and each install (30 s), routing into the existing failed-plugin handling.Bounds are generous, failures land on the same non-fatal paths as before, so slow-but-working networks are unaffected.
How did you verify your code works?
New deterministic tests that hang a local server/registry and assert the bound fires:
packages/core/test/npm.test.ts(also asserts no.staging-*dir is left behind),skill-discovery.test.ts,plugin-failure.test.ts(activation latch releases, next plugin still activates),plugin/module.test.ts. Typecheck clean inutil,core,tui(and dependentsserver,cli). Touched-package suites were compared against base92242b55— only pre-existing failures, byte-identical lists. A network-namespace airgap harness (dropped SYNs + hanging DNS) measured the unbounded npm retry ladder these bounds cap: ~100-160 s per cold plugin spec with hanging DNS, ~6-13 min with black-holed TCP.Screenshots / recordings
N/A — the TUI shows the same loading states, just bounded.
Checklist
🤖 Generated with Claude Code