refactor(plugin-sdk): narrow config runtime imports

This commit is contained in:
Peter Steinberger
2026-04-27 14:57:48 +01:00
parent f3e8a8a319
commit 4336a7f3a9
573 changed files with 1066 additions and 860 deletions

View File

@@ -75,4 +75,43 @@ describe("config boundary guard", () => {
"extensions/telegram/src/send.ts:1: export async function send() { return loadConfig(); }",
]);
});
it("flags broad config-runtime barrel imports in production code", () => {
const repoRoot = makeRepoFixture();
writeFixture(
repoRoot,
"extensions/telegram/src/index.ts",
[
'import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'import { requireRuntimeConfig } from "openclaw/plugin-sdk/config-runtime";',
'type Loader = typeof import("openclaw/plugin-sdk/config-runtime").getRuntimeConfig;',
"export type Config = OpenClawConfig;",
"export const load: Loader = requireRuntimeConfig;",
].join("\n"),
);
expect(collectDeprecatedInternalConfigApiViolations({ repoRoot })).toEqual(
expect.arrayContaining([
"extensions/telegram/src/index.ts:1 use narrow plugin-sdk config subpaths instead of openclaw/plugin-sdk/config-runtime",
"extensions/telegram/src/index.ts:2 use narrow plugin-sdk config subpaths instead of openclaw/plugin-sdk/config-runtime",
"extensions/telegram/src/index.ts:3 use narrow plugin-sdk config subpaths instead of openclaw/plugin-sdk/config-runtime",
]),
);
});
it("allows narrow config SDK subpaths in production code", () => {
const repoRoot = makeRepoFixture();
writeFixture(
repoRoot,
"extensions/telegram/src/index.ts",
[
'import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'import { requireRuntimeConfig } from "openclaw/plugin-sdk/plugin-config-runtime";',
'type Loader = typeof import("openclaw/plugin-sdk/runtime-config-snapshot").getRuntimeConfig;',
'export const load = (cfg: OpenClawConfig) => requireRuntimeConfig(cfg, "telegram");',
].join("\n"),
);
expect(collectDeprecatedInternalConfigApiViolations({ repoRoot })).toEqual([]);
});
});

View File

@@ -66,14 +66,15 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export { evaluateGroupRouteAccessForPolicy, resolveDmGroupAccessWithLists, resolveSenderScopedGroupPolicy } from "openclaw/plugin-sdk/channel-policy";',
'export { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";',
'export { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'export { GoogleChatConfigSchema } from "openclaw/plugin-sdk/channel-config-schema-legacy";',
'export { GROUP_POLICY_BLOCKED_LABEL, isDangerousNameMatchingEnabled, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/config-runtime";',
'export { GROUP_POLICY_BLOCKED_LABEL, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";',
'export { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";',
'export { fetchRemoteMedia, resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";',
'export { loadOutboundMediaFromUrl } from "openclaw/plugin-sdk/outbound-media";',
'export type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";',
'export { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";',
'export type { GoogleChatAccountConfig, GoogleChatConfig } from "openclaw/plugin-sdk/config-runtime";',
'export type { GoogleChatAccountConfig, GoogleChatConfig } from "openclaw/plugin-sdk/config-types";',
'export { extractToolSend } from "openclaw/plugin-sdk/tool-send";',
'export { resolveInboundMentionDecision } from "openclaw/plugin-sdk/channel-inbound";',
'export { resolveInboundRouteEnvelopeBuilderWithRuntime } from "openclaw/plugin-sdk/inbound-envelope";',
@@ -94,8 +95,9 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";',
'export { PAIRING_APPROVED_MESSAGE, buildProbeChannelStatusSummary, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/channel-status";',
'export { buildChannelKeyCandidates, normalizeChannelSlug, resolveChannelEntryMatchWithFallback, resolveNestedAllowlistDecision } from "openclaw/plugin-sdk/channel-targets";',
'export type { GroupPolicy, GroupToolPolicyConfig, MSTeamsChannelConfig, MSTeamsConfig, MSTeamsReplyStyle, MSTeamsTeamConfig, MarkdownTableMode, OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'export { isDangerousNameMatchingEnabled, resolveDefaultGroupPolicy } from "openclaw/plugin-sdk/config-runtime";',
'export type { GroupPolicy, GroupToolPolicyConfig, MSTeamsChannelConfig, MSTeamsConfig, MSTeamsReplyStyle, MSTeamsTeamConfig, MarkdownTableMode, OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'export { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";',
'export { resolveDefaultGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";',
'export { withFileLock } from "openclaw/plugin-sdk/file-lock";',
'export { keepHttpServerTaskAlive } from "openclaw/plugin-sdk/channel-lifecycle";',
'export { detectMime, extensionForMime, extractOriginalFilename, getFileExtension, resolveChannelMediaMaxBytes } from "openclaw/plugin-sdk/media-runtime";',
@@ -127,7 +129,7 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export { setMatrixRuntime } from "./src/runtime.js";',
'export { writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store";',
'export type { ChannelDirectoryEntry, ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-contract";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'export { formatZonedTimestamp } from "openclaw/plugin-sdk/core";',
'export type { PluginRuntime, RuntimeLogger } from "openclaw/plugin-sdk/plugin-runtime";',
'export type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";',
@@ -144,8 +146,8 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export { logInboundDrop } from "openclaw/plugin-sdk/channel-logging";',
'export { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";',
'export { readStoreAllowFromForDmPolicy, resolveDmGroupAccessWithCommandGate } from "openclaw/plugin-sdk/channel-policy";',
'export type { BlockStreamingCoalesceConfig, DmConfig, DmPolicy, GroupPolicy, GroupToolPolicyConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'export { GROUP_POLICY_BLOCKED_LABEL, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/config-runtime";',
'export type { BlockStreamingCoalesceConfig, DmConfig, DmPolicy, GroupPolicy, GroupToolPolicyConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'export { GROUP_POLICY_BLOCKED_LABEL, resolveAllowlistProviderRuntimeGroupPolicy, resolveDefaultGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";',
'export { dispatchInboundReplyWithBase } from "openclaw/plugin-sdk/inbound-reply-dispatch";',
'export type { OutboundReplyPayload } from "openclaw/plugin-sdk/reply-payload";',
'export { deliverFormattedTextWithAttachments } from "openclaw/plugin-sdk/reply-payload";',
@@ -156,7 +158,7 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export { setNextcloudTalkRuntime } from "./src/runtime.js";',
],
[bundledPluginFile({ rootDir: ROOT_DIR, pluginId: "nostr", relativePath: "runtime-api.ts" })]: [
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'export { getPluginRuntimeGatewayRequestScope } from "openclaw/plugin-sdk/plugin-runtime";',
'export type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";',
],
@@ -202,7 +204,7 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export { resolveTelegramToken } from "./src/token.js";',
'export { setTelegramRuntime } from "./src/runtime.js";',
'export type { ChannelPlugin } from "openclaw/plugin-sdk/channel-core";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'export type TelegramAccountConfig = NonNullable< NonNullable<RuntimeOpenClawConfig["channels"]>["telegram"] >;',
'export type TelegramActionConfig = NonNullable<TelegramAccountConfig["actions"]>;',
'export type TelegramNetworkConfig = NonNullable<TelegramAccountConfig["network"]>;',
@@ -213,7 +215,7 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
'export type { ChannelAccountSnapshot, ChannelCapabilities, ChannelGatewayContext, ChannelLogSink, ChannelMessageActionAdapter, ChannelMessageActionContext, ChannelMeta, ChannelOutboundAdapter, ChannelOutboundContext, ChannelResolveKind, ChannelResolveResult, ChannelStatusAdapter } from "openclaw/plugin-sdk/channel-contract";',
'export type { ChannelPlugin } from "openclaw/plugin-sdk/channel-core";',
'export type { OutboundDeliveryResult } from "openclaw/plugin-sdk/channel-send-result";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";',
'export type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";',
'export type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";',
'export type { WizardPrompter } from "openclaw/plugin-sdk/setup";',
],

View File

@@ -100,9 +100,7 @@ describe("startLazyPluginServiceModule", () => {
platformSpy.mockRestore();
}
expect(importModule).toHaveBeenCalledWith(
"file:///C:/Users/alice/plugin%20folder/x%23y.mjs",
);
expect(importModule).toHaveBeenCalledWith("file:///C:/Users/alice/plugin%20folder/x%23y.mjs");
});
it("leaves caller-supplied override loaders responsible for their own specifiers", async () => {