Repository navigation
feat(core): expose config changes stream - #39131
Merged
Merged
Conversation
kitlangton
force-pushed
the
config-changes
branch
from
July 27, 2026 15:46
d3bb7b5 to
e26095d
Compare
Contributor
Author
|
Unit failures are the pre-existing v2 base set (Unbound layer node: @opencode/Location from the tool consolidation refactor, plus the pre-existing PluginSupervisor auto-discovered reload failure) — verified identical on clean base. Typecheck and both e2e jobs green. |
This was referenced Jul 27, 2026
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
Adds
config.changes()to the Config service: a stream of raw filesystem updates under config roots. This is the seam that lets domain owners (commands, agents, plugins) observe edits to the source files they parse — without overloadingconfig.updated, which stays reserved for structured config and topology changes.Second slice of the config source reload series, after #38983 (read-barrier event ordering). Design doc:
docs/design/config-source-reload.mdon theconfig-source-reloadbranch.How
Config already owns everything this needs:
reconcileWatcheskeeps deduplicated recursive subscriptions aligned with entries, and everyWatcher.Updateunder every root already funnels into one internalPubSub(packages/core/src/config.ts). This PR exposes that existing feed:implemented as
Stream.fromPubSub(updates)— one line of runtime code. Because Config reconciles watches on reload, subscribers also receive updates from roots added later, without resubscribing.Consumers will compose filtering and debounce at the call site:
The remaining diff is mechanical: 24
Config.Service.oftest stubs across 16 files gainchanges: () => Stream.empty.Scope
Deliberately not here, coming as follow-up PRs:
Testing
Config > exposes filesystem updates under config roots through changes— written red first (config.changes is not a function), green after.bun testover all 13 touched test files: 102 pass, 0 fail.bun typecheckinpackages/core: clean.test/session-runner.test.tsfails identically (24) with and without this change — the pre-existingUnbound layer node: @opencode/Locationset from the tool consolidation refactor, unrelated to this PR.