chore(plugins): window unused and bundled-only public plugin-sdk subpaths (#108415)

* chore(plugins): window unused and bundled-only public plugin-sdk subpaths

* fix(plugins): keep literal compat codes in windowed subpath seeds
This commit is contained in:
Peter Steinberger
2026-07-15 11:21:59 -07:00
committed by GitHub
parent 023126b802
commit bbb62d8510
5 changed files with 281 additions and 10 deletions
+17 -8
View File
@@ -1038,16 +1038,25 @@ apps own device capture/playback UX.
| **Each compat record's `removeAfter` date** | That specific surface is eligible for removal; `pnpm plugins:boundary-report --fail-on-eligible-compat` fails CI once the date passes. |
| **Next major release** | Any surfaces still not migrated are removed; plugins still using them will fail. |
The deprecated public SDK subpaths below have registry-backed removal windows.
The public SDK subpaths below have registry-backed removal or demotion windows.
They do not currently emit a runtime warning when an external plugin imports
them; `scripts/check-deprecated-api-usage.mjs` only diagnoses imports from core
and bundled plugin source.
them. The repository deprecated-usage guard applies only to the fully unused
θ1 tier and the earlier compatibility tier; θ2 remains available to bundled
plugins during the window.
| `removeAfter` | Deprecated SDK subpaths |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `2026-07-30` | `agent-dir-compat`, `channel-envelope`, `channel-inbound-roots`, `channel-location`, `channel-message-runtime`, `channel-pairing-paths`, `channel-reply-options-runtime`, `config-schema`, `config-types`, `direct-dm`, `direct-dm-access`, `mattermost`, `media-generation-runtime-shared`, `memory-core`, `memory-core-engine-runtime`, `memory-core-host-events`, `memory-core-host-multimodal`, `memory-core-host-query`, `memory-host-files`, `memory-host-status`, `music-generation-core`, `outbound-runtime`, `outbound-send-deps`, `provider-auth-login`, `provider-zai-endpoint`, `reply-dedupe`, `runtime-logger`, `runtime-secret-resolution`, `self-hosted-provider-setup`, `setup-adapter-runtime`, `telegram-command-config`, `webhook-path`, `zalouser` |
| `2026-08-15` | `agent-config-primitives`, `channel-logging`, `channel-secret-runtime`, `channel-streaming`, `group-access`, `inbound-reply-dispatch`, `matrix`, `text-runtime`, `zod` |
| `2026-09-01` | `channel-lifecycle`, `channel-message`, `channel-reply-pipeline`, `config-runtime`, `infra-runtime` |
For the window introduced on 2026-07-15, θ1 has no known external or bundled
consumers and will be deleted after the window. θ2 has bundled consumers but no
known external consumers; only its public package export will be retired. Its
module will remain available to bundled plugins as a private-local-only
subpath.
| `removeAfter` | Tier | SDK subpaths |
| ------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `2026-07-30` | Earlier compatibility deprecations | `agent-dir-compat`, `channel-envelope`, `channel-inbound-roots`, `channel-location`, `channel-message-runtime`, `channel-pairing-paths`, `channel-reply-options-runtime`, `config-schema`, `config-types`, `direct-dm`, `direct-dm-access`, `mattermost`, `media-generation-runtime-shared`, `memory-core`, `memory-core-engine-runtime`, `memory-core-host-events`, `memory-core-host-multimodal`, `memory-core-host-query`, `memory-host-files`, `memory-host-status`, `music-generation-core`, `outbound-runtime`, `outbound-send-deps`, `provider-auth-login`, `provider-zai-endpoint`, `reply-dedupe`, `runtime-logger`, `runtime-secret-resolution`, `self-hosted-provider-setup`, `setup-adapter-runtime`, `telegram-command-config`, `webhook-path`, `zalouser` |
| `2026-07-30` | θ1: fully unused; remove subpath | `command-gating`, `lmstudio`, `lmstudio-runtime`, `secret-provider-integration`, `skills-runtime` |
| `2026-07-30` | θ2: bundled-only; retire public export | `access-groups`, `account-resolution-runtime`, `acp-binding-resolve-runtime`, `acp-binding-runtime`, `acp-runtime`, `acp-runtime-backend`, `agent-core`, `agent-harness-exec-review-runtime`, `agent-harness-task-runtime`, `agent-harness-tool-runtime`, `agent-media-payload`, `agent-sessions`, `approval-reaction-runtime`, `approval-reference-runtime`, `async-lock-runtime`, `browser-config`, `bundled-channel-config-schema`, `channel-activity-runtime`, `channel-config-writes`, `channel-mention-gating`, `channel-route`, `channel-secret-tts-runtime`, `channel-targets`, `chat-channel-ids`, `cli-backend`, `cli-runtime`, `codex-mcp-projection`, `command-status-runtime`, `command-surface`, `concurrency-runtime`, `context-visibility-runtime`, `conversation-binding-runtime`, `cron-store-runtime`, `dangerous-name-runtime`, `delivery-queue-runtime`, `direct-dm-guard-policy`, `directory-config-runtime`, `document-extractor`, `embedding-providers`, `exec-approvals-runtime`, `expect-runtime`, `fetch-runtime`, `file-access-runtime`, `file-lock`, `global-singleton`, `group-activation`, `heartbeat-runtime`, `host-runtime`, `html-entity-runtime`, `image-generation`, `image-generation-core`, `image-generation-runtime`, `inline-image-data-url-runtime`, `json-schema-runtime`, `json-unsafe-integers`, `keyed-async-queue`, `llm`, `markdown-table-runtime`, `media-generation-runtime`, `media-understanding`, `memory-core-host-embedding-registry`, `memory-core-host-engine-embeddings`, `memory-core-host-engine-qmd`, `memory-core-host-engine-storage`, `memory-core-host-runtime-cli`, `memory-core-host-runtime-core`, `memory-core-host-runtime-files`, `memory-core-host-secret`, `memory-core-host-status`, `memory-host-core`, `memory-host-events`, `memory-host-markdown`, `memory-host-search`, `message-tool-delivery-hints`, `migration`, `migration-runtime`, `music-generation`, `node-host`, `number-runtime`, `outbound-media`, `pair-loop-guard-runtime`, `plugin-config-runtime`, `plugin-state-runtime`, `poll-runtime`, `process-runtime`, `provider-auth-api-key`, `provider-auth-login-flow-runtime`, `provider-auth-result`, `provider-auth-runtime`, `provider-catalog-live-runtime`, `provider-catalog-shared`, `provider-entry`, `provider-env-vars`, `provider-http`, `provider-model-shared`, `provider-model-types`, `provider-oauth-runtime`, `provider-onboard`, `provider-selection-runtime`, `provider-setup`, `provider-stream`, `provider-stream-family`, `provider-stream-shared`, `provider-tools`, `provider-transport-runtime`, `provider-usage`, `provider-web-fetch`, `provider-web-fetch-contract`, `provider-web-search`, `provider-web-search-config-contract`, `provider-web-search-contract`, `qa-live-transport-scenarios`, `qa-runner-runtime`, `realtime-bootstrap-context`, `realtime-transcription`, `realtime-voice`, `reply-reference`, `request-url`, `response-limit-runtime`, `retry-runtime`, `runtime-doctor`, `runtime-fetch`, `sandbox`, `secret-file-runtime`, `secure-random-runtime`, `session-binding-runtime`, `session-catalog`, `session-key-runtime`, `session-transcript-hit`, `session-transcript-runtime`, `session-visibility`, `simple-completion-runtime`, `speech`, `speech-core`, `sqlite-runtime`, `ssrf-dispatcher`, `string-normalization-runtime`, `system-event-runtime`, `talk-config-runtime`, `target-resolver-runtime`, `text-autolink-runtime`, `text-utility-runtime`, `thread-bindings-runtime`, `thread-bindings-session-runtime`, `time-runtime`, `tool-payload`, `tool-plugin`, `tool-results`, `transcripts`, `transport-ready-runtime`, `tts-runtime`, `types`, `video-generation`, `video-generation-core`, `video-generation-runtime`, `web-content-extractor`, `webhook-targets`, `windows-spawn` |
| `2026-08-15` | Earlier compatibility deprecations | `agent-config-primitives`, `channel-logging`, `channel-secret-runtime`, `channel-streaming`, `group-access`, `inbound-reply-dispatch`, `matrix`, `text-runtime`, `zod` |
| `2026-09-01` | Earlier compatibility deprecations | `channel-lifecycle`, `channel-message`, `channel-reply-pipeline`, `config-runtime`, `infra-runtime` |
All core plugins have already migrated. External plugins should migrate
before the next major release. Run `pnpm plugins:boundary-report` to see which
@@ -15,6 +15,7 @@
"channel-secret-runtime",
"channel-streaming",
"command-auth",
"command-gating",
"compat",
"config-runtime",
"config-schema",
@@ -25,6 +26,8 @@
"group-access",
"inbound-reply-dispatch",
"infra-runtime",
"lmstudio",
"lmstudio-runtime",
"matrix",
"mattermost",
"media-generation-runtime-shared",
@@ -44,8 +47,10 @@
"reply-dedupe",
"runtime-logger",
"runtime-secret-resolution",
"secret-provider-integration",
"self-hosted-provider-setup",
"setup-adapter-runtime",
"skills-runtime",
"telegram-account",
"telegram-command-config",
"text-runtime",
+7 -2
View File
@@ -93,14 +93,18 @@ function readPluginSdkEntrypointBudgetEnv(name, fallback, env = process.env) {
const defaultPublicDeprecatedExportsByEntrypointBudget = Object.freeze({
core: 2,
health: 1,
lmstudio: 1,
"command-gating": 5,
lmstudio: 37,
"lmstudio-runtime": 27,
"provider-setup": 1,
"self-hosted-provider-setup": 14,
routing: 1,
runtime: 3,
"runtime-logger": 3,
"runtime-secret-resolution": 5,
"secret-provider-integration": 4,
"setup-adapter-runtime": 1,
"skills-runtime": 5,
"channel-streaming": 49,
"approval-gateway-runtime": 1,
"approval-handler-runtime": 1,
@@ -233,7 +237,8 @@ export function readPluginSdkSurfaceBudgets(env = process.env) {
"OPENCLAW_PLUGIN_SDK_MAX_PUBLIC_DEPRECATED_EXPORTS",
// +2: group scope encoder/key builder mirrored by deprecated compat.
// Harvest: channel-ingress -8; dead channel-message dispatch aliases -23.
3262,
// +77: five zero-consumer subpaths enter their removal window.
3339,
env,
),
publicWildcardReexports: readPluginSdkSurfaceBudgetEnv(
+42
View File
@@ -22,6 +22,23 @@ const deprecatedTargetParserCompatFiles = new Set([
"src/infra/outbound/outbound-session.test-helpers.ts",
"src/plugins/compat/registry.test.ts",
]);
const publicSdkContractNarrowingTiers = [
{
name: "fully unused subpath",
codeSuffix: "-unused-subpath",
count: 5,
replacement: "none needed — no known consumers; the subpath is removed without successor",
releaseNote: /no known consumers.*removal without a successor/u,
},
{
name: "bundled-only public export",
codeSuffix: "-public-demotion",
count: 158,
replacement:
"subpath becomes internal (private-local-only); no external successor — no known external consumers",
releaseNote: /public export.*module stays available for bundled plugins.*private-local-only/u,
},
] as const;
function expectNonEmptyStringList(values: readonly string[], label: string) {
expect(values, label).toEqual([expect.stringMatching(/\S/u), ...values.slice(1)]);
@@ -64,6 +81,31 @@ describe("plugin compatibility registry", () => {
}
});
it.each(publicSdkContractNarrowingTiers)(
"keeps the $name tier on its registry-backed window",
({ codeSuffix, count, replacement, releaseNote }) => {
const records = listPluginCompatRecords().filter((record) =>
record.code.endsWith(codeSuffix),
);
expect(records).toHaveLength(count);
for (const record of records) {
expect(record).toMatchObject({
status: "deprecated",
owner: "sdk",
introduced: "2026-07-15",
deprecated: "2026-07-15",
warningStarts: "2026-07-15",
removeAfter: "2026-07-30",
replacement,
docsPath: "/plugins/sdk-migration",
});
expect(record.surfaces).toEqual([expect.stringMatching(/^openclaw\/plugin-sdk\//u)]);
expect(record.releaseNote).toMatch(releaseNote);
}
},
);
it("keeps loaded target compatibility surfaces exported during their removal windows", () => {
const source = fs.readFileSync("src/channels/plugins/target-parsing-loaded.ts", "utf8");
expect(source).toMatch(/export type \{ ChannelRouteParsedTarget \}/u);
+210
View File
@@ -375,8 +375,218 @@ const DEPRECATED_PLUGIN_SDK_SUBPATH_RECORDS = DEPRECATED_PLUGIN_SDK_SUBPATH_SEED
}),
) satisfies readonly PluginCompatRecord[];
const UNUSED_PUBLIC_PLUGIN_SDK_SUBPATHS = [
"command-gating",
"lmstudio",
"lmstudio-runtime",
"secret-provider-integration",
"skills-runtime",
] as const;
const BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATHS = [
"access-groups",
"account-resolution-runtime",
"acp-binding-resolve-runtime",
"acp-binding-runtime",
"acp-runtime",
"acp-runtime-backend",
"agent-core",
"agent-harness-exec-review-runtime",
"agent-harness-task-runtime",
"agent-harness-tool-runtime",
"agent-media-payload",
"agent-sessions",
"approval-reaction-runtime",
"approval-reference-runtime",
"async-lock-runtime",
"browser-config",
"bundled-channel-config-schema",
"channel-activity-runtime",
"channel-config-writes",
"channel-mention-gating",
"channel-route",
"channel-secret-tts-runtime",
"channel-targets",
"chat-channel-ids",
"cli-backend",
"cli-runtime",
"codex-mcp-projection",
"command-status-runtime",
"command-surface",
"concurrency-runtime",
"context-visibility-runtime",
"conversation-binding-runtime",
"cron-store-runtime",
"dangerous-name-runtime",
"delivery-queue-runtime",
"direct-dm-guard-policy",
"directory-config-runtime",
"document-extractor",
"embedding-providers",
"exec-approvals-runtime",
"expect-runtime",
"fetch-runtime",
"file-access-runtime",
"file-lock",
"global-singleton",
"group-activation",
"heartbeat-runtime",
"host-runtime",
"html-entity-runtime",
"image-generation",
"image-generation-core",
"image-generation-runtime",
"inline-image-data-url-runtime",
"json-schema-runtime",
"json-unsafe-integers",
"keyed-async-queue",
"llm",
"markdown-table-runtime",
"media-generation-runtime",
"media-understanding",
"memory-core-host-embedding-registry",
"memory-core-host-engine-embeddings",
"memory-core-host-engine-qmd",
"memory-core-host-engine-storage",
"memory-core-host-runtime-cli",
"memory-core-host-runtime-core",
"memory-core-host-runtime-files",
"memory-core-host-secret",
"memory-core-host-status",
"memory-host-core",
"memory-host-events",
"memory-host-markdown",
"memory-host-search",
"message-tool-delivery-hints",
"migration",
"migration-runtime",
"music-generation",
"node-host",
"number-runtime",
"outbound-media",
"pair-loop-guard-runtime",
"plugin-config-runtime",
"plugin-state-runtime",
"poll-runtime",
"process-runtime",
"provider-auth-api-key",
"provider-auth-login-flow-runtime",
"provider-auth-result",
"provider-auth-runtime",
"provider-catalog-live-runtime",
"provider-catalog-shared",
"provider-entry",
"provider-env-vars",
"provider-http",
"provider-model-shared",
"provider-model-types",
"provider-oauth-runtime",
"provider-onboard",
"provider-selection-runtime",
"provider-setup",
"provider-stream",
"provider-stream-family",
"provider-stream-shared",
"provider-tools",
"provider-transport-runtime",
"provider-usage",
"provider-web-fetch",
"provider-web-fetch-contract",
"provider-web-search",
"provider-web-search-config-contract",
"provider-web-search-contract",
"qa-live-transport-scenarios",
"qa-runner-runtime",
"realtime-bootstrap-context",
"realtime-transcription",
"realtime-voice",
"reply-reference",
"request-url",
"response-limit-runtime",
"retry-runtime",
"runtime-doctor",
"runtime-fetch",
"sandbox",
"secret-file-runtime",
"secure-random-runtime",
"session-binding-runtime",
"session-catalog",
"session-key-runtime",
"session-transcript-hit",
"session-transcript-runtime",
"session-visibility",
"simple-completion-runtime",
"speech",
"speech-core",
"sqlite-runtime",
"ssrf-dispatcher",
"string-normalization-runtime",
"system-event-runtime",
"talk-config-runtime",
"target-resolver-runtime",
"text-autolink-runtime",
"text-utility-runtime",
"thread-bindings-runtime",
"thread-bindings-session-runtime",
"time-runtime",
"tool-payload",
"tool-plugin",
"tool-results",
"transcripts",
"transport-ready-runtime",
"tts-runtime",
"types",
"video-generation",
"video-generation-core",
"video-generation-runtime",
"web-content-extractor",
"webhook-targets",
"windows-spawn",
] as const;
const UNUSED_PUBLIC_PLUGIN_SDK_SUBPATH_RECORDS = UNUSED_PUBLIC_PLUGIN_SDK_SUBPATHS.map(
(subpath) => ({
code: `plugin-sdk-${subpath}-unused-subpath` as const,
status: "deprecated" as const,
owner: "sdk" as const,
introduced: "2026-07-15",
deprecated: "2026-07-15",
warningStarts: "2026-07-15",
removeAfter: "2026-07-30",
replacement: "none needed — no known consumers; the subpath is removed without successor",
docsPath: "/plugins/sdk-migration",
surfaces: [`openclaw/plugin-sdk/${subpath}`],
diagnostics: [
"repository deprecated API usage guard for core and bundled plugins; no external runtime import warning",
],
tests: ["src/plugins/compat/registry.test.ts"],
releaseNote: `The public \`openclaw/plugin-sdk/${subpath}\` subpath has no known consumers and is scheduled for removal without a successor.`,
}),
) satisfies readonly PluginCompatRecord[];
const BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATH_RECORDS = BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATHS.map(
(subpath) => ({
code: `plugin-sdk-${subpath}-public-demotion` as const,
status: "deprecated" as const,
owner: "sdk" as const,
introduced: "2026-07-15",
deprecated: "2026-07-15",
warningStarts: "2026-07-15",
removeAfter: "2026-07-30",
replacement:
"subpath becomes internal (private-local-only); no external successor — no known external consumers",
docsPath: "/plugins/sdk-migration",
surfaces: [`openclaw/plugin-sdk/${subpath}`],
diagnostics: ["registry-backed public SDK demotion window; no external runtime import warning"],
tests: ["src/plugins/compat/registry.test.ts"],
releaseNote: `Only the public export for \`openclaw/plugin-sdk/${subpath}\` is retiring; the module stays available for bundled plugins as a private-local-only subpath.`,
}),
) satisfies readonly PluginCompatRecord[];
const PLUGIN_COMPAT_RECORDS = [
...DEPRECATED_PLUGIN_SDK_SUBPATH_RECORDS,
...UNUSED_PUBLIC_PLUGIN_SDK_SUBPATH_RECORDS,
...BUNDLED_ONLY_PUBLIC_PLUGIN_SDK_SUBPATH_RECORDS,
{
code: "legacy-before-agent-start",
status: "deprecated",