Skip to content

Extension host: establish host-owned plugin runtime foundations#47713

Closed
gumadeiras wants to merge 1 commit intomainfrom
codex/extension-host-foundations-single
Closed

Extension host: establish host-owned plugin runtime foundations#47713
gumadeiras wants to merge 1 commit intomainfrom
codex/extension-host-foundations-single

Conversation

@gumadeiras
Copy link
Member

@gumadeiras gumadeiras commented Mar 16, 2026

Summary

This PR establishes the first host-owned extension-host foundations for plugin runtime behavior.

Today on main, plugin runtime logic still lives in core, mostly under legacy src/plugins/* modules and nearby core-owned subsystem code. This PR starts moving that ownership behind src/extension-host/* boundaries while preserving compatibility for existing callers.

It also introduces the planned nested src/extension-host/ layout for the foundations included in this PR:

  • src/extension-host/activation/
  • src/extension-host/policy/
  • src/extension-host/compat/
  • src/extension-host/manifests/
  • src/extension-host/static/
  • src/extension-host/contributions/

This is the first real cut away from plugin-era ownership in core. It is not the end of the migration.

How to review this PR

This PR is large, but it is one migration slice with one theme:

  • move plugin runtime ownership behind src/extension-host/*
  • keep legacy src/plugins/* entry points as compatibility facades
  • move a focused set of runtime consumers onto those host-owned seams

Recommended review order:

  1. Loader / activation boundary
  • src/plugins/loader.ts
  • src/extension-host/activation/*
  • src/extension-host/policy/*
  1. Registry / compatibility boundary
  • src/plugins/registry.ts
  • src/extension-host/compat/*
  1. Runtime registry ownership
  • src/extension-host/contributions/runtime-registry.ts
  • src/extension-host/contributions/registry-writes.ts
  • representative consumers:
    • src/channels/*
    • src/plugins/http-registry.ts
    • src/plugins/services.ts
    • src/cli/plugin-registry.ts
  1. Provider / tool / command foundations
  • src/extension-host/contributions/provider-*
  • src/extension-host/contributions/tool-runtime.ts
  • src/extension-host/contributions/command-runtime.ts
  1. Static and manifest normalization
  • src/extension-host/manifests/*
  • src/extension-host/static/*
  1. Internal docs sync
  • docs/.internal/extension-host-migration/*
  • src/extension-host/cutover-inventory.md

What changed

This PR does four main things:

  1. Introduces host-owned loader and activation seams
  2. Introduces host-owned registry and runtime-registry seams
  3. Moves provider, tool, command, service, CLI, channel, route, and gateway behavior behind host-owned boundaries
  4. Organizes this migration slice under the nested src/extension-host/ layout above

What did NOT change

This PR does not:

  • complete the migration
  • remove legacy src/plugins/* entry points
  • introduce media/TTS/embedding runtime-family work
  • introduce runtime-backend catalog/arbitration work
  • change the event-pipeline, conversation-binding, or interaction-routing architecture
  • claim that plugin-specific logic is fully out of core already

Why this PR is large

This PR is large mainly because it combines three things that need to land together to make the boundary real:

  • new host-owned boundary modules under src/extension-host/*
  • rewiring existing callers onto those modules
  • keeping legacy src/plugins/* entry points in place as compatibility facades

Many files under src/extension-host/ are new because this is the first time this boundary is landing on main, not because the PR contains unrelated features.

What is wrong with main today

On main, core still owns a large amount of plugin runtime behavior.

Examples:

  • plugin loading and registration are centered in files like src/plugins/loader.ts and src/plugins/registry.ts
  • plugin-facing runtime surfaces for tools, providers, services, CLI registrars, channels, and commands still route through core-owned plugin modules
  • provider auth/setup/selection behavior is mixed into plugin-era code paths instead of a dedicated host-owned boundary
  • registry state, compatibility logic, and runtime ownership are interleaved, which makes it hard to tell what is legacy versus intended end-state ownership

That means plugin code still lives in core in ways we do not want long-term.

Target architecture

The end state of the migration is:

  • plugin-specific behavior lives with the plugin
  • core does not carry product-specific plugin logic
  • legacy src/plugins/* modules remain only as compatibility facades
  • the extension host owns the generic runtime boundary for:
    • activation and loading
    • manifest normalization and static descriptors
    • runtime registries
    • policy, arbitration, and fallback
    • lifecycle and security
    • compatibility during migration

This architecture is meant to work across plugin types, not just one category.

Examples:

  • channel plugins
  • auth/model provider plugins
  • search providers
  • tool plugins
  • command plugins
  • service plugins
  • future plugin types that fit the same host-owned contribution model

The goal is a generic host-owned runtime boundary, not category-specific core logic for each plugin family.

Concrete examples from this PR

This PR introduces the first major host-owned foundations for that architecture.

Loader and activation foundations

Before:

  • plugin loading behavior was primarily owned by legacy plugin-era modules

After:

  • host-owned loader seams now exist for candidate planning, register flow, import flow, orchestration, cache control, lifecycle state, session state, discovery policy, activation policy, finalization policy, bootstrap, execution setup, preflight, pipeline, and runtime setup

Registry and compatibility foundations

Before:

  • registry writes, compatibility shims, and runtime ownership were mixed in legacy plugin registry code

After:

  • host-owned registry write helpers, compatibility helpers, and registration actions exist behind src/extension-host/*
  • legacy plugin-era entry points remain in place as compatibility facades

Runtime registry foundations

Before:

  • runtime consumers read and wrote legacy plugin registry collections directly

After:

  • host-owned runtime-registry read/storage seams now exist for channels, providers, tools, services, CLI registrations, HTTP routes, and gateway methods
  • compatibility views are preserved while ownership starts shifting to the host boundary

Provider foundations

Before:

  • provider runtime, discovery, auth flows, onboarding, and model-selection hooks were plugin-era concerns in core

After:

  • those behaviors now have explicit host-owned seams in src/extension-host/*

Other runtime foundations

This PR also moves additional plugin runtime behavior behind host-owned seams for:

  • tool runtime
  • service lifecycle
  • CLI lifecycle
  • gateway method aggregation
  • channel storage/lookup
  • command runtime

Why this matters for different plugin types

This is not only about cleaning up existing plugin code. It is about making the ownership model generic enough to support different plugin types without baking plugin-specific logic into core.

Examples:

  • channel plugins should register routing/runtime surfaces through host-owned registries instead of custom core code
  • auth/provider plugins should expose setup/auth/runtime behavior through host-owned seams instead of plugin-era loaders and registries
  • search providers should fit the same model, whether surfaced as tools or as host-owned runtime backends later
  • future plugin types should not require a new category of product-shaped core architecture

Core should understand generic concepts like:

  • activation
  • manifests
  • contributions
  • runtime registry membership
  • policy/arbitration
  • compatibility

Core should not need product-specific logic for each plugin family.

Migration note

One intentional transitional cost in this PR is the compatibility mirroring inside src/extension-host/contributions/runtime-registry.ts.

The host-owned runtime registry is now the direction of travel, but legacy plugin-era callers still expect arrays and maps like:

  • registry.channels
  • registry.providers
  • registry.tools
  • registry.cliRegistrars
  • registry.services
  • registry.commands
  • registry.httpRoutes
  • registry.gatewayHandlers

To preserve backward compatibility during the migration, this PR keeps mirrored legacy views alongside the host-owned runtime-registry state.

That duplication is intentional for now:

  • it keeps existing callers working
  • it lets new host-owned readers and writers move first
  • it avoids forcing a flag day across all plugin/runtime consumers

It is not the intended end state. As more callers move onto host-owned accessors, this compatibility mirroring should shrink and eventually disappear.

Scope boundary

This PR does not complete the migration.

It does not yet do the later work around:

  • context-engine and ACP follow-on runtime work
  • subsystem-runtime families like media, TTS, and embeddings
  • runtime-backend catalog and arbitration layers
  • canonical event-pipeline and interaction/binding cutover
  • pilot migrations

Behavior

Compatibility is preserved intentionally, but this PR is not purely structural.

It introduces real host-owned boundaries and reroutes real runtime behavior through them, while keeping legacy plugin-era entry points available as facades.

Verification

  • pnpm build
  • targeted extension-host loader, registry, provider, runtime-registry, channel, CLI/service, and command test coverage

Why this PR now

This is the first coherent foundation slice for the migration:

  • it starts moving plugin runtime ownership out of core
  • it keeps compatibility in place
  • it creates host-owned seams that later PRs can build on without redoing the same extraction work

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 16, 2026

Too many files changed for review. (144 files found, 100 file limit)

Copilot AI review requested due to automatic review settings March 16, 2026 00:40
@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation gateway Gateway runtime cli CLI command changes commands Command implementations agents Agent runtime and tooling size: XL maintainer Maintainer-authored PR labels Mar 16, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR establishes host-owned “extension host” foundations for plugin runtime behavior by moving key loader, manifest, registry, and contribution logic behind src/extension-host/* boundaries while preserving legacy compatibility.

Changes:

  • Introduces a host-owned activation/loader pipeline (preflight → execution → session → finalize) with caching, provenance, and policy seams.
  • Adds host-owned contribution/runtime-registry helpers (HTTP routes, tools, services, CLI commands, providers, gateway methods, commands) and updates core call sites to use them.
  • Introduces host-owned manifest/schema/resolved-registry helpers and migrates config validation/auto-enable and related flows to use resolved extensions.

Reviewed changes

Copilot reviewed 136 out of 144 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/plugins/provider-discovery.ts Routes discovery-result normalization through extension-host helper for compatibility.
src/plugins/manifest.ts Adds loadPackageManifest helper for safe package.json loading.
src/plugins/manifest-registry.ts Adds resolved-extension metadata to manifest records via extension-host manifest helpers.
src/plugins/install.ts Uses extension-host schema helpers for extension entry resolution during install.
src/plugins/http-registry.ts Moves HTTP route registration to extension-host runtime-registry helpers.
src/plugins/discovery.ts Switches to extension-host schema helpers and shared package-manifest loader.
src/plugins/cli.ts Delegates CLI command registration to extension-host lifecycle helper.
src/gateway/server/plugins-http/route-match.ts Reads HTTP routes via extension-host runtime-registry helper.
src/gateway/server/plugins-http.ts Reads HTTP routes via extension-host runtime-registry helper.
src/gateway/server.impl.ts Composes gateway handlers using extension-host gateway-method aggregation helper.
src/gateway/server-plugins.ts Moves gateway-method listing + diagnostics logging behind extension-host helpers.
src/extension-host/static/active-registry.ts Introduces global active extension-host registry state + accessors.
src/extension-host/static/active-registry.test.ts Tests active extension-host registry initialization and versioning.
src/extension-host/policy/loader-provenance.ts Adds provenance tracking primitives (path matchers, install tracking rules).
src/extension-host/policy/loader-provenance.test.ts Tests provenance path matching and realpath fallback behavior.
src/extension-host/policy/loader-policy.test.ts Tests loader policy ordering/record creation behavior.
src/extension-host/policy/loader-finalization-policy.ts Adds finalization policy for memory-slot + provenance warnings.
src/extension-host/policy/loader-finalization-policy.test.ts Tests finalization diagnostics/warnings behavior.
src/extension-host/policy/loader-discovery-policy.ts Adds discovery allowlist warning policy.
src/extension-host/policy/loader-discovery-policy.test.ts Tests discovery-policy warnings and warning cache behavior.
src/extension-host/policy/loader-activation-policy.ts Adds activation policy outcome resolution for candidates/duplicates/disabled.
src/extension-host/policy/loader-activation-policy.test.ts Tests activation policy outcomes.
src/extension-host/manifests/schema.test.ts Tests extension-host manifest/schema helpers (entries, metadata, legacy descriptor).
src/extension-host/manifests/resolved-registry.ts Introduces resolved-extension registry built from plugin manifest registry.
src/extension-host/manifests/manifest-registry.ts Adds resolved-extension record builder from plugin manifest + candidate.
src/extension-host/contributions/tool-runtime.ts Adds host-owned tool resolution with allowlist + conflict diagnostics.
src/extension-host/contributions/tool-runtime.test.ts Tests tool allowlists, conflicts, and factory-error handling.
src/extension-host/contributions/service-lifecycle.ts Adds host-owned service start/stop lifecycle orchestration.
src/extension-host/contributions/service-lifecycle.test.ts Tests service start/stop ordering and failure handling.
src/extension-host/contributions/registry-writes.ts Adds host-owned helpers to write registry entries for contributions.
src/extension-host/contributions/provider-wizard.test.ts Tests provider wizard option/model picker helpers.
src/extension-host/contributions/provider-runtime.ts Adds host-owned provider projection from registrations.
src/extension-host/contributions/provider-runtime.test.ts Tests provider projection behavior.
src/extension-host/contributions/provider-model-selection.ts Adds host-owned provider model-selected hook runner.
src/extension-host/contributions/provider-discovery.ts Adds host-owned provider discovery grouping and result normalization.
src/extension-host/contributions/provider-discovery.test.ts Tests discovery provider grouping and normalization behavior.
src/extension-host/contributions/provider-auth.ts Adds host-owned provider match/auth method selection + config patch helpers.
src/extension-host/contributions/provider-auth.test.ts Tests provider auth helpers + config patch/default model behavior.
src/extension-host/contributions/gateway-methods.ts Adds host-owned gateway method listing/handler composition + diag logging.
src/extension-host/contributions/gateway-methods.test.ts Tests gateway methods, handler override behavior, and diagnostics routing.
src/extension-host/contributions/command-runtime.test.ts Tests host-owned command runtime registration/normalization/aliases.
src/extension-host/contributions/cli-lifecycle.ts Adds host-owned CLI registrar execution with overlap detection.
src/extension-host/contributions/cli-lifecycle.test.ts Tests CLI overlap skipping and sync/async error handling.
src/extension-host/compat/plugin-registry.ts Adds host-owned facade for legacy registry operations + API creation.
src/extension-host/compat/plugin-registry.test.ts Tests provider/command registration through host-owned facade.
src/extension-host/compat/plugin-registry-registrations.test.ts Tests host-owned registration actions (gateway collisions, context engine id).
src/extension-host/compat/plugin-registry-compat.ts Adds compatibility normalization for providers/commands + diagnostics wiring.
src/extension-host/compat/plugin-registry-compat.test.ts Tests provider normalization and duplicate command diagnostics.
src/extension-host/compat/plugin-api.ts Adds host-owned compatibility plugin API delegating to host actions.
src/extension-host/compat/plugin-api.test.ts Tests compatibility API delegation and logger normalization.
src/extension-host/compat/loader-compat.ts Adds plugin-sdk alias resolution + exported subpath mapping for loader.
src/extension-host/compat/hook-compat.ts Adds typed-hook policy enforcement + legacy hook bridging helpers.
src/extension-host/compat/hook-compat.test.ts Tests hook bridging and prompt-injection constraints.
src/extension-host/activation/loader-state.ts Adds lifecycle-state machine + helpers for registry plugin records.
src/extension-host/activation/loader-state.test.ts Tests lifecycle transitions and registry finalization promotion.
src/extension-host/activation/loader-session.ts Adds session state for activation run (memory slot, cache, seen ids).
src/extension-host/activation/loader-session.test.ts Tests session mutation and finalization delegation.
src/extension-host/activation/loader-runtime.ts Adds module export resolution, record application, config validation, memory-slot decisions.
src/extension-host/activation/loader-runtime.test.ts Tests export resolution, record application, config validation, memory decisions.
src/extension-host/activation/loader-runtime-proxy.ts Adds lazy Proxy-based runtime instantiation helper.
src/extension-host/activation/loader-runtime-proxy.test.ts Tests lazy runtime creation and proxy behavior.
src/extension-host/activation/loader-run.ts Adds orchestrator to process ordered candidates then finalize session.
src/extension-host/activation/loader-run.test.ts Tests candidate filtering and finalization invocation.
src/extension-host/activation/loader-pipeline.ts Adds pipeline that threads preflight → execution → session run.
src/extension-host/activation/loader-pipeline.test.ts Tests pipeline threading behavior.
src/extension-host/activation/loader-orchestrator.ts Adds top-level extension-host registry loader entrypoint + state clearing.
src/extension-host/activation/loader-module-loader.ts Adds jiti-based module loader with plugin-sdk aliasing support.
src/extension-host/activation/loader-module-loader.test.ts Tests lazy jiti loader creation and alias config behavior.
src/extension-host/activation/loader-import.ts Adds boundary-checked module import helper for safe plugin loads.
src/extension-host/activation/loader-import.test.ts Tests safe import, root escape rejection, and load error handling.
src/extension-host/activation/loader-host-state.ts Adds shared loader host state (cache + warning cache).
src/extension-host/activation/loader-host-state.test.ts Tests warning-cache clearing behavior.
src/extension-host/activation/loader-finalize.ts Adds finalization step (policy warnings, cache write, activation).
src/extension-host/activation/loader-finalize.test.ts Tests finalization cache/activation and memory-slot warnings.
src/extension-host/activation/loader-execution.ts Adds execution setup (registry+runtime, bootstrap, module loader, session).
src/extension-host/activation/loader-execution.test.ts Tests execution composition and returned components.
src/extension-host/activation/loader-cache.ts Adds LRU-ish registry cache + cache key builder.
src/extension-host/activation/loader-cache.test.ts Tests cache key normalization and eviction/refresh behavior.
src/extension-host/activation/loader-bootstrap.ts Adds bootstrap (discovery, manifest registry, warnings, provenance, ordering).
src/extension-host/activation/loader-bootstrap.test.ts Tests bootstrap ordering, warnings, and diagnostic propagation.
src/extension-host/activation.ts Adds activation entrypoint wiring active registry + hook runner initialization.
src/extension-host/activation.test.ts Tests activation sets active registry and global hook runner.
src/config/validation.ts Switches plugin-related config validation to resolved-extension registry + validation index.
src/config/resolved-extension-validation.ts Adds resolved-extension validation index builder for channels/schemas.
src/config/resolved-extension-validation.test.ts Tests resolved-extension validation index aggregation.
src/config/plugin-auto-enable.ts Shifts auto-enable to resolved-extension registry with compatibility fallback input.
src/config/doc-baseline.ts Uses resolved-extension registry to build bundled config schema response.
src/commands/provider-auth-helpers.ts Replaces local provider auth helpers with extension-host provider-auth helpers.
src/commands/auth-choice.apply.plugin-provider.test.ts Updates tests to mock/run host-owned provider model-selection hook.
src/cli/plugin-registry.ts Uses host runtime-entry detection to skip redundant plugin loads.
src/cli/plugin-registry.test.ts Adds tests for provider-only active registry skipping loads.
src/channels/registry.ts Reads channel registrations from active extension-host registry/runtime-registry.
src/channels/plugins/registry-loader.ts Uses active extension-host registry/runtime-registry for channel lookup caching.
src/channels/plugins/plugins-core.test.ts Updates test to add channel registration via extension-host helper.
src/channels/plugins/index.ts Updates channel plugin list caching to use extension-host registry/version + registration listing.
src/channels/plugins/catalog.ts Uses extension-host schema helper for package metadata parsing in catalog entries.
src/channels/dock.ts Reads channel dock entries from extension-host registry/runtime-registry.
src/auto-reply/status.ts Switches to host-owned plugin command listing for status/commands output.
src/auto-reply/reply/commands-plugin.ts Switches to host-owned plugin command match/execute runtime.
src/agents/skills/plugin-skills.ts Adds resolved-extension registry support and registry-based skill dir collection helper.
src/agents/skills/plugin-skills.test.ts Updates tests to use resolved-extension registry fixtures instead of manifest-registry mocking.
src/agents/provider-id.ts Introduces standalone provider id normalization utilities.
src/agents/provider-id.test.ts Tests provider-id normalization aliases and auth normalization.
src/agents/model-ref.ts Introduces model ref parsing/normalization utilities.
src/agents/model-ref.test.ts Tests model ref parsing and canonical-key behavior.
src/agents/google-model-id.ts Adds normalization for legacy Google Gemini model IDs.
src/agents/google-model-id.test.ts Tests Google model ID normalization behavior.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f67e9115b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling cli CLI command changes commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants