chore: tighten plugin boundary export audit

This commit is contained in:
Peter Steinberger
2026-04-27 11:46:57 +01:00
parent 236ca49998
commit 5a81c4000c
6 changed files with 12 additions and 211 deletions

View File

@@ -208,6 +208,8 @@ For channel-owned execution helpers, bundled plugins should keep the execution r
The same boundary applies to provider-named SDK seams in general: core should not import channel-specific convenience barrels for Slack, Discord, Signal, WhatsApp, or similar extensions. If core needs a behavior, either consume the bundled plugin's own `api.ts` / `runtime-api.ts` barrel or promote the need into a narrow generic capability in the shared SDK.
Bundled plugins follow the same rule. A bundled plugin's `runtime-api.ts` should not re-export its own branded `openclaw/plugin-sdk/<plugin-id>` facade. Those branded facades remain compatibility shims for external plugins and older consumers, but bundled plugins should use local exports plus narrow generic SDK subpaths such as `openclaw/plugin-sdk/channel-policy`, `openclaw/plugin-sdk/runtime-store`, or `openclaw/plugin-sdk/webhook-ingress`. New code should not add plugin-id-specific SDK facades unless the compatibility boundary for an existing external ecosystem requires it.
For polls specifically, there are two execution paths:
- `outbound.sendPoll` is the shared baseline for channels that fit the common poll model

View File

@@ -338,6 +338,10 @@
"types": "./dist/plugin-sdk/speech-core.d.ts",
"default": "./dist/plugin-sdk/speech-core.js"
},
"./plugin-sdk/tts-runtime": {
"types": "./dist/plugin-sdk/tts-runtime.d.ts",
"default": "./dist/plugin-sdk/tts-runtime.js"
},
"./plugin-sdk/plugin-runtime": {
"types": "./dist/plugin-sdk/plugin-runtime.d.ts",
"default": "./dist/plugin-sdk/plugin-runtime.js"

View File

@@ -144,6 +144,10 @@
"types": "./dist/src/plugin-sdk/text-runtime.d.ts",
"default": "./src/text-runtime.ts"
},
"./tts-runtime": {
"types": "./dist/src/plugin-sdk/tts-runtime.d.ts",
"default": "./src/tts-runtime.ts"
},
"./testing": {
"types": "./dist/src/plugin-sdk/testing.d.ts",
"default": "./src/testing.ts"

View File

@@ -38,12 +38,6 @@ const baselinePathByMode = {
"fixtures",
"extension-plugin-sdk-internal-inventory.json",
),
"relative-outside-package": path.join(
repoRoot,
"test",
"fixtures",
"extension-relative-outside-package-inventory.json",
),
};
let allInventoryByModePromise;
@@ -264,9 +258,7 @@ export async function readExpectedInventory(mode) {
return JSON.parse(await fs.readFile(baselinePathByMode[mode], "utf8"));
} catch (error) {
if (
(mode === "plugin-sdk-internal" ||
mode === "src-outside-plugin-sdk" ||
mode === "relative-outside-package") &&
(mode === "plugin-sdk-internal" || mode === "src-outside-plugin-sdk") &&
error &&
typeof error === "object" &&
"code" in error &&

View File

@@ -68,6 +68,7 @@
"agent-runtime",
"simple-completion-runtime",
"speech-core",
"tts-runtime",
"plugin-runtime",
"skills-runtime",
"channel-secret-basic-runtime",

View File

@@ -1,202 +0,0 @@
[
{
"file": "extensions/bluebubbles/src/runtime-api.ts",
"line": 1,
"kind": "export",
"specifier": "../../../src/plugin-sdk/bluebubbles.js",
"resolvedPath": "src/plugin-sdk/bluebubbles.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/bluebubbles/src/targets.ts",
"line": 8,
"kind": "import",
"specifier": "../../imessage/api.js",
"resolvedPath": "extensions/imessage/api.js",
"reason": "imports another extension via relative path outside the extension package"
},
{
"file": "extensions/feishu/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/feishu.js",
"resolvedPath": "src/plugin-sdk/feishu.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/googlechat/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/googlechat.js",
"resolvedPath": "src/plugin-sdk/googlechat.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/imessage/runtime-api.ts",
"line": 16,
"kind": "export",
"specifier": "../../src/plugin-sdk/imessage.js",
"resolvedPath": "src/plugin-sdk/imessage.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/irc/src/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../../src/plugin-sdk/irc.js",
"resolvedPath": "src/plugin-sdk/irc.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/line/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/line.js",
"resolvedPath": "src/plugin-sdk/line.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/line/runtime-api.ts",
"line": 13,
"kind": "export",
"specifier": "../../src/plugin-sdk/line-core.js",
"resolvedPath": "src/plugin-sdk/line-core.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/matrix/runtime-api.ts",
"line": 19,
"kind": "export",
"specifier": "../../src/plugin-sdk/json-store.js",
"resolvedPath": "src/plugin-sdk/json-store.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/matrix/runtime-api.ts",
"line": 28,
"kind": "export",
"specifier": "../../src/plugin-sdk/matrix.js",
"resolvedPath": "src/plugin-sdk/matrix.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/matrix/runtime-api.ts",
"line": 29,
"kind": "export",
"specifier": "../../src/plugin-sdk/matrix.js",
"resolvedPath": "src/plugin-sdk/matrix.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/matrix/src/runtime-api.ts",
"line": 1,
"kind": "export",
"specifier": "../../../src/plugin-sdk/matrix.js",
"resolvedPath": "src/plugin-sdk/matrix.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/mattermost/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/mattermost.js",
"resolvedPath": "src/plugin-sdk/mattermost.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/msteams/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/msteams.js",
"resolvedPath": "src/plugin-sdk/msteams.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/nextcloud-talk/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/nextcloud-talk.js",
"resolvedPath": "src/plugin-sdk/nextcloud-talk.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/nostr/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/nostr.js",
"resolvedPath": "src/plugin-sdk/nostr.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/telegram/runtime-api.ts",
"line": 10,
"kind": "export",
"specifier": "../../src/plugin-sdk/telegram.js",
"resolvedPath": "src/plugin-sdk/telegram.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/telegram/runtime-api.ts",
"line": 40,
"kind": "export",
"specifier": "../../src/plugin-sdk/telegram.js",
"resolvedPath": "src/plugin-sdk/telegram.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/tlon/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/tlon.js",
"resolvedPath": "src/plugin-sdk/tlon.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/twitch/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/twitch.js",
"resolvedPath": "src/plugin-sdk/twitch.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/voice-call/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/voice-call.js",
"resolvedPath": "src/plugin-sdk/voice-call.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/whatsapp/src/runtime-api.ts",
"line": 19,
"kind": "export",
"specifier": "../../../src/plugin-sdk/whatsapp-core.js",
"resolvedPath": "src/plugin-sdk/whatsapp-core.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/whatsapp/src/runtime-api.ts",
"line": 34,
"kind": "export",
"specifier": "../../../src/plugin-sdk/whatsapp-shared.js",
"resolvedPath": "src/plugin-sdk/whatsapp-shared.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/zalo/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/zalo.js",
"resolvedPath": "src/plugin-sdk/zalo.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
},
{
"file": "extensions/zalouser/runtime-api.ts",
"line": 4,
"kind": "export",
"specifier": "../../src/plugin-sdk/zalouser.js",
"resolvedPath": "src/plugin-sdk/zalouser.js",
"reason": "re-exports plugin-sdk via relative path; use openclaw/plugin-sdk/<subpath>"
}
]