import { existsSync, readFileSync, readdirSync } from "node:fs"; import { join, posix, resolve } from "node:path"; import { privateLocalOnlyPluginSdkEntrypoints } from "./plugin-sdk-entries.mjs"; export const EXTENSION_PACKAGE_BOUNDARY_INCLUDE = ["./*.ts", "./src/**/*.ts"] as const; export const EXTENSION_PACKAGE_BOUNDARY_EXCLUDE = [ "./**/*.test.ts", "./dist/**", "./node_modules/**", "./src/test-support/**", "./src/**/*test-helpers.ts", "./src/**/*test-harness.ts", "./src/**/*test-support.ts", ] as const; const privateLocalOnlyPluginSdkPackageDtsPaths = Object.fromEntries( privateLocalOnlyPluginSdkEntrypoints.map((entrypoint) => [ `openclaw/plugin-sdk/${entrypoint}`, [`../packages/plugin-sdk/dist/src/plugin-sdk/${entrypoint}.d.ts`], ]), ) as Record; export const EXTENSION_PACKAGE_BOUNDARY_BASE_PATHS = { "openclaw/extension-api": ["../src/extensionAPI.ts"], "openclaw/plugin-sdk": ["../dist/plugin-sdk/index.d.ts"], "openclaw/plugin-sdk/*": ["../dist/plugin-sdk/*.d.ts"], ...privateLocalOnlyPluginSdkPackageDtsPaths, "openclaw/plugin-sdk/account-id": ["../dist/plugin-sdk/account-id.d.ts"], "openclaw/plugin-sdk/channel-entry-contract": ["../dist/plugin-sdk/channel-entry-contract.d.ts"], "openclaw/plugin-sdk/browser-maintenance": [ "../packages/plugin-sdk/dist/extensions/browser/browser-maintenance.d.ts", ], "openclaw/plugin-sdk/channel-secret-basic-runtime": [ "../dist/plugin-sdk/channel-secret-basic-runtime.d.ts", ], "openclaw/plugin-sdk/channel-secret-runtime": ["../dist/plugin-sdk/channel-secret-runtime.d.ts"], "openclaw/plugin-sdk/channel-secret-tts-runtime": [ "../dist/plugin-sdk/channel-secret-tts-runtime.d.ts", ], "openclaw/plugin-sdk/channel-streaming": ["../dist/plugin-sdk/channel-streaming.d.ts"], "openclaw/plugin-sdk/error-runtime": ["../dist/plugin-sdk/error-runtime.d.ts"], "openclaw/plugin-sdk/provider-catalog-shared": [ "../dist/plugin-sdk/provider-catalog-shared.d.ts", ], "openclaw/plugin-sdk/provider-entry": ["../dist/plugin-sdk/provider-entry.d.ts"], "openclaw/plugin-sdk/secret-ref-runtime": ["../dist/plugin-sdk/secret-ref-runtime.d.ts"], "openclaw/plugin-sdk/ssrf-runtime": ["../dist/plugin-sdk/ssrf-runtime.d.ts"], "@openclaw/qa-channel/api.js": ["../dist/plugin-sdk/extensions/qa-channel/api.d.ts"], "@openclaw/discord/api.js": ["../dist/plugin-sdk/extensions/discord/api.d.ts"], "@openclaw/slack/api.js": ["../dist/plugin-sdk/extensions/slack/api.d.ts"], "@openclaw/whatsapp/api.js": ["../dist/plugin-sdk/extensions/whatsapp/api.d.ts"], "@openclaw/llm-core": ["../dist/plugin-sdk/packages/llm-core/src/index.d.ts"], "@openclaw/llm-core/diagnostics": [ "../dist/plugin-sdk/packages/llm-core/src/utils/diagnostics.d.ts", ], "@openclaw/llm-core/event-stream": [ "../dist/plugin-sdk/packages/llm-core/src/utils/event-stream.d.ts", ], "@openclaw/llm-core/types": ["../dist/plugin-sdk/packages/llm-core/src/types.d.ts"], "@openclaw/llm-core/validation": ["../dist/plugin-sdk/packages/llm-core/src/validation.d.ts"], "@openclaw/llm-core/*": ["../dist/plugin-sdk/packages/llm-core/src/*.d.ts"], "@openclaw/model-catalog-core": ["../dist/plugin-sdk/packages/model-catalog-core/src/index.d.ts"], "@openclaw/model-catalog-core/configured-model-refs": [ "../dist/plugin-sdk/packages/model-catalog-core/src/configured-model-refs.d.ts", ], "@openclaw/model-catalog-core/model-catalog-refs": [ "../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-refs.d.ts", ], "@openclaw/model-catalog-core/model-catalog-normalize": [ "../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-normalize.d.ts", ], "@openclaw/model-catalog-core/model-catalog-types": [ "../dist/plugin-sdk/packages/model-catalog-core/src/model-catalog-types.d.ts", ], "@openclaw/model-catalog-core/provider-id": [ "../dist/plugin-sdk/packages/model-catalog-core/src/provider-id.d.ts", ], "@openclaw/model-catalog-core/provider-model-id-normalization": [ "../dist/plugin-sdk/packages/model-catalog-core/src/provider-model-id-normalization.d.ts", ], "@openclaw/model-catalog-core/provider-model-id-normalize": [ "../dist/plugin-sdk/packages/model-catalog-core/src/provider-model-id-normalize.d.ts", ], "@openclaw/model-catalog-core/*": ["../dist/plugin-sdk/packages/model-catalog-core/src/*.d.ts"], "@openclaw/markdown-core": ["../dist/plugin-sdk/packages/markdown-core/src/index.d.ts"], "@openclaw/markdown-core/code-spans": [ "../dist/plugin-sdk/packages/markdown-core/src/code-spans.d.ts", ], "@openclaw/markdown-core/fences": ["../dist/plugin-sdk/packages/markdown-core/src/fences.d.ts"], "@openclaw/markdown-core/frontmatter": [ "../dist/plugin-sdk/packages/markdown-core/src/frontmatter.d.ts", ], "@openclaw/markdown-core/ir": ["../dist/plugin-sdk/packages/markdown-core/src/ir.d.ts"], "@openclaw/markdown-core/render": ["../dist/plugin-sdk/packages/markdown-core/src/render.d.ts"], "@openclaw/markdown-core/render-aware-chunking": [ "../dist/plugin-sdk/packages/markdown-core/src/render-aware-chunking.d.ts", ], "@openclaw/markdown-core/tables": ["../dist/plugin-sdk/packages/markdown-core/src/tables.d.ts"], "@openclaw/markdown-core/types": ["../dist/plugin-sdk/packages/markdown-core/src/types.d.ts"], "@openclaw/markdown-core/*": ["../dist/plugin-sdk/packages/markdown-core/src/*.d.ts"], "@openclaw/media-generation-core": [ "../dist/plugin-sdk/packages/media-generation-core/src/index.d.ts", ], "@openclaw/media-generation-core/capability-model-ref": [ "../dist/plugin-sdk/packages/media-generation-core/src/capability-model-ref.d.ts", ], "@openclaw/media-generation-core/catalog": [ "../dist/plugin-sdk/packages/media-generation-core/src/catalog.d.ts", ], "@openclaw/media-generation-core/model-ref": [ "../dist/plugin-sdk/packages/media-generation-core/src/model-ref.d.ts", ], "@openclaw/media-generation-core/normalization": [ "../dist/plugin-sdk/packages/media-generation-core/src/normalization.d.ts", ], "@openclaw/media-generation-core/*": [ "../dist/plugin-sdk/packages/media-generation-core/src/*.d.ts", ], "@openclaw/terminal-core": ["../dist/plugin-sdk/packages/terminal-core/src/index.d.ts"], "@openclaw/terminal-core/ansi": ["../dist/plugin-sdk/packages/terminal-core/src/ansi.d.ts"], "@openclaw/terminal-core/decorative-emoji": [ "../dist/plugin-sdk/packages/terminal-core/src/decorative-emoji.d.ts", ], "@openclaw/terminal-core/health-style": [ "../dist/plugin-sdk/packages/terminal-core/src/health-style.d.ts", ], "@openclaw/terminal-core/links": ["../dist/plugin-sdk/packages/terminal-core/src/links.d.ts"], "@openclaw/terminal-core/note": ["../dist/plugin-sdk/packages/terminal-core/src/note.d.ts"], "@openclaw/terminal-core/osc-progress": [ "../dist/plugin-sdk/packages/terminal-core/src/osc-progress.d.ts", ], "@openclaw/terminal-core/palette": ["../dist/plugin-sdk/packages/terminal-core/src/palette.d.ts"], "@openclaw/terminal-core/progress-line": [ "../dist/plugin-sdk/packages/terminal-core/src/progress-line.d.ts", ], "@openclaw/terminal-core/prompt-select-styled": [ "../dist/plugin-sdk/packages/terminal-core/src/prompt-select-styled.d.ts", ], "@openclaw/terminal-core/prompt-select-styled-params": [ "../dist/plugin-sdk/packages/terminal-core/src/prompt-select-styled-params.d.ts", ], "@openclaw/terminal-core/prompt-style": [ "../dist/plugin-sdk/packages/terminal-core/src/prompt-style.d.ts", ], "@openclaw/terminal-core/restore": ["../dist/plugin-sdk/packages/terminal-core/src/restore.d.ts"], "@openclaw/terminal-core/safe-text": [ "../dist/plugin-sdk/packages/terminal-core/src/safe-text.d.ts", ], "@openclaw/terminal-core/stream-writer": [ "../dist/plugin-sdk/packages/terminal-core/src/stream-writer.d.ts", ], "@openclaw/terminal-core/table": ["../dist/plugin-sdk/packages/terminal-core/src/table.d.ts"], "@openclaw/terminal-core/terminal-link": [ "../dist/plugin-sdk/packages/terminal-core/src/terminal-link.d.ts", ], "@openclaw/terminal-core/theme": ["../dist/plugin-sdk/packages/terminal-core/src/theme.d.ts"], "@openclaw/terminal-core/*": ["../dist/plugin-sdk/packages/terminal-core/src/*.d.ts"], "@openclaw/*.js": ["../packages/plugin-sdk/dist/extensions/*.d.ts", "../extensions/*"], "@openclaw/*": ["../packages/plugin-sdk/dist/extensions/*", "../extensions/*"], "openclaw/plugin-sdk/qa-channel": ["../dist/plugin-sdk/src/plugin-sdk/qa-channel.d.ts"], "openclaw/plugin-sdk/qa-channel-protocol": [ "../dist/plugin-sdk/src/plugin-sdk/qa-channel-protocol.d.ts", ], "openclaw/plugin-sdk/qa-runtime": ["../dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts"], "@openclaw/plugin-sdk/*": ["../dist/plugin-sdk/*.d.ts"], } as const; function prefixExtensionPackageBoundaryPaths( paths: Record, prefix: string, ): Record { return Object.fromEntries( Object.entries(paths).map(([key, values]) => [ key, values.map((value) => posix.join(prefix, value)), ]), ); } export const EXTENSION_PACKAGE_BOUNDARY_XAI_PATHS = { ...prefixExtensionPackageBoundaryPaths( (({ "openclaw/plugin-sdk/channel-secret-basic-runtime": _omitBasic, "openclaw/plugin-sdk/channel-secret-tts-runtime": _omitTts, "@openclaw/discord/api.js": _omitDiscord, "@openclaw/slack/api.js": _omitSlack, "@openclaw/whatsapp/api.js": _omitWhatsApp, ...rest }) => rest)(EXTENSION_PACKAGE_BOUNDARY_BASE_PATHS), "../", ), "openclaw/plugin-sdk/channel-entry-contract": [ "../../dist/plugin-sdk/channel-entry-contract.d.ts", ], "openclaw/plugin-sdk/browser-maintenance": [ "../../dist/plugin-sdk/src/plugin-sdk/browser-maintenance.d.ts", ], "openclaw/plugin-sdk/cli-runtime": ["../../dist/plugin-sdk/cli-runtime.d.ts"], "openclaw/plugin-sdk/provider-catalog-shared": [ "../../dist/plugin-sdk/provider-catalog-shared.d.ts", ], "openclaw/plugin-sdk/provider-env-vars": ["../../dist/plugin-sdk/provider-env-vars.d.ts"], "openclaw/plugin-sdk/provider-entry": ["../../dist/plugin-sdk/provider-entry.d.ts"], "openclaw/plugin-sdk/provider-web-search-contract": [ "../../dist/plugin-sdk/provider-web-search-contract.d.ts", ], "@openclaw/qa-channel/api.js": ["../../dist/plugin-sdk/extensions/qa-channel/api.d.ts"], "@openclaw/*.js": ["../../packages/plugin-sdk/dist/extensions/*.d.ts", "../*"], "@openclaw/*": ["../*"], "@openclaw/plugin-sdk/*": ["../../dist/plugin-sdk/*.d.ts"], "@openclaw/anthropic-vertex/api.js": ["./.boundary-stubs/anthropic-vertex-api.d.ts"], "@openclaw/ollama/api.js": ["./.boundary-stubs/ollama-api.d.ts"], "@openclaw/ollama/runtime-api.js": ["./.boundary-stubs/ollama-runtime-api.d.ts"], "@openclaw/speech-core/runtime-api.js": ["./.boundary-stubs/speech-core-runtime-api.d.ts"], } as const; type ExtensionPackageBoundaryTsConfigJson = { extends?: unknown; compilerOptions?: { rootDir?: unknown; paths?: unknown; }; include?: unknown; exclude?: unknown; }; type ExtensionPackageBoundaryPackageJson = { devDependencies?: Record; }; // oxlint-disable-next-line typescript/no-unnecessary-type-parameters -- Boundary helper lets callers ascribe JSON file shape. function readJsonFile(filePath: string): T { return JSON.parse(readFileSync(filePath, "utf8")) as T; } function collectBundledExtensionIds(rootDir = resolve(".")): string[] { return readdirSync(join(rootDir, "extensions"), { withFileTypes: true }) .filter((entry) => entry.isDirectory()) .map((entry) => entry.name) .toSorted(); } function resolveExtensionTsconfigPath(extensionId: string, rootDir = resolve(".")): string { return join(rootDir, "extensions", extensionId, "tsconfig.json"); } function resolveExtensionPackageJsonPath(extensionId: string, rootDir = resolve(".")): string { return join(rootDir, "extensions", extensionId, "package.json"); } export function readExtensionPackageBoundaryTsconfig( extensionId: string, rootDir = resolve("."), ): ExtensionPackageBoundaryTsConfigJson { return readJsonFile( resolveExtensionTsconfigPath(extensionId, rootDir), ); } export function readExtensionPackageBoundaryPackageJson( extensionId: string, rootDir = resolve("."), ): ExtensionPackageBoundaryPackageJson { return readJsonFile( resolveExtensionPackageJsonPath(extensionId, rootDir), ); } export function isOptInExtensionPackageBoundaryTsconfig( tsconfig: ExtensionPackageBoundaryTsConfigJson, ): boolean { return tsconfig.extends === "../tsconfig.package-boundary.base.json"; } export function collectExtensionsWithTsconfig(rootDir = resolve(".")): string[] { return collectBundledExtensionIds(rootDir).filter((extensionId) => existsSync(resolveExtensionTsconfigPath(extensionId, rootDir)), ); } export function collectOptInExtensionPackageBoundaries(rootDir = resolve(".")): string[] { return collectExtensionsWithTsconfig(rootDir).filter((extensionId) => isOptInExtensionPackageBoundaryTsconfig( readExtensionPackageBoundaryTsconfig(extensionId, rootDir), ), ); }