mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-01 06:50:23 +00:00
refactor: enforce scoped plugin sdk imports
This commit is contained in:
@@ -13,13 +13,13 @@ import {
|
||||
setSetupChannelEnabled,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import {
|
||||
createAllowlistSetupWizardProxy,
|
||||
type ChannelSetupAdapter,
|
||||
type ChannelSetupDmPolicy,
|
||||
type ChannelSetupWizard,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import { inspectDiscordAccount } from "./account-inspect.js";
|
||||
import { listDiscordAccountIds, resolveDiscordAccount } from "./accounts.js";
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ import {
|
||||
setSetupChannelEnabled,
|
||||
type WizardPrompter,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import { type ChannelSetupDmPolicy, type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import { inspectDiscordAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listDiscordAccountIds,
|
||||
|
||||
@@ -10,13 +10,13 @@ import {
|
||||
type OpenClawConfig,
|
||||
type WizardPrompter,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import type {
|
||||
ChannelSetupAdapter,
|
||||
ChannelSetupDmPolicy,
|
||||
ChannelSetupWizard,
|
||||
ChannelSetupWizardTextInput,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import {
|
||||
listIMessageAccountIds,
|
||||
resolveDefaultIMessageAccountId,
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import {
|
||||
setSetupChannelEnabled,
|
||||
type ChannelSetupWizard,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { setSetupChannelEnabled, type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||
import { detectBinary } from "../../../src/plugins/setup-binary.js";
|
||||
import { listIMessageAccountIds, resolveIMessageAccount } from "./accounts.js";
|
||||
import {
|
||||
|
||||
@@ -2,19 +2,19 @@ import {
|
||||
buildAccountScopedDmSecurityPolicy,
|
||||
collectAllowlistProviderRestrictSendersWarnings,
|
||||
} from "openclaw/plugin-sdk/channel-policy";
|
||||
import {
|
||||
deleteAccountFromConfigSection,
|
||||
setAccountEnabledInConfigSection,
|
||||
} from "../../../src/channels/plugins/config-helpers.js";
|
||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
||||
import { IMessageConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
|
||||
import {
|
||||
formatTrimmedAllowFromEntries,
|
||||
resolveIMessageConfigAllowFrom,
|
||||
resolveIMessageConfigDefaultTo,
|
||||
} from "../../../src/plugin-sdk/channel-config-helpers.js";
|
||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
||||
import {
|
||||
deleteAccountFromConfigSection,
|
||||
setAccountEnabledInConfigSection,
|
||||
} from "../../../src/channels/plugins/config-helpers.js";
|
||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
||||
import { IMessageConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
|
||||
import {
|
||||
listIMessageAccountIds,
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import {
|
||||
setSetupChannelEnabled,
|
||||
type ChannelSetupWizard,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { setSetupChannelEnabled, type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||
import { detectBinary } from "../../../src/plugins/setup-binary.js";
|
||||
import { installSignalCli } from "../../../src/plugins/signal-cli-install.js";
|
||||
import { listSignalAccountIds, resolveSignalAccount } from "./accounts.js";
|
||||
|
||||
@@ -15,13 +15,13 @@ import {
|
||||
setLegacyChannelDmPolicyWithAllowFrom,
|
||||
setSetupChannelEnabled,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import {
|
||||
type ChannelSetupAdapter,
|
||||
type ChannelSetupDmPolicy,
|
||||
type ChannelSetupWizard,
|
||||
type ChannelSetupWizardAllowFromEntry,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import { inspectSlackAccount } from "./account-inspect.js";
|
||||
import { listSlackAccountIds, resolveSlackAccount, type ResolvedSlackAccount } from "./accounts.js";
|
||||
import {
|
||||
|
||||
@@ -14,12 +14,12 @@ import {
|
||||
setSetupChannelEnabled,
|
||||
type WizardPrompter,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import type {
|
||||
ChannelSetupDmPolicy,
|
||||
ChannelSetupWizard,
|
||||
ChannelSetupWizardAllowFromEntry,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import { inspectSlackAccount } from "./account-inspect.js";
|
||||
import {
|
||||
listSlackAccountIds,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/telegram";
|
||||
import { expect, vi } from "vitest";
|
||||
import {
|
||||
|
||||
@@ -9,9 +9,9 @@ import {
|
||||
type OpenClawConfig,
|
||||
type WizardPrompter,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import type { ChannelSetupAdapter, ChannelSetupDmPolicy } from "openclaw/plugin-sdk/setup";
|
||||
import { formatCliCommand } from "../../../src/cli/command-format.js";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import type { ChannelSetupAdapter, ChannelSetupDmPolicy } from "openclaw/plugin-sdk/setup";
|
||||
import { resolveDefaultTelegramAccountId, resolveTelegramAccount } from "./accounts.js";
|
||||
import { fetchTelegramChatId } from "./api-fetch.js";
|
||||
|
||||
|
||||
@@ -10,9 +10,9 @@ import {
|
||||
type DmPolicy,
|
||||
type OpenClawConfig,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||
import { formatCliCommand } from "../../../src/cli/command-format.js";
|
||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
||||
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||
import { listWhatsAppAccountIds, resolveWhatsAppAuthDir } from "./accounts.js";
|
||||
import { loginWeb } from "./login.js";
|
||||
import { whatsappSetupAdapter } from "./setup-core.js";
|
||||
|
||||
@@ -3,20 +3,20 @@ import {
|
||||
collectAllowlistProviderGroupPolicyWarnings,
|
||||
collectOpenGroupPolicyRouteAllowlistWarnings,
|
||||
} from "openclaw/plugin-sdk/channel-policy";
|
||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
||||
import {
|
||||
resolveWhatsAppGroupRequireMention,
|
||||
resolveWhatsAppGroupToolPolicy,
|
||||
} from "../../../src/channels/plugins/group-mentions.js";
|
||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
||||
import { resolveWhatsAppGroupIntroHint } from "../../../src/channels/plugins/whatsapp-shared.js";
|
||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
||||
import { WhatsAppConfigSchema } from "../../../src/config/zod-schema.providers-whatsapp.js";
|
||||
import {
|
||||
formatWhatsAppConfigAllowFromEntries,
|
||||
resolveWhatsAppConfigAllowFrom,
|
||||
resolveWhatsAppConfigDefaultTo,
|
||||
} from "../../../src/plugin-sdk/channel-config-helpers.js";
|
||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
||||
import {
|
||||
resolveWhatsAppGroupRequireMention,
|
||||
resolveWhatsAppGroupToolPolicy,
|
||||
} from "../../../src/channels/plugins/group-mentions.js";
|
||||
import { resolveWhatsAppGroupIntroHint } from "../../../src/channels/plugins/whatsapp-shared.js";
|
||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
||||
import { WhatsAppConfigSchema } from "../../../src/config/zod-schema.providers-whatsapp.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
|
||||
import { normalizeE164 } from "../../../src/utils.js";
|
||||
import {
|
||||
|
||||
@@ -68,6 +68,27 @@ function collectSharedExtensionSourceFiles(): string[] {
|
||||
return collectPluginSourceFiles(path.join(process.cwd(), "extensions", "shared"));
|
||||
}
|
||||
|
||||
function collectBundledExtensionSourceFiles(): string[] {
|
||||
const extensionsDir = path.join(process.cwd(), "extensions");
|
||||
let entries: fs.Dirent[] = [];
|
||||
try {
|
||||
entries = fs.readdirSync(extensionsDir, { withFileTypes: true });
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
|
||||
const files: string[] = [];
|
||||
for (const entry of entries) {
|
||||
if (!entry.isDirectory() || entry.name === "shared") {
|
||||
continue;
|
||||
}
|
||||
for (const srcFile of collectPluginSourceFiles(path.join(extensionsDir, entry.name))) {
|
||||
files.push(srcFile);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
function main() {
|
||||
const discovery = discoverOpenClawPlugins({});
|
||||
const bundledCandidates = discovery.candidates.filter((c) => c.origin === "bundled");
|
||||
@@ -81,6 +102,9 @@ function main() {
|
||||
for (const sharedFile of collectSharedExtensionSourceFiles()) {
|
||||
filesToCheck.add(sharedFile);
|
||||
}
|
||||
for (const extensionFile of collectBundledExtensionSourceFiles()) {
|
||||
filesToCheck.add(extensionFile);
|
||||
}
|
||||
|
||||
const monolithicOffenders: string[] = [];
|
||||
const legacyCompatOffenders: string[] = [];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
@@ -108,6 +108,47 @@ function readSetupBarrelImportBlock(path: string): string {
|
||||
return lines.slice(startLineIndex, targetLineIndex + 1).join("\n");
|
||||
}
|
||||
|
||||
function collectExtensionSourceFiles(): string[] {
|
||||
const extensionsDir = resolve(ROOT_DIR, "..", "extensions");
|
||||
const sharedExtensionsDir = resolve(extensionsDir, "shared");
|
||||
const files: string[] = [];
|
||||
const stack = [extensionsDir];
|
||||
while (stack.length > 0) {
|
||||
const current = stack.pop();
|
||||
if (!current) {
|
||||
continue;
|
||||
}
|
||||
for (const entry of readdirSync(current, { withFileTypes: true })) {
|
||||
const fullPath = resolve(current, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "coverage") {
|
||||
continue;
|
||||
}
|
||||
stack.push(fullPath);
|
||||
continue;
|
||||
}
|
||||
if (!entry.isFile() || !/\.(?:[cm]?ts|[cm]?js|tsx|jsx)$/u.test(entry.name)) {
|
||||
continue;
|
||||
}
|
||||
if (entry.name.endsWith(".d.ts") || fullPath.includes(sharedExtensionsDir)) {
|
||||
continue;
|
||||
}
|
||||
if (fullPath.includes(`${resolve(ROOT_DIR, "..", "extensions")}/shared/`)) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
fullPath.includes(".test.") ||
|
||||
fullPath.includes(".fixture.") ||
|
||||
fullPath.includes(".snap")
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
files.push(fullPath);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
describe("channel import guardrails", () => {
|
||||
it("keeps channel helper modules off their own SDK barrels", () => {
|
||||
for (const source of SAME_CHANNEL_SDK_GUARDS) {
|
||||
@@ -128,4 +169,16 @@ describe("channel import guardrails", () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps bundled extension source files off root and compat plugin-sdk imports", () => {
|
||||
for (const file of collectExtensionSourceFiles()) {
|
||||
const text = readFileSync(file, "utf8");
|
||||
expect(text, `${file} should not import openclaw/plugin-sdk root`).not.toMatch(
|
||||
/["']openclaw\/plugin-sdk["']/,
|
||||
);
|
||||
expect(text, `${file} should not import openclaw/plugin-sdk/compat`).not.toMatch(
|
||||
/["']openclaw\/plugin-sdk\/compat["']/,
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user