fix(tui): explicitly register spinner to survive Windows tree-shaking - #91
Merged
Conversation
On a Windows host, `bun build` drops the side-effect-only
`import "opentui-spinner/solid"` because the package's `sideEffects`
path glob does not match backslash paths. The `extend({ spinner })`
call inside it never runs, so the bundled Windows binary crashes at
runtime with `[Reconciler] Unknown component type: spinner` the first
time `<spinner>` renders. macOS/Linux are unaffected (forward-slash
paths match), which is why the prior lockfile dedupe fix did not stop
the Windows crash.
Verified the root cause against the released v1.17.11-dev.10 artifacts:
the Windows `opencode.exe` contains zero spinner runtime strings
("Spinner interval must be a finite", "createPulse requires at least
one color"), while the macOS binary from the same release contains
them — confirming the registration code was tree-shaken out on Windows.
Fix: register the spinner explicitly via `extend({ spinner:
SpinnerRenderable })` in a local module that each `<spinner>` render
path imports. This carries a real value dependency the bundler cannot
drop. The retained `opentui-spinner/solid` side-effect import is kept
for JSX type augmentation; `extend` is `Object.assign` over a flat
catalogue, so the resulting double registration on macOS/Linux is
harmless.
This mirrors the existing `extend({ go_upsell_art })` pattern in
packages/tui/src/component/bg-pulse.tsx.
LeXwDeX
enabled auto-merge
July 9, 2026 03:42
This was referenced Jul 9, 2026
LeXwDeX
added a commit
that referenced
this pull request
Jul 10, 2026
Three improvements for offline / restricted-network startup that are not covered by the already-merged offline-catalog PRs (#88-#91): 1. Plugin SDK offline bundling: build.ts copies the plugin source into a vendored directory next to each binary. At runtime npm.install resolves @opencode-ai/plugin via three-tier fallback — project-local > bundled copy > registry — so plugin installs succeed without network access. 2. dependencyVersion(): only pin the version on stable latest releases (channel=latest + pure semver x.y.z). Fork/prerelease/local builds get undefined so the install doesn't request a non-existent registry version. 3. Reference offline degradation: only register a Git reference when its cache directory actually exists, and update the entry after a successful refresh. Missing references are omitted instead of carrying a stale path.
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.
Problem
The Windows release binary (
opencode.exe) crashes at runtime with[Reconciler] Unknown component type: spinnerthe first time<spinner>renders. The prior fix (#90, lockfile dedupe) did not stop it.Root cause
On a Windows host,
bun builddrops the side-effect-onlyimport "opentui-spinner/solid". That package declaressideEffects: ["./dist/solid.mjs"]as a forward-slash glob, which Bun does not match against backslash paths on a Windows builder. Theextend({ spinner })call inside it never executes, so the reconciler has nospinnercomponent registered. macOS/Linux match fine (forward-slash paths), which is why only Windows crashes.Verified against the released v1.17.11-dev.10 artifacts:
Spinner interval must be a finitecreatePulse requires at least one coloropencode.exe(Windows)opencode(macOS)The Windows binary contains zero spinner runtime code — the registration was tree-shaken out.
Fix
Register the spinner explicitly via
extend({ spinner: SpinnerRenderable })in a local module imported by every<spinner>render path. The explicitextend(...)carries a real value dependency the bundler cannot drop.packages/tui/src/ui/spinner-register.ts(new) — used by the TUIpackages/opencode/src/cli/cmd/run/spinner-register.ts(new) — used by theopencode runfooterimport "opentui-spinner/solid"→ the local registration moduleThe retained
opentui-spinner/solidside-effect import is not redundant: it provides JSX type augmentation for<spinner>. At runtime it re-registers too, butextendisObject.assignover a flat catalogue, so double registration is harmless. This mirrors the existingextend({ go_upsell_art })pattern inpackages/tui/src/component/bg-pulse.tsx.Verification
bun typecheckinpackages/tui— PASSbun typecheckinpackages/opencode— PASS./packages/opencode/script/build.ts --single --skip-install --skip-embed-web-ui— PASS, smoke test--versionPASSFollow-up (not in this PR)
A real end-to-end fix confirmation requires the Windows CI build. Suggested: add a post-build check on the Windows artifact that greps
opencode.exeforSpinner interval must be a finite(>0) so this regression cannot recur silently.Checklist
main, PR targetsdev