From 42f432246482642580971fed2103321e43fbbae8 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 12 Aug 2026 10:54:06 -0700 Subject: [PATCH] refactor(plugin-sdk): prune unreachable facades (#122745) --- src/plugin-sdk/anthropic-vertex.ts | 43 ----------- src/plugin-sdk/copilot-proxy.ts | 9 --- src/plugin-sdk/feishu-security.ts | 22 ------ src/plugin-sdk/litellm.ts | 43 ----------- src/plugin-sdk/lobster.ts | 15 ---- src/plugin-sdk/open-prose.ts | 5 -- src/plugin-sdk/openrouter.ts | 35 --------- src/plugin-sdk/security-runtime-internal.ts | 31 -------- src/plugin-sdk/synology-chat.ts | 29 -------- src/plugin-sdk/talk-voice.ts | 5 -- src/plugin-sdk/vercel-ai-gateway.ts | 71 ------------------- src/plugin-sdk/xiaomi.ts | 35 --------- .../contracts/plugin-sdk-subpaths.test.ts | 2 - 13 files changed, 345 deletions(-) delete mode 100644 src/plugin-sdk/anthropic-vertex.ts delete mode 100644 src/plugin-sdk/copilot-proxy.ts delete mode 100644 src/plugin-sdk/feishu-security.ts delete mode 100644 src/plugin-sdk/litellm.ts delete mode 100644 src/plugin-sdk/lobster.ts delete mode 100644 src/plugin-sdk/open-prose.ts delete mode 100644 src/plugin-sdk/openrouter.ts delete mode 100644 src/plugin-sdk/security-runtime-internal.ts delete mode 100644 src/plugin-sdk/synology-chat.ts delete mode 100644 src/plugin-sdk/talk-voice.ts delete mode 100644 src/plugin-sdk/vercel-ai-gateway.ts delete mode 100644 src/plugin-sdk/xiaomi.ts diff --git a/src/plugin-sdk/anthropic-vertex.ts b/src/plugin-sdk/anthropic-vertex.ts deleted file mode 100644 index 34cd17ce6df6..000000000000 --- a/src/plugin-sdk/anthropic-vertex.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Public SDK facade for Anthropic Vertex implicit provider discovery and config helpers. - */ -import type { ModelProviderConfig } from "../config/types.js"; -import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js"; - -type FacadeModule = { - resolveAnthropicVertexClientRegion: (params?: { - baseUrl?: string; - env?: NodeJS.ProcessEnv; - }) => string; - resolveAnthropicVertexProjectId: (env?: NodeJS.ProcessEnv) => string | undefined; - buildAnthropicVertexProvider: (params?: { env?: NodeJS.ProcessEnv }) => ModelProviderConfig; - resolveImplicitAnthropicVertexProvider: (params?: { - env?: NodeJS.ProcessEnv; - }) => ModelProviderConfig | null; - mergeImplicitAnthropicVertexProvider: (params: { - existing?: ModelProviderConfig; - implicit: ModelProviderConfig; - }) => ModelProviderConfig; -}; - -function loadFacadeModule(): FacadeModule { - return loadBundledPluginPublicSurfaceModuleSync({ - dirName: "anthropic-vertex", - artifactBasename: "api.js", - }); -} - -/** Resolves the Anthropic Vertex region through the activated bundled provider facade. */ -export const resolveAnthropicVertexClientRegion: FacadeModule["resolveAnthropicVertexClientRegion"] = - ((...args) => - loadFacadeModule().resolveAnthropicVertexClientRegion( - ...args, - )) as FacadeModule["resolveAnthropicVertexClientRegion"]; - -/** Resolves the Anthropic Vertex project id through the activated provider facade. */ -export const resolveAnthropicVertexProjectId: FacadeModule["resolveAnthropicVertexProjectId"] = (( - ...args -) => - loadFacadeModule().resolveAnthropicVertexProjectId( - ...args, - )) as FacadeModule["resolveAnthropicVertexProjectId"]; diff --git a/src/plugin-sdk/copilot-proxy.ts b/src/plugin-sdk/copilot-proxy.ts deleted file mode 100644 index 96a151377883..000000000000 --- a/src/plugin-sdk/copilot-proxy.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Narrow plugin-sdk surface for the bundled copilot-proxy plugin. -// Keep this list additive and scoped to the bundled Copilot proxy surface. - -export { definePluginEntry } from "./plugin-entry.js"; -export type { - OpenClawPluginApi, - ProviderAuthContext, - ProviderAuthResult, -} from "../plugins/types.js"; diff --git a/src/plugin-sdk/feishu-security.ts b/src/plugin-sdk/feishu-security.ts deleted file mode 100644 index 7134b9947bed..000000000000 --- a/src/plugin-sdk/feishu-security.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Manual facade. Keep loader boundary explicit. -import type { OpenClawConfig } from "../config/types.js"; -import type { SecurityAuditFinding } from "../security/audit.types.js"; -import { loadBundledPluginPublicSurfaceModuleSyncCore } from "./facade-loader.js"; - -type SecuritySurface = { - collectFeishuSecurityAuditFindings: (params: { cfg: OpenClawConfig }) => SecurityAuditFinding[]; -}; - -function loadSecuritySurface(): SecuritySurface { - return loadBundledPluginPublicSurfaceModuleSyncCore({ - dirName: "feishu", - artifactBasename: "security-contract-api.js", - }); -} - -/** Collect Feishu plugin security findings through the lazy bundled-plugin facade. */ -export const collectFeishuSecurityAuditFindings: SecuritySurface["collectFeishuSecurityAuditFindings"] = - ((...args) => - loadSecuritySurface().collectFeishuSecurityAuditFindings( - ...args, - )) as SecuritySurface["collectFeishuSecurityAuditFindings"]; diff --git a/src/plugin-sdk/litellm.ts b/src/plugin-sdk/litellm.ts deleted file mode 100644 index 923cb1c0455c..000000000000 --- a/src/plugin-sdk/litellm.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Manual facade. Keep loader boundary explicit. -import type { ModelDefinitionConfig, OpenClawConfig } from "../config/types.js"; -import { loadBundledPluginPublicSurfaceModuleSyncCore } from "./facade-loader.js"; - -type FacadeModule = { - applyLitellmConfig: (cfg: OpenClawConfig) => OpenClawConfig; - applyLitellmProviderConfig: (cfg: OpenClawConfig) => OpenClawConfig; - buildLitellmModelDefinition: () => ModelDefinitionConfig; - LITELLM_BASE_URL: string; - LITELLM_DEFAULT_MODEL_ID: string; - LITELLM_DEFAULT_MODEL_REF: string; -}; - -function loadFacadeModule(): FacadeModule { - return loadBundledPluginPublicSurfaceModuleSyncCore({ - dirName: "litellm", - artifactBasename: "api.js", - }); -} -/** Apply LiteLLM defaults to the full OpenClaw config. */ -export const applyLitellmConfig: FacadeModule["applyLitellmConfig"] = ((...args) => - loadFacadeModule()["applyLitellmConfig"](...args)) as FacadeModule["applyLitellmConfig"]; -/** Apply only LiteLLM provider config defaults. */ -export const applyLitellmProviderConfig: FacadeModule["applyLitellmProviderConfig"] = ((...args) => - loadFacadeModule()["applyLitellmProviderConfig"]( - ...args, - )) as FacadeModule["applyLitellmProviderConfig"]; -/** Build the LiteLLM model definition written by setup/config helpers. */ -export const buildLitellmModelDefinition: FacadeModule["buildLitellmModelDefinition"] = (( - ...args -) => - loadFacadeModule()["buildLitellmModelDefinition"]( - ...args, - )) as FacadeModule["buildLitellmModelDefinition"]; -/** Default LiteLLM gateway base URL. */ -export const LITELLM_BASE_URL: FacadeModule["LITELLM_BASE_URL"] = - loadFacadeModule()["LITELLM_BASE_URL"]; -/** Default LiteLLM model id advertised by the bundled provider facade. */ -export const LITELLM_DEFAULT_MODEL_ID: FacadeModule["LITELLM_DEFAULT_MODEL_ID"] = - loadFacadeModule()["LITELLM_DEFAULT_MODEL_ID"]; -/** Default LiteLLM provider/model reference written by setup flows. */ -export const LITELLM_DEFAULT_MODEL_REF: FacadeModule["LITELLM_DEFAULT_MODEL_REF"] = - loadFacadeModule()["LITELLM_DEFAULT_MODEL_REF"]; diff --git a/src/plugin-sdk/lobster.ts b/src/plugin-sdk/lobster.ts deleted file mode 100644 index 07601b374c3d..000000000000 --- a/src/plugin-sdk/lobster.ts +++ /dev/null @@ -1,15 +0,0 @@ -// Private Lobster plugin helpers for bundled extensions. -// Keep this surface narrow and limited to the Lobster workflow/tool contract. - -export { definePluginEntry } from "./plugin-entry.js"; -export { - applyWindowsSpawnProgramPolicy, - materializeWindowsSpawnProgram, - resolveWindowsSpawnProgramCandidate, -} from "./windows-spawn.js"; -export type { - AnyAgentTool, - OpenClawPluginApi, - OpenClawPluginToolContext, - OpenClawPluginToolFactory, -} from "../plugins/types.js"; diff --git a/src/plugin-sdk/open-prose.ts b/src/plugin-sdk/open-prose.ts deleted file mode 100644 index 210291b90941..000000000000 --- a/src/plugin-sdk/open-prose.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Narrow plugin-sdk surface for the bundled open-prose plugin. -// Keep this list additive and scoped to the bundled open-prose surface. - -export { definePluginEntry } from "./plugin-entry.js"; -export type { OpenClawPluginApi } from "../plugins/types.js"; diff --git a/src/plugin-sdk/openrouter.ts b/src/plugin-sdk/openrouter.ts deleted file mode 100644 index 53e287705dcb..000000000000 --- a/src/plugin-sdk/openrouter.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Manual facade. Keep loader boundary explicit. -import type { ModelProviderConfig, OpenClawConfig } from "../config/types.js"; -import { loadBundledPluginPublicSurfaceModuleSyncCore } from "./facade-loader.js"; - -type FacadeModule = { - applyOpenrouterConfig: (cfg: OpenClawConfig) => OpenClawConfig; - applyOpenrouterProviderConfig: (cfg: OpenClawConfig) => OpenClawConfig; - buildOpenrouterProvider: () => ModelProviderConfig; - OPENROUTER_DEFAULT_MODEL_REF: string; -}; - -function loadFacadeModule(): FacadeModule { - return loadBundledPluginPublicSurfaceModuleSyncCore({ - dirName: "openrouter", - artifactBasename: "api.js", - }); -} -/** Apply OpenRouter defaults to the full OpenClaw config. */ -export const applyOpenrouterConfig: FacadeModule["applyOpenrouterConfig"] = ((...args) => - loadFacadeModule()["applyOpenrouterConfig"](...args)) as FacadeModule["applyOpenrouterConfig"]; -/** Apply only OpenRouter provider config defaults. */ -export const applyOpenrouterProviderConfig: FacadeModule["applyOpenrouterProviderConfig"] = (( - ...args -) => - loadFacadeModule()["applyOpenrouterProviderConfig"]( - ...args, - )) as FacadeModule["applyOpenrouterProviderConfig"]; -/** Build the OpenRouter model provider entry used by setup/config helpers. */ -export const buildOpenrouterProvider: FacadeModule["buildOpenrouterProvider"] = ((...args) => - loadFacadeModule()["buildOpenrouterProvider"]( - ...args, - )) as FacadeModule["buildOpenrouterProvider"]; -/** Default OpenRouter provider/model reference written by setup flows. */ -export const OPENROUTER_DEFAULT_MODEL_REF: FacadeModule["OPENROUTER_DEFAULT_MODEL_REF"] = - loadFacadeModule()["OPENROUTER_DEFAULT_MODEL_REF"]; diff --git a/src/plugin-sdk/security-runtime-internal.ts b/src/plugin-sdk/security-runtime-internal.ts deleted file mode 100644 index a4a4e96d8ea6..000000000000 --- a/src/plugin-sdk/security-runtime-internal.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { root as fsRoot, type OpenResult } from "../infra/fs-safe.js"; - -/** Safely open a path beneath a trusted root while rejecting hardlinks and unsafe symlinks by default. */ -export async function openFileWithinRoot(params: { - rootDir: string; - relativePath: string; - rejectHardlinks?: boolean; - nonBlockingRead?: boolean; - allowSymlinkTargetWithinRoot?: boolean; -}): Promise { - const root = await fsRoot(params.rootDir); - return await root.open(params.relativePath, { - hardlinks: params.rejectHardlinks === false ? "allow" : "reject", - nonBlockingRead: params.nonBlockingRead, - symlinks: params.allowSymlinkTargetWithinRoot === true ? "follow-within-root" : "reject", - }); -} - -/** Copy a source file into a path beneath a trusted root using fs-safe root policy. */ -export async function writeFileFromPathWithinRoot(params: { - rootDir: string; - relativePath: string; - sourcePath: string; - mkdir?: boolean; -}): Promise { - const root = await fsRoot(params.rootDir); - await root.copyIn(params.relativePath, params.sourcePath, { - mkdir: params.mkdir, - sourceHardlinks: "reject", - }); -} diff --git a/src/plugin-sdk/synology-chat.ts b/src/plugin-sdk/synology-chat.ts deleted file mode 100644 index 63a10b00f19a..000000000000 --- a/src/plugin-sdk/synology-chat.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Manual facade. Keep loader boundary explicit. -import type { SecurityAuditFinding } from "../security/audit.types.js"; -import { loadBundledPluginPublicSurfaceModuleSyncCore } from "./facade-loader.js"; - -type FacadeModule = { - collectSynologyChatSecurityAuditFindings: (params: { - accountId?: string | null; - account: { - accountId?: string; - dangerouslyAllowNameMatching?: boolean; - }; - orderedAccountIds: string[]; - hasExplicitAccountPath: boolean; - }) => SecurityAuditFinding[]; -}; - -function loadFacadeModule(): FacadeModule { - return loadBundledPluginPublicSurfaceModuleSyncCore({ - dirName: "synology-chat", - artifactBasename: "contract-api.js", - }); -} - -/** Collect Synology Chat security findings through the lazy bundled-plugin facade. */ -export const collectSynologyChatSecurityAuditFindings: FacadeModule["collectSynologyChatSecurityAuditFindings"] = - ((...args) => - loadFacadeModule().collectSynologyChatSecurityAuditFindings( - ...args, - )) as FacadeModule["collectSynologyChatSecurityAuditFindings"]; diff --git a/src/plugin-sdk/talk-voice.ts b/src/plugin-sdk/talk-voice.ts deleted file mode 100644 index 56943e6abd9e..000000000000 --- a/src/plugin-sdk/talk-voice.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Narrow plugin-sdk surface for the bundled talk-voice plugin. -// Keep this list additive and scoped to the bundled talk-voice surface. - -export { definePluginEntry } from "./plugin-entry.js"; -export type { OpenClawPluginApi } from "../plugins/types.js"; diff --git a/src/plugin-sdk/vercel-ai-gateway.ts b/src/plugin-sdk/vercel-ai-gateway.ts deleted file mode 100644 index 397bcde266b3..000000000000 --- a/src/plugin-sdk/vercel-ai-gateway.ts +++ /dev/null @@ -1,71 +0,0 @@ -// Manual facade. Keep loader boundary explicit. -import type { ModelDefinitionConfig, ModelProviderConfig } from "../config/types.js"; -import { - createLazyFacadeObjectValue, - loadBundledPluginPublicSurfaceModuleSyncCore, -} from "./facade-loader.js"; - -type ModelCost = ModelDefinitionConfig["cost"]; - -type FacadeModule = { - buildVercelAiGatewayProvider: () => Promise; - discoverVercelAiGatewayModels: () => Promise; - getStaticVercelAiGatewayModelCatalog: () => ModelDefinitionConfig[]; - VERCEL_AI_GATEWAY_BASE_URL: string; - VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW: number; - VERCEL_AI_GATEWAY_DEFAULT_COST: ModelCost; - VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS: number; - VERCEL_AI_GATEWAY_DEFAULT_MODEL_ID: string; - VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF: string; - VERCEL_AI_GATEWAY_PROVIDER_ID: string; -}; - -function loadFacadeModule(): FacadeModule { - return loadBundledPluginPublicSurfaceModuleSyncCore({ - dirName: "vercel-ai-gateway", - artifactBasename: "api.js", - }); -} -/** Build the Vercel AI Gateway provider config through the bundled provider facade. */ -export const buildVercelAiGatewayProvider: FacadeModule["buildVercelAiGatewayProvider"] = (( - ...args -) => - loadFacadeModule()["buildVercelAiGatewayProvider"]( - ...args, - )) as FacadeModule["buildVercelAiGatewayProvider"]; -/** Discover Vercel AI Gateway models through the bundled provider facade. */ -export const discoverVercelAiGatewayModels: FacadeModule["discoverVercelAiGatewayModels"] = (( - ...args -) => - loadFacadeModule()["discoverVercelAiGatewayModels"]( - ...args, - )) as FacadeModule["discoverVercelAiGatewayModels"]; -/** Return the static Vercel AI Gateway model catalog used before live discovery. */ -export const getStaticVercelAiGatewayModelCatalog: FacadeModule["getStaticVercelAiGatewayModelCatalog"] = - ((...args) => - loadFacadeModule()["getStaticVercelAiGatewayModelCatalog"]( - ...args, - )) as FacadeModule["getStaticVercelAiGatewayModelCatalog"]; -/** Default Vercel AI Gateway base URL. */ -export const VERCEL_AI_GATEWAY_BASE_URL: FacadeModule["VERCEL_AI_GATEWAY_BASE_URL"] = - loadFacadeModule()["VERCEL_AI_GATEWAY_BASE_URL"]; -/** Default context window assigned to Vercel AI Gateway models without catalog metadata. */ -export const VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW: FacadeModule["VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW"] = - loadFacadeModule()["VERCEL_AI_GATEWAY_DEFAULT_CONTEXT_WINDOW"]; -/** Default cost metadata assigned to Vercel AI Gateway models without catalog metadata. */ -export const VERCEL_AI_GATEWAY_DEFAULT_COST: FacadeModule["VERCEL_AI_GATEWAY_DEFAULT_COST"] = - createLazyFacadeObjectValue( - () => loadFacadeModule()["VERCEL_AI_GATEWAY_DEFAULT_COST"] as object, - ) as FacadeModule["VERCEL_AI_GATEWAY_DEFAULT_COST"]; -/** Default max-token value assigned to Vercel AI Gateway models without catalog metadata. */ -export const VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS: FacadeModule["VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS"] = - loadFacadeModule()["VERCEL_AI_GATEWAY_DEFAULT_MAX_TOKENS"]; -/** Default Vercel AI Gateway model id used by setup flows. */ -export const VERCEL_AI_GATEWAY_DEFAULT_MODEL_ID: FacadeModule["VERCEL_AI_GATEWAY_DEFAULT_MODEL_ID"] = - loadFacadeModule()["VERCEL_AI_GATEWAY_DEFAULT_MODEL_ID"]; -/** Default Vercel AI Gateway provider/model reference written by setup flows. */ -export const VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF: FacadeModule["VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF"] = - loadFacadeModule()["VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF"]; -/** Provider id used for Vercel AI Gateway config and model refs. */ -export const VERCEL_AI_GATEWAY_PROVIDER_ID: FacadeModule["VERCEL_AI_GATEWAY_PROVIDER_ID"] = - loadFacadeModule()["VERCEL_AI_GATEWAY_PROVIDER_ID"]; diff --git a/src/plugin-sdk/xiaomi.ts b/src/plugin-sdk/xiaomi.ts deleted file mode 100644 index d9a3bb6c1809..000000000000 --- a/src/plugin-sdk/xiaomi.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Manual facade. Keep loader boundary explicit. -import type { ModelProviderConfig, OpenClawConfig } from "../config/types.js"; -import { loadBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js"; - -type FacadeModule = { - applyXiaomiConfig: (cfg: OpenClawConfig) => OpenClawConfig; - applyXiaomiProviderConfig: (cfg: OpenClawConfig) => OpenClawConfig; - buildXiaomiProvider: () => ModelProviderConfig; - XIAOMI_DEFAULT_MODEL_ID: string; - XIAOMI_DEFAULT_MODEL_REF: string; -}; - -function loadFacadeModule(): FacadeModule { - return loadBundledPluginPublicSurfaceModuleSync({ - dirName: "xiaomi", - artifactBasename: "api.js", - }); -} -/** Apply Xiaomi provider defaults to the full OpenClaw config. */ -export const applyXiaomiConfig: FacadeModule["applyXiaomiConfig"] = ((...args) => - loadFacadeModule()["applyXiaomiConfig"](...args)) as FacadeModule["applyXiaomiConfig"]; -/** Apply only Xiaomi provider config defaults. */ -export const applyXiaomiProviderConfig: FacadeModule["applyXiaomiProviderConfig"] = ((...args) => - loadFacadeModule()["applyXiaomiProviderConfig"]( - ...args, - )) as FacadeModule["applyXiaomiProviderConfig"]; -/** Build the Xiaomi model provider entry used by setup/config helpers. */ -export const buildXiaomiProvider: FacadeModule["buildXiaomiProvider"] = ((...args) => - loadFacadeModule()["buildXiaomiProvider"](...args)) as FacadeModule["buildXiaomiProvider"]; -/** Default Xiaomi model id advertised by the provider facade. */ -export const XIAOMI_DEFAULT_MODEL_ID: FacadeModule["XIAOMI_DEFAULT_MODEL_ID"] = - loadFacadeModule()["XIAOMI_DEFAULT_MODEL_ID"]; -/** Default Xiaomi provider/model reference written by setup flows. */ -export const XIAOMI_DEFAULT_MODEL_REF: FacadeModule["XIAOMI_DEFAULT_MODEL_REF"] = - loadFacadeModule()["XIAOMI_DEFAULT_MODEL_REF"]; diff --git a/src/plugins/contracts/plugin-sdk-subpaths.test.ts b/src/plugins/contracts/plugin-sdk-subpaths.test.ts index 5082fed1c025..5ac5ecf9fe4b 100644 --- a/src/plugins/contracts/plugin-sdk-subpaths.test.ts +++ b/src/plugins/contracts/plugin-sdk-subpaths.test.ts @@ -1303,8 +1303,6 @@ describe("plugin-sdk subpath exports", () => { expectSourceOmitsSnippet("google-model-id", "./google.js"); expectSourceOmitsSnippet("google-model-id", "./facade-runtime.js"); expectSourceOmitsSnippet("google-model-id", "../../extensions/"); - expectSourceMentions("xiaomi", ["./facade-runtime.js"]); - expectSourceOmitsSnippet("xiaomi", "./facade-loader.js"); expectRepoSourceOmitsSnippet("extensions/xai/model-id.ts", "./xai.js"); expectRepoSourceOmitsSnippet("extensions/xai/model-id.ts", "./facade-runtime.js"); expectRepoSourceOmitsSnippet("extensions/xai/model-id.ts", "../../extensions/");