Repository navigation
fix(tui): stabilize plugin reload generations - #43447
Merged
Merged
Conversation
kitlangton
enabled auto-merge (squash)
August 19, 2026 15:11
# ------------------------ >8 ------------------------ # Do not modify or remove the line above. # Everything below it will be ignored. # # Conflicts: # packages/tui/test/plugin-hot-reload.test.tsx
jinhuang712
pushed a commit
to jinhuang712/opencode
that referenced
this pull request
Sep 26, 2026
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.
What
Harden the setup-failure recovery merged in #43441 so one logical source save remains one plugin generation even when the filesystem exposes several mtimes. This preserves the last good plugin without suppressing legitimate retries caused by changed source or options.
Before / After
Before: Setup failures were memoized by an mtime-derived module URL. A single save can expose several mtimes, so duplicate notifications could still look like distinct generations and repeat the teardown/restore cycle. Mutable config option references could also make an options-only change look unchanged.
After: Local entrypoint contents map to a process-unique numeric generation. Repeated reads of unchanged contents reuse that generation, source reverts still get a fresh ESM URL, and immutable option snapshots make options-only retries reliable.
How
packages/tui/src/plugin/context.tsxfingerprints local entrypoint contents, assigns process-wide monotonic generations, snapshots registration options, and centralizes generation comparison and contribution cleanup.packages/tui/src/plugin/discovery.tskeeps cache-busted imports numeric while accepting generation numbers rather than assuming they are mtimes.packages/tui/test/plugin-hot-reload.test.tsxuses a second healthy plugin as a positive reconcile barrier before asserting that an unchanged broken save did not cycle the restored plugin.Scope
This keeps the existing entrypoint-only watch boundary. Changes to nested helper modules remain outside this fix.
Testing
bun run test test/plugin-hot-reload.test.tsx --test-name-pattern "a save whose setup throws" --rerun-each 20frompackages/tui: 20/20 pass; the original implementation failed 18/20 locally.bun run test test/plugin-hot-reload.test.tsx test/plugin-discovery.test.ts test/plugin-reload.test.tsfrompackages/tui: 16 pass.bun typecheckfrompackages/tui.Flow
flowchart LR A[Filesystem notification] --> B[Hash entrypoint contents] B --> C{Content changed?} C -- No --> D[Reuse generation] C -- Yes --> E[Assign unique generation] D --> F{Known setup failure for generation + options?} E --> F F -- Yes --> G[Keep last good plugin active] F -- No --> H[Import and activate]