Skip to content

refactor(plugins): give host-service resolution its own home - #1023

Merged
rmyndharis merged 1 commit into
mainfrom
refactor/plugin-host-services
Jul 31, 2026
Merged

refactor(plugins): give host-service resolution its own home#1023
rmyndharis merged 1 commit into
mainfrom
refactor/plugin-host-services

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Second step on plugin-loader.service.ts, after the config-defaults seeder.

Why

The loader carried five private resolvers — MessageService, SessionService,
ConversationMappingService, PluginInstanceService, SearchProviderRegistry — each a lazy require
plus a non-strict ModuleRef.get. Both halves are load-bearing and neither is about loading plugins:

  • the lazy require avoids a static edge that closes
    plugin-loader → message → session → engine.factory → core/plugins barrel → plugin-loader, which
    corrupts MessageService's constructor paramtype metadata at boot;
  • ModuleRef instead of constructor injection avoids the provider cycle
    PluginLoaderService → SessionService → EngineFactory → PluginLoaderService.

That reasoning was spelled out three times inside a file that otherwise has nothing to do with
module-load order.

What changes

PluginHostServices owns the pair and the explanation. The loader keeps its ModuleRef parameter and
builds the locator in the constructor body, so the constructor signature is untouched — all 33
positional constructions across six spec files, and the three spec subclasses overriding
createSandboxHost, compile and pass unchanged.

The loader also stops naming the five services: four type-only imports leave with the bodies.
MessageService stays, because dispatchConversationMedia still takes it as a parameter type.

Two tests moved

getSearchRegistry's own tests reached it through a private cast on the loader
((loader as unknown as { getSearchRegistry })) and needed twenty lines of config/storage/HookManager
scaffolding. Against PluginHostServices the same two assertions need one line. They were moved rather
than kept alive by a delegate on the loader, which would have preserved the reach-in that made them
brittle.

Suite total is unchanged at 4011 — nothing added, two tests relocated. Suite count 249 → 250 for the
new file.

On the plan this came from

The earlier plan justified a prep commit rewriting those 33 constructions to Test.createTestingModule,
on the grounds that moving fields would force a spec rewrite. Checked at source, that was not needed
here and was skipped: the constructor already absorbs new dependencies through @Optional — its own
comment records exactly that — so only reordering or removing a parameter forces the churn. The same
plan also called this step a prerequisite for breaking a plugin-loaderplugin-storage require
cycle; that cycle does not exist today either.

Verification

Backend lint, prettier --check, tsc --noEmit over the full project including specs, build, 4011 unit
tests, 137 e2e tests, and the dashboard build all pass on Node 22.

The loader carried five private resolvers — MessageService, SessionService,
ConversationMappingService, PluginInstanceService, SearchProviderRegistry — each
a lazy require plus a non-strict ModuleRef.get. Both halves exist to dodge a
documented cycle, and that reasoning was spelled out three times in a file that
has nothing else to do with module-load order.

PluginHostServices now owns the pair and the explanation. The loader keeps the
ModuleRef parameter and builds the locator in its constructor body, so the
constructor SIGNATURE is untouched: all 33 positional constructions across six
spec files, and the three spec subclasses overriding createSandboxHost, compile
and pass unchanged.

The loader also stops naming the five services. Four type-only imports go with
the bodies; MessageService stays because dispatchConversationMedia still takes
it as a parameter type.

Two tests moved rather than being kept working by a delegate. They reached
getSearchRegistry through a private cast on the loader and needed twenty lines
of config/storage/HookManager scaffolding to do it; against PluginHostServices
the same two assertions need one line. Suite total is unchanged at 4011.

A note for whoever picks up the next step: the plan this came from justified an
earlier prep commit rewriting those 33 constructions to Test.createTestingModule,
on the grounds that field moves would force a spec rewrite. That was not needed
here and was skipped. The constructor already absorbs new dependencies through
@optional, as its own comment records; only reordering or removing a parameter
would force the churn.
@rmyndharis
rmyndharis merged commit 0e8a828 into main Jul 31, 2026
15 checks passed
@rmyndharis
rmyndharis deleted the refactor/plugin-host-services branch July 31, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant