| #!/usr/bin/env node |
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
| import { readFileSync, existsSync } from "node:fs"; |
| import { resolve, dirname } from "node:path"; |
| import { fileURLToPath } from "node:url"; |
|
|
| const __dirname = dirname(fileURLToPath(import.meta.url)); |
| const distFile = resolve(__dirname, "..", "dist", "plugin-sdk", "index.js"); |
|
|
| if (!existsSync(distFile)) { |
| console.error("ERROR: dist/plugin-sdk/index.js not found. Run `pnpm build` first."); |
| process.exit(1); |
| } |
|
|
| const content = readFileSync(distFile, "utf-8"); |
|
|
| |
| |
| const exportMatch = content.match(/export\s*\{([^}]+)\}\s*;?\s*$/); |
| if (!exportMatch) { |
| console.error("ERROR: Could not find export statement in dist/plugin-sdk/index.js"); |
| process.exit(1); |
| } |
|
|
| const exportedNames = exportMatch[1] |
| .split(",") |
| .map((s) => { |
| |
| const parts = s.trim().split(/\s+as\s+/); |
| return (parts[parts.length - 1] || "").trim(); |
| }) |
| .filter(Boolean); |
|
|
| const exportSet = new Set(exportedNames); |
|
|
| const requiredSubpathEntries = [ |
| "core", |
| "compat", |
| "telegram", |
| "discord", |
| "slack", |
| "signal", |
| "imessage", |
| "whatsapp", |
| "line", |
| "msteams", |
| "acpx", |
| "bluebubbles", |
| "copilot-proxy", |
| "device-pair", |
| "diagnostics-otel", |
| "diffs", |
| "feishu", |
| "google-gemini-cli-auth", |
| "googlechat", |
| "irc", |
| "llm-task", |
| "lobster", |
| "matrix", |
| "mattermost", |
| "memory-core", |
| "memory-lancedb", |
| "minimax-portal-auth", |
| "nextcloud-talk", |
| "nostr", |
| "open-prose", |
| "phone-control", |
| "qwen-portal-auth", |
| "synology-chat", |
| "talk-voice", |
| "test-utils", |
| "thread-ownership", |
| "tlon", |
| "twitch", |
| "voice-call", |
| "zalo", |
| "zalouser", |
| "account-id", |
| "keyed-async-queue", |
| ]; |
|
|
| const requiredRuntimeShimEntries = ["root-alias.cjs"]; |
|
|
| |
| |
| |
| const requiredExports = [ |
| "isDangerousNameMatchingEnabled", |
| "createAccountListHelpers", |
| "buildAgentMediaPayload", |
| "createReplyPrefixOptions", |
| "createTypingCallbacks", |
| "logInboundDrop", |
| "logTypingFailure", |
| "buildPendingHistoryContextFromMap", |
| "clearHistoryEntriesIfEnabled", |
| "recordPendingHistoryEntryIfEnabled", |
| "resolveControlCommandGate", |
| "resolveDmGroupAccessWithLists", |
| "resolveAllowlistProviderRuntimeGroupPolicy", |
| "resolveDefaultGroupPolicy", |
| "resolveChannelMediaMaxBytes", |
| "warnMissingProviderGroupPolicyFallbackOnce", |
| "emptyPluginConfigSchema", |
| "normalizePluginHttpPath", |
| "registerPluginHttpRoute", |
| "DEFAULT_ACCOUNT_ID", |
| "DEFAULT_GROUP_HISTORY_LIMIT", |
| ]; |
|
|
| let missing = 0; |
| for (const name of requiredExports) { |
| if (!exportSet.has(name)) { |
| console.error(`MISSING EXPORT: ${name}`); |
| missing += 1; |
| } |
| } |
|
|
| for (const entry of requiredSubpathEntries) { |
| const jsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.js`); |
| const dtsPath = resolve(__dirname, "..", "dist", "plugin-sdk", `${entry}.d.ts`); |
| if (!existsSync(jsPath)) { |
| console.error(`MISSING SUBPATH JS: dist/plugin-sdk/${entry}.js`); |
| missing += 1; |
| } |
| if (!existsSync(dtsPath)) { |
| console.error(`MISSING SUBPATH DTS: dist/plugin-sdk/${entry}.d.ts`); |
| missing += 1; |
| } |
| } |
|
|
| for (const entry of requiredRuntimeShimEntries) { |
| const shimPath = resolve(__dirname, "..", "dist", "plugin-sdk", entry); |
| if (!existsSync(shimPath)) { |
| console.error(`MISSING RUNTIME SHIM: dist/plugin-sdk/${entry}`); |
| missing += 1; |
| } |
| } |
|
|
| if (missing > 0) { |
| console.error( |
| `\nERROR: ${missing} required plugin-sdk artifact(s) missing (named exports or subpath files).`, |
| ); |
| console.error("This will break channel extension plugins at runtime."); |
| console.error("Check src/plugin-sdk/index.ts, subpath entries, and rebuild."); |
| process.exit(1); |
| } |
|
|
| console.log(`OK: All ${requiredExports.length} required plugin-sdk exports verified.`); |
|
|