mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 14:01:24 +08:00
Compare commits
8 Commits
v2026.6.4-
...
flat-decla
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4149dc0af1 | ||
|
|
39973675c5 | ||
|
|
a974fd2f77 | ||
|
|
59a4ab4daa | ||
|
|
ca61f668d5 | ||
|
|
3cda9be785 | ||
|
|
ed2c6bee69 | ||
|
|
2815ac066b |
@@ -8,6 +8,10 @@ import {
|
||||
resolveNodeFromNodeList,
|
||||
type NodeMatchCandidate,
|
||||
} from "openclaw/plugin-sdk/gateway-runtime";
|
||||
import {
|
||||
parseStrictFiniteNumber,
|
||||
parseStrictPositiveInteger,
|
||||
} from "openclaw/plugin-sdk/number-runtime";
|
||||
import { defaultRuntime } from "openclaw/plugin-sdk/runtime";
|
||||
import {
|
||||
normalizeLowercaseStringOrEmpty,
|
||||
@@ -70,41 +74,6 @@ export type CanvasCliDependencies = {
|
||||
type CanvasNodeCandidate = NodeMatchCandidate;
|
||||
type CanvasSnapshotRequestFormat = "png" | "jpeg";
|
||||
|
||||
function normalizeNumericString(value: string): string | undefined {
|
||||
const trimmed = value.trim();
|
||||
return trimmed ? trimmed : undefined;
|
||||
}
|
||||
|
||||
function parseStrictPositiveInteger(value: unknown): number | undefined {
|
||||
if (typeof value === "number") {
|
||||
return Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
||||
}
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = normalizeNumericString(value);
|
||||
if (!normalized || !/^\+?\d+$/.test(normalized)) {
|
||||
return undefined;
|
||||
}
|
||||
const parsed = Number(normalized);
|
||||
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : undefined;
|
||||
}
|
||||
|
||||
function parseStrictFiniteNumber(value: unknown): number | undefined {
|
||||
if (typeof value === "number") {
|
||||
return Number.isFinite(value) ? value : undefined;
|
||||
}
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const normalized = normalizeNumericString(value);
|
||||
if (!normalized || !/^[+-]?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:e[+-]?\d+)?$/i.test(normalized)) {
|
||||
return undefined;
|
||||
}
|
||||
const parsed = Number(normalized);
|
||||
return Number.isFinite(parsed) ? parsed : undefined;
|
||||
}
|
||||
|
||||
function parseCanvasSnapshotRequestFormat(raw: unknown): CanvasSnapshotRequestFormat {
|
||||
const format = normalizeLowercaseStringOrEmpty(normalizeOptionalString(raw) ?? "jpg");
|
||||
switch (format) {
|
||||
|
||||
@@ -3,42 +3,97 @@
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"openclaw/extension-api": ["../src/extensionAPI.ts"],
|
||||
"openclaw/plugin-sdk": ["../dist/plugin-sdk/src/plugin-sdk/index.d.ts"],
|
||||
"openclaw/plugin-sdk/*": ["../dist/plugin-sdk/src/plugin-sdk/*.d.ts"],
|
||||
"openclaw/plugin-sdk/account-id": ["../dist/plugin-sdk/src/plugin-sdk/account-id.d.ts"],
|
||||
"openclaw/plugin-sdk": ["../dist/plugin-sdk/index.d.ts"],
|
||||
"openclaw/plugin-sdk/*": ["../dist/plugin-sdk/*.d.ts"],
|
||||
"openclaw/plugin-sdk/reply-payload-testing": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/reply-payload-testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/ssrf-runtime-internal": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/ssrf-runtime-internal.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/codex-native-task-runtime": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/codex-native-task-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/agent-runtime-test-contracts": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/agent-runtime-test-contracts.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-target-testing": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-target-testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-test-helpers": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-test-helpers.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/plugin-test-api": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-api.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/plugin-test-contracts": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-contracts.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/plugin-test-runtime": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-http-test-mocks": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/provider-http-test-mocks.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-test-contracts": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/provider-test-contracts.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/test-env": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/test-env.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/test-fixtures": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/test-fixtures.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/test-node-mocks": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/test-node-mocks.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/testing": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-contract-testing": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-contract-testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/account-id": ["../dist/plugin-sdk/account-id.d.ts"],
|
||||
"openclaw/plugin-sdk/channel-entry-contract": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-entry-contract.d.ts"
|
||||
"../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": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-secret-basic-runtime.d.ts"
|
||||
"../dist/plugin-sdk/channel-secret-basic-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-secret-runtime": [
|
||||
"../dist/plugin-sdk/src/plugin-sdk/channel-secret-runtime.d.ts"
|
||||
"../dist/plugin-sdk/channel-secret-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-secret-tts-runtime": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-secret-tts-runtime.d.ts"
|
||||
"../dist/plugin-sdk/channel-secret-tts-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/error-runtime": ["../dist/plugin-sdk/src/plugin-sdk/error-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": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/provider-catalog-shared.d.ts"
|
||||
"../dist/plugin-sdk/provider-catalog-shared.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-entry": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/provider-entry.d.ts"
|
||||
"../dist/plugin-sdk/provider-entry.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/secret-ref-runtime": [
|
||||
"../dist/plugin-sdk/src/plugin-sdk/secret-ref-runtime.d.ts"
|
||||
"../dist/plugin-sdk/secret-ref-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/ssrf-runtime": ["../dist/plugin-sdk/src/plugin-sdk/ssrf-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/*.js": ["../packages/plugin-sdk/dist/extensions/*.d.ts", "../extensions/*"],
|
||||
"@openclaw/*": ["../packages/plugin-sdk/dist/extensions/*", "../extensions/*"],
|
||||
"@openclaw/plugin-sdk/*": ["../dist/plugin-sdk/src/plugin-sdk/*.d.ts"]
|
||||
"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/*": ["../dist/plugin-sdk/*.d.ts"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,44 +4,101 @@
|
||||
"rootDir": ".",
|
||||
"paths": {
|
||||
"openclaw/extension-api": ["../../src/extensionAPI.ts"],
|
||||
"openclaw/plugin-sdk": ["../../dist/plugin-sdk/src/plugin-sdk/index.d.ts"],
|
||||
"openclaw/plugin-sdk/*": ["../../dist/plugin-sdk/src/plugin-sdk/*.d.ts"],
|
||||
"openclaw/plugin-sdk/account-id": ["../../dist/plugin-sdk/src/plugin-sdk/account-id.d.ts"],
|
||||
"openclaw/plugin-sdk": ["../../dist/plugin-sdk/index.d.ts"],
|
||||
"openclaw/plugin-sdk/*": ["../../dist/plugin-sdk/*.d.ts"],
|
||||
"openclaw/plugin-sdk/reply-payload-testing": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/reply-payload-testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/ssrf-runtime-internal": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/ssrf-runtime-internal.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/codex-native-task-runtime": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/codex-native-task-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/agent-runtime-test-contracts": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/agent-runtime-test-contracts.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-target-testing": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/channel-target-testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-test-helpers": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/channel-test-helpers.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/plugin-test-api": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-api.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/plugin-test-contracts": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-contracts.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/plugin-test-runtime": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/plugin-test-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-http-test-mocks": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/provider-http-test-mocks.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-test-contracts": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/provider-test-contracts.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/test-env": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-env.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/test-fixtures": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-fixtures.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/test-node-mocks": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/test-node-mocks.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/testing": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-contract-testing": [
|
||||
"../../packages/plugin-sdk/dist/src/plugin-sdk/channel-contract-testing.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/account-id": ["../../dist/plugin-sdk/account-id.d.ts"],
|
||||
"openclaw/plugin-sdk/channel-entry-contract": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/channel-entry-contract.d.ts"
|
||||
"../../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/channel-secret-runtime": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/channel-secret-runtime.d.ts"
|
||||
"../../dist/plugin-sdk/channel-secret-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/cli-runtime": ["../../dist/plugin-sdk/src/plugin-sdk/cli-runtime.d.ts"],
|
||||
"openclaw/plugin-sdk/channel-streaming": [
|
||||
"../../dist/plugin-sdk/channel-streaming.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/cli-runtime": ["../../dist/plugin-sdk/cli-runtime.d.ts"],
|
||||
"openclaw/plugin-sdk/error-runtime": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/error-runtime.d.ts"
|
||||
"../../dist/plugin-sdk/error-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-catalog-shared": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/provider-catalog-shared.d.ts"
|
||||
"../../dist/plugin-sdk/provider-catalog-shared.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-env-vars": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/provider-env-vars.d.ts"
|
||||
"../../dist/plugin-sdk/provider-env-vars.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-entry": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/provider-entry.d.ts"
|
||||
"../../dist/plugin-sdk/provider-entry.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-web-search-contract": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/provider-web-search-contract.d.ts"
|
||||
"../../dist/plugin-sdk/provider-web-search-contract.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/secret-ref-runtime": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/secret-ref-runtime.d.ts"
|
||||
"../../dist/plugin-sdk/secret-ref-runtime.d.ts"
|
||||
],
|
||||
"openclaw/plugin-sdk/ssrf-runtime": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/ssrf-runtime.d.ts"
|
||||
"../../dist/plugin-sdk/ssrf-runtime.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/src/plugin-sdk/*.d.ts"],
|
||||
"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/*": ["../../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"],
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
"!dist/plugin-sdk/channel-target-testing.d.ts",
|
||||
"!dist/plugin-sdk/channel-test-helpers.js",
|
||||
"!dist/plugin-sdk/channel-test-helpers.d.ts",
|
||||
"!dist/plugin-sdk/codex-native-task-runtime.js",
|
||||
"!dist/plugin-sdk/codex-native-task-runtime.d.ts",
|
||||
"!dist/plugin-sdk/plugin-test-api.js",
|
||||
"!dist/plugin-sdk/plugin-test-api.d.ts",
|
||||
"!dist/plugin-sdk/plugin-test-contracts.js",
|
||||
@@ -53,12 +55,16 @@
|
||||
"!dist/plugin-sdk/provider-test-contracts.d.ts",
|
||||
"!dist/plugin-sdk/reply-payload-testing.js",
|
||||
"!dist/plugin-sdk/reply-payload-testing.d.ts",
|
||||
"!dist/plugin-sdk/ssrf-runtime-internal.js",
|
||||
"!dist/plugin-sdk/ssrf-runtime-internal.d.ts",
|
||||
"!dist/plugin-sdk/test-env.js",
|
||||
"!dist/plugin-sdk/test-env.d.ts",
|
||||
"!dist/plugin-sdk/test-fixtures.js",
|
||||
"!dist/plugin-sdk/test-fixtures.d.ts",
|
||||
"!dist/plugin-sdk/test-node-mocks.js",
|
||||
"!dist/plugin-sdk/test-node-mocks.d.ts",
|
||||
"!dist/plugin-sdk/test-utils.js",
|
||||
"!dist/plugin-sdk/test-utils.d.ts",
|
||||
"!dist/plugin-sdk/testing.js",
|
||||
"!dist/plugin-sdk/testing.d.ts",
|
||||
"!dist/plugin-sdk/src/agents/test-helpers/**",
|
||||
@@ -108,6 +114,7 @@
|
||||
"!dist/plugin-sdk/qa-channel-protocol.*",
|
||||
"!dist/plugin-sdk/qa-lab.*",
|
||||
"!dist/plugin-sdk/qa-runtime.*",
|
||||
"!dist/plugin-sdk/src/**",
|
||||
"!dist/plugin-sdk/src/plugin-sdk/qa-channel.d.ts",
|
||||
"!dist/plugin-sdk/src/plugin-sdk/qa-channel-protocol.d.ts",
|
||||
"!dist/plugin-sdk/src/plugin-sdk/qa-lab.d.ts",
|
||||
|
||||
11
scripts/fixtures/packed-plugin-sdk-type-smoke.ts
Normal file
11
scripts/fixtures/packed-plugin-sdk-type-smoke.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
type PublicPluginSdkModules = [
|
||||
typeof import("openclaw/plugin-sdk"),
|
||||
typeof import("openclaw/plugin-sdk/channel-entry-contract"),
|
||||
typeof import("openclaw/plugin-sdk/config-contracts"),
|
||||
typeof import("openclaw/plugin-sdk/provider-entry"),
|
||||
typeof import("openclaw/plugin-sdk/runtime-env"),
|
||||
];
|
||||
|
||||
const resolvedModules = null as unknown as PublicPluginSdkModules;
|
||||
|
||||
void resolvedModules;
|
||||
@@ -1,5 +1,6 @@
|
||||
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 = [
|
||||
@@ -11,44 +12,50 @@ export const EXTENSION_PACKAGE_BOUNDARY_EXCLUDE = [
|
||||
"./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<string, readonly string[]>;
|
||||
|
||||
export const EXTENSION_PACKAGE_BOUNDARY_BASE_PATHS = {
|
||||
"openclaw/extension-api": ["../src/extensionAPI.ts"],
|
||||
"openclaw/plugin-sdk": ["../dist/plugin-sdk/src/plugin-sdk/index.d.ts"],
|
||||
"openclaw/plugin-sdk/*": ["../dist/plugin-sdk/src/plugin-sdk/*.d.ts"],
|
||||
"openclaw/plugin-sdk/account-id": ["../dist/plugin-sdk/src/plugin-sdk/account-id.d.ts"],
|
||||
"openclaw/plugin-sdk/channel-entry-contract": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-entry-contract.d.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": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-secret-basic-runtime.d.ts",
|
||||
],
|
||||
"openclaw/plugin-sdk/channel-secret-runtime": [
|
||||
"../dist/plugin-sdk/src/plugin-sdk/channel-secret-runtime.d.ts",
|
||||
"../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": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/channel-secret-tts-runtime.d.ts",
|
||||
"../dist/plugin-sdk/channel-secret-tts-runtime.d.ts",
|
||||
],
|
||||
"openclaw/plugin-sdk/error-runtime": ["../dist/plugin-sdk/src/plugin-sdk/error-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": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/provider-catalog-shared.d.ts",
|
||||
"../dist/plugin-sdk/provider-catalog-shared.d.ts",
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-entry": [
|
||||
"../packages/plugin-sdk/dist/src/plugin-sdk/provider-entry.d.ts",
|
||||
],
|
||||
"openclaw/plugin-sdk/secret-ref-runtime": [
|
||||
"../dist/plugin-sdk/src/plugin-sdk/secret-ref-runtime.d.ts",
|
||||
],
|
||||
"openclaw/plugin-sdk/ssrf-runtime": ["../dist/plugin-sdk/src/plugin-sdk/ssrf-runtime.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/*.js": ["../packages/plugin-sdk/dist/extensions/*.d.ts", "../extensions/*"],
|
||||
"@openclaw/*": ["../packages/plugin-sdk/dist/extensions/*", "../extensions/*"],
|
||||
"@openclaw/plugin-sdk/*": ["../dist/plugin-sdk/src/plugin-sdk/*.d.ts"],
|
||||
"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/*": ["../dist/plugin-sdk/*.d.ts"],
|
||||
} as const;
|
||||
|
||||
function prefixExtensionPackageBoundaryPaths(
|
||||
@@ -76,28 +83,24 @@ export const EXTENSION_PACKAGE_BOUNDARY_XAI_PATHS = {
|
||||
"../",
|
||||
),
|
||||
"openclaw/plugin-sdk/channel-entry-contract": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/channel-entry-contract.d.ts",
|
||||
"../../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/src/plugin-sdk/cli-runtime.d.ts"],
|
||||
"openclaw/plugin-sdk/cli-runtime": ["../../dist/plugin-sdk/cli-runtime.d.ts"],
|
||||
"openclaw/plugin-sdk/provider-catalog-shared": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/provider-catalog-shared.d.ts",
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-env-vars": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/provider-env-vars.d.ts",
|
||||
],
|
||||
"openclaw/plugin-sdk/provider-entry": [
|
||||
"../../dist/plugin-sdk/src/plugin-sdk/provider-entry.d.ts",
|
||||
"../../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/src/plugin-sdk/provider-web-search-contract.d.ts",
|
||||
"../../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/src/plugin-sdk/*.d.ts"],
|
||||
"@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"],
|
||||
|
||||
@@ -15,3 +15,4 @@ export function buildPluginSdkPackageExports(): Record<
|
||||
}
|
||||
>;
|
||||
export function listPluginSdkDistArtifacts(): string[];
|
||||
export function listPrivateLocalOnlyPluginSdkDistArtifacts(): string[];
|
||||
|
||||
@@ -57,3 +57,10 @@ export function listPluginSdkDistArtifacts() {
|
||||
`dist/plugin-sdk/${entry}.d.ts`,
|
||||
]);
|
||||
}
|
||||
|
||||
export function listPrivateLocalOnlyPluginSdkDistArtifacts() {
|
||||
return privateLocalOnlyPluginSdkEntrypoints.flatMap((entry) => [
|
||||
`dist/plugin-sdk/${entry}.js`,
|
||||
`dist/plugin-sdk/${entry}.d.ts`,
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ const repoRoot = resolve(import.meta.dirname, "..");
|
||||
const runTsgoScript = path.join(repoRoot, "scripts/run-tsgo.mjs");
|
||||
const TYPE_INPUT_EXTENSIONS = new Set([".ts", ".tsx", ".d.ts", ".js", ".mjs", ".json"]);
|
||||
const VALID_MODES = new Set(["all", "package-boundary"]);
|
||||
const ROOT_SHIMS_NODE_OPTIONS =
|
||||
`${process.env.NODE_OPTIONS ?? ""} --max-old-space-size=4096`.trim();
|
||||
|
||||
const PLUGIN_SDK_TYPE_INPUTS = [
|
||||
"tsconfig.json",
|
||||
@@ -23,10 +25,10 @@ const ROOT_DTS_REQUIRED_OUTPUTS = [
|
||||
"dist/plugin-sdk/packages/memory-host-sdk/src/engine-embeddings.d.ts",
|
||||
"dist/plugin-sdk/packages/memory-host-sdk/src/secret.d.ts",
|
||||
"dist/plugin-sdk/packages/memory-host-sdk/src/status.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/error-runtime.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/plugin-entry.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/provider-auth.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/video-generation.d.ts",
|
||||
"dist/plugin-sdk/error-runtime.d.ts",
|
||||
"dist/plugin-sdk/plugin-entry.d.ts",
|
||||
"dist/plugin-sdk/provider-auth.d.ts",
|
||||
"dist/plugin-sdk/video-generation.d.ts",
|
||||
];
|
||||
const PACKAGE_DTS_INPUTS = ["packages/plugin-sdk/tsconfig.json", ...PLUGIN_SDK_TYPE_INPUTS];
|
||||
const PACKAGE_DTS_STAMP = "packages/plugin-sdk/dist/.boundary-dts.stamp";
|
||||
@@ -67,6 +69,7 @@ const WHATSAPP_DTS_INPUTS = [
|
||||
const WHATSAPP_DTS_STAMP = "dist/plugin-sdk/extensions/whatsapp/.boundary-dts.stamp";
|
||||
const WHATSAPP_DTS_REQUIRED_OUTPUTS = ["dist/plugin-sdk/extensions/whatsapp/api.d.ts"];
|
||||
const ENTRY_SHIMS_INPUTS = [
|
||||
"scripts/lib/plugin-sdk-private-local-only-subpaths.json",
|
||||
"scripts/write-plugin-sdk-entry-dts.ts",
|
||||
"scripts/lib/plugin-sdk-entrypoints.json",
|
||||
"scripts/lib/plugin-sdk-entries.mjs",
|
||||
@@ -505,6 +508,7 @@ async function main(argv = process.argv.slice(2)) {
|
||||
"plugin-sdk boundary root shims",
|
||||
["--import", "tsx", resolve(repoRoot, "scripts/write-plugin-sdk-entry-dts.ts")],
|
||||
120_000,
|
||||
{ env: { NODE_OPTIONS: ROOT_SHIMS_NODE_OPTIONS } },
|
||||
);
|
||||
} else if (mode === "all") {
|
||||
process.stdout.write("[plugin-sdk boundary root shims] fresh; skipping\n");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { execFileSync } from "node:child_process";
|
||||
import {
|
||||
copyFileSync,
|
||||
existsSync,
|
||||
lstatSync,
|
||||
mkdtempSync,
|
||||
@@ -35,7 +36,10 @@ import {
|
||||
} from "./lib/bundled-plugin-build-entries.mjs";
|
||||
import { collectPackUnpackedSizeErrors as collectNpmPackUnpackedSizeErrors } from "./lib/npm-pack-budget.mjs";
|
||||
import { collectBundledPluginPackageDependencySpecs } from "./lib/plugin-package-dependencies.mjs";
|
||||
import { listPluginSdkDistArtifacts } from "./lib/plugin-sdk-entries.mjs";
|
||||
import {
|
||||
listPluginSdkDistArtifacts,
|
||||
listPrivateLocalOnlyPluginSdkDistArtifacts,
|
||||
} from "./lib/plugin-sdk-entries.mjs";
|
||||
import {
|
||||
runInstalledWorkspaceBootstrapSmoke,
|
||||
WORKSPACE_TEMPLATE_PACK_PATHS,
|
||||
@@ -99,10 +103,12 @@ const forbiddenPrefixes = [
|
||||
"dist/plugin-sdk/qa-channel-protocol.",
|
||||
"dist/plugin-sdk/qa-lab.",
|
||||
"dist/plugin-sdk/qa-runtime.",
|
||||
"dist/plugin-sdk/src/",
|
||||
"dist/plugin-sdk/src/plugin-sdk/qa-channel.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/qa-channel-protocol.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/qa-lab.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts",
|
||||
...listPrivateLocalOnlyPluginSdkDistArtifacts(),
|
||||
"dist/qa-runtime-",
|
||||
"dist/plugin-sdk/.tsbuildinfo",
|
||||
"docs/.generated/",
|
||||
@@ -117,6 +123,12 @@ const forbiddenPrivateQaContentMarkers = [
|
||||
"qa-lab/cli.js",
|
||||
"qa-lab/runtime-api.js",
|
||||
] as const;
|
||||
const forbiddenPrivatePluginSdkDeclarationMarkers = [
|
||||
"//#region src/agents/test-helpers/",
|
||||
"//#region src/plugin-sdk/test-helpers/",
|
||||
"//#region src/test-helpers/",
|
||||
"//#region src/test-utils/",
|
||||
] as const;
|
||||
const forbiddenPrivateQaContentScanPrefixes = ["dist/"] as const;
|
||||
const forbiddenPluginSdkRootAliasMinifiedExportPattern = /\bmod\.[A-Za-z_$]\b/u;
|
||||
const appcastPath = resolve("appcast.xml");
|
||||
@@ -149,7 +161,9 @@ export const PACKED_COMPLETION_SMOKE_ARGS = [
|
||||
"--shell",
|
||||
"zsh",
|
||||
] as const;
|
||||
|
||||
const PACKED_PLUGIN_SDK_TYPESCRIPT_SMOKE_FIXTURE = resolve(
|
||||
"scripts/fixtures/packed-plugin-sdk-type-smoke.ts",
|
||||
);
|
||||
export function collectSkillShellScriptExecutableErrors(rootDir = resolve(".")): string[] {
|
||||
if (process.platform === "win32") {
|
||||
return [];
|
||||
@@ -483,6 +497,78 @@ function verifyPackedInstalledPackage(params: {
|
||||
}
|
||||
}
|
||||
|
||||
export function createPackedPluginSdkTypescriptSmokeProject(params: {
|
||||
consumerDir: string;
|
||||
packageSpec: string;
|
||||
}): void {
|
||||
mkdirSync(join(params.consumerDir, "src"), { recursive: true });
|
||||
writeFileSync(
|
||||
join(params.consumerDir, "package.json"),
|
||||
`${JSON.stringify(
|
||||
{
|
||||
name: "openclaw-plugin-sdk-type-smoke",
|
||||
private: true,
|
||||
type: "module",
|
||||
dependencies: {
|
||||
openclaw: params.packageSpec,
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
"utf8",
|
||||
);
|
||||
writeFileSync(
|
||||
join(params.consumerDir, "tsconfig.json"),
|
||||
`${JSON.stringify(
|
||||
{
|
||||
compilerOptions: {
|
||||
module: "NodeNext",
|
||||
moduleResolution: "NodeNext",
|
||||
noEmit: true,
|
||||
strict: true,
|
||||
skipLibCheck: true,
|
||||
target: "ES2022",
|
||||
},
|
||||
include: ["src/index.ts"],
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
"utf8",
|
||||
);
|
||||
copyFileSync(
|
||||
PACKED_PLUGIN_SDK_TYPESCRIPT_SMOKE_FIXTURE,
|
||||
join(params.consumerDir, "src", "index.ts"),
|
||||
);
|
||||
}
|
||||
|
||||
function runPackedPluginSdkTypescriptSmoke(tarballPath: string, tmpRoot: string): void {
|
||||
const consumerDir = join(tmpRoot, "plugin-sdk-type-consumer");
|
||||
createPackedPluginSdkTypescriptSmokeProject({
|
||||
consumerDir,
|
||||
packageSpec: `file:${tarballPath}`,
|
||||
});
|
||||
execNpm(["install", "--ignore-scripts", "--no-audit", "--no-fund"], {
|
||||
cwd: consumerDir,
|
||||
encoding: "utf8",
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
const installedOpenClawRoot = join(consumerDir, "node_modules", "openclaw");
|
||||
const tscPath = [
|
||||
join(consumerDir, "node_modules", "typescript", "bin", "tsc"),
|
||||
join(installedOpenClawRoot, "node_modules", "typescript", "bin", "tsc"),
|
||||
].find((candidate) => existsSync(candidate));
|
||||
if (!tscPath) {
|
||||
throw new Error("release-check: packed plugin SDK TypeScript smoke could not find tsc.");
|
||||
}
|
||||
execFileSync(process.execPath, [tscPath, "-p", "tsconfig.json", "--pretty", "false"], {
|
||||
cwd: consumerDir,
|
||||
stdio: "inherit",
|
||||
});
|
||||
}
|
||||
|
||||
export function writePackedBundledPluginActivationConfig(homeDir: string): void {
|
||||
const configPath = join(homeDir, ".openclaw", "openclaw.json");
|
||||
mkdirSync(join(homeDir, ".openclaw"), { recursive: true });
|
||||
@@ -652,6 +738,7 @@ function runPackedBundledChannelEntrySmoke(): void {
|
||||
runPackedBundledPluginPostinstall(packageRoot);
|
||||
runPackedBundledPluginActivationSmoke(packageRoot, tmpRoot);
|
||||
runPackedTaskRegistryControlRuntimeSmoke(packageRoot);
|
||||
runPackedPluginSdkTypescriptSmoke(tarballPath, tmpRoot);
|
||||
execFileSync(
|
||||
process.execPath,
|
||||
[
|
||||
@@ -759,7 +846,10 @@ export function collectForbiddenPackContentPaths(
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
return forbiddenPrivateQaContentMarkers.some((marker) => content.includes(marker));
|
||||
return (
|
||||
forbiddenPrivateQaContentMarkers.some((marker) => content.includes(marker)) ||
|
||||
forbiddenPrivatePluginSdkDeclarationMarkers.some((marker) => content.includes(marker))
|
||||
);
|
||||
})
|
||||
.toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { pluginSdkEntrypoints } from "./lib/plugin-sdk-entries.mjs";
|
||||
import { build } from "tsdown";
|
||||
import { buildPluginSdkEntrySources, pluginSdkEntrypoints } from "./lib/plugin-sdk-entries.mjs";
|
||||
|
||||
const RUNTIME_SHIMS: Partial<Record<string, string>> = {
|
||||
"webhook-path": [
|
||||
@@ -37,17 +39,63 @@ const RUNTIME_SHIMS: Partial<Record<string, string>> = {
|
||||
].join("\n"),
|
||||
};
|
||||
|
||||
// TypeScript declaration emit writes files under `dist/plugin-sdk/src/plugin-sdk/*` because the
|
||||
// source lives at `src/plugin-sdk/*` and `rootDir` is `.` (repo root, to support
|
||||
// cross-src/extensions refs).
|
||||
//
|
||||
// Our package export map points subpath `types` at `dist/plugin-sdk/<entry>.d.ts`, so we
|
||||
// generate stable entry d.ts files that re-export the real declarations.
|
||||
for (const entry of pluginSdkEntrypoints) {
|
||||
const typeOut = path.join(process.cwd(), `dist/plugin-sdk/${entry}.d.ts`);
|
||||
fs.mkdirSync(path.dirname(typeOut), { recursive: true });
|
||||
fs.writeFileSync(typeOut, `export * from "./src/plugin-sdk/${entry}.js";\n`, "utf8");
|
||||
function isBareImportSpecifier(id: string): boolean {
|
||||
return !id.startsWith(".") && !id.startsWith("/") && !/^[A-Za-z]:[\\/]/u.test(id);
|
||||
}
|
||||
|
||||
function removeExistingFlatDeclarations(outDir: string): void {
|
||||
if (!fs.existsSync(outDir)) {
|
||||
return;
|
||||
}
|
||||
for (const entry of fs.readdirSync(outDir, { withFileTypes: true })) {
|
||||
if (!entry.isFile() || !entry.name.endsWith(".d.ts")) {
|
||||
continue;
|
||||
}
|
||||
fs.rmSync(path.join(outDir, entry.name), { force: true });
|
||||
}
|
||||
}
|
||||
|
||||
function copyFlatDeclarations(fromDir: string, toDir: string): void {
|
||||
fs.mkdirSync(toDir, { recursive: true });
|
||||
for (const entry of fs.readdirSync(fromDir, { withFileTypes: true })) {
|
||||
if (!entry.isFile() || !entry.name.endsWith(".d.ts")) {
|
||||
continue;
|
||||
}
|
||||
fs.copyFileSync(path.join(fromDir, entry.name), path.join(toDir, entry.name));
|
||||
}
|
||||
}
|
||||
|
||||
const distPluginSdkDir = path.join(process.cwd(), "dist/plugin-sdk");
|
||||
const flatDeclarationTempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-plugin-sdk-dts-"));
|
||||
|
||||
try {
|
||||
await build({
|
||||
clean: true,
|
||||
config: false,
|
||||
deps: { neverBundle: (id) => isBareImportSpecifier(id) },
|
||||
dts: true,
|
||||
entry: buildPluginSdkEntrySources(),
|
||||
failOnWarn: false,
|
||||
fixedExtension: false,
|
||||
format: "esm",
|
||||
logLevel: "error",
|
||||
outDir: flatDeclarationTempDir,
|
||||
outExtensions: () => ({ js: ".js", dts: ".d.ts" }),
|
||||
platform: "node",
|
||||
report: false,
|
||||
tsconfig: "tsconfig.plugin-sdk.dts.json",
|
||||
});
|
||||
|
||||
removeExistingFlatDeclarations(distPluginSdkDir);
|
||||
copyFlatDeclarations(flatDeclarationTempDir, distPluginSdkDir);
|
||||
} finally {
|
||||
fs.rmSync(flatDeclarationTempDir, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
// The root npm package ships flat bundled declarations under `dist/plugin-sdk`.
|
||||
// The private workspace package keeps source-shaped declaration paths for local
|
||||
// package-boundary projects, so bridge them back to the packaged flat entries.
|
||||
for (const entry of pluginSdkEntrypoints) {
|
||||
const packageTypeOut = path.join(
|
||||
process.cwd(),
|
||||
`packages/plugin-sdk/dist/src/plugin-sdk/${entry}.d.ts`,
|
||||
|
||||
@@ -85,6 +85,20 @@ describe("package dist inventory", () => {
|
||||
"qa-lab",
|
||||
"cli.d.ts",
|
||||
);
|
||||
const omittedDeepPluginSdkDeclaration = path.join(
|
||||
packageRoot,
|
||||
"dist",
|
||||
"plugin-sdk",
|
||||
"src",
|
||||
"plugin-sdk",
|
||||
"provider-entry.d.ts",
|
||||
);
|
||||
const flatPluginSdkDeclaration = path.join(
|
||||
packageRoot,
|
||||
"dist",
|
||||
"plugin-sdk",
|
||||
"provider-entry.d.ts",
|
||||
);
|
||||
const omittedQaRuntimeChunk = path.join(packageRoot, "dist", "qa-runtime-B9LDtssJ.js");
|
||||
const [omittedBuildStamp, omittedRuntimePostBuildStamp] = LOCAL_BUILD_METADATA_DIST_PATHS.map(
|
||||
(relativePath) => path.join(packageRoot, relativePath),
|
||||
@@ -95,6 +109,7 @@ describe("package dist inventory", () => {
|
||||
await fs.mkdir(path.dirname(omittedQaMatrixChunk), { recursive: true });
|
||||
await fs.mkdir(path.dirname(omittedQaLabTypes), { recursive: true });
|
||||
await fs.mkdir(path.join(packageRoot, "dist", "plugin-sdk"), { recursive: true });
|
||||
await fs.mkdir(path.dirname(omittedDeepPluginSdkDeclaration), { recursive: true });
|
||||
await fs.writeFile(packagedQaChannelRuntime, "export {};\n", "utf8");
|
||||
await fs.writeFile(packagedQaLabRuntime, "export {};\n", "utf8");
|
||||
await fs.writeFile(omittedQaChunk, "export {};\n", "utf8");
|
||||
@@ -104,12 +119,16 @@ describe("package dist inventory", () => {
|
||||
await fs.writeFile(omittedQaChannelPluginSdk, "export {};\n", "utf8");
|
||||
await fs.writeFile(omittedQaChannelProtocolPluginSdk, "export {};\n", "utf8");
|
||||
await fs.writeFile(omittedQaLabTypes, "export {};\n", "utf8");
|
||||
await fs.writeFile(omittedDeepPluginSdkDeclaration, "export {};\n", "utf8");
|
||||
await fs.writeFile(flatPluginSdkDeclaration, "export {};\n", "utf8");
|
||||
await fs.writeFile(omittedQaRuntimeChunk, "export {};\n", "utf8");
|
||||
await fs.writeFile(omittedBuildStamp, "{}\n", "utf8");
|
||||
await fs.writeFile(omittedRuntimePostBuildStamp, "{}\n", "utf8");
|
||||
await fs.writeFile(omittedMap, "{}", "utf8");
|
||||
|
||||
await expect(writePackageDistInventory(packageRoot)).resolves.toStrictEqual([]);
|
||||
await expect(writePackageDistInventory(packageRoot)).resolves.toStrictEqual([
|
||||
"dist/plugin-sdk/provider-entry.d.ts",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@ const OMITTED_PRIVATE_QA_PLUGIN_SDK_FILES = new Set([
|
||||
`dist/plugin-sdk/src/plugin-sdk/${LEGACY_QA_LAB_DIR}.d.ts`,
|
||||
"dist/plugin-sdk/src/plugin-sdk/qa-runtime.d.ts",
|
||||
]);
|
||||
// The build keeps source-shaped SDK declarations for local boundary projects,
|
||||
// but the npm package ships flat declarations and must not inventory the old tree.
|
||||
const OMITTED_DEEP_PLUGIN_SDK_DECLARATION_PREFIX = "dist/plugin-sdk/src/";
|
||||
const OMITTED_PRIVATE_QA_DIST_PREFIXES = ["dist/qa-runtime-"];
|
||||
const OMITTED_PLUGIN_SDK_TEST_FILES = new Set([
|
||||
"dist/plugin-sdk/agent-runtime-test-contracts.d.ts",
|
||||
@@ -72,6 +75,7 @@ const OMITTED_DIST_SUBTREE_PATTERNS = [
|
||||
/^dist\/extensions\/node_modules(?:\/|$)/u,
|
||||
/^dist\/extensions\/[^/]+\/node_modules(?:\/|$)/u,
|
||||
/^dist\/extensions\/qa-matrix(?:\/|$)/u,
|
||||
/^dist\/plugin-sdk\/src(?:\/|$)/u,
|
||||
new RegExp(`^dist/plugin-sdk/extensions/${LEGACY_QA_CHANNEL_DIR}(?:/|$)`, "u"),
|
||||
new RegExp(`^dist/plugin-sdk/extensions/${LEGACY_QA_LAB_DIR}(?:/|$)`, "u"),
|
||||
] as const;
|
||||
@@ -275,10 +279,7 @@ function isPackageFilesExcludedDistPath(
|
||||
);
|
||||
}
|
||||
|
||||
function isPackagedDistPath(
|
||||
relativePath: string,
|
||||
rules: PackageDistInventoryRules,
|
||||
): boolean {
|
||||
function isPackagedDistPath(relativePath: string, rules: PackageDistInventoryRules): boolean {
|
||||
if (!relativePath.startsWith("dist/")) {
|
||||
return false;
|
||||
}
|
||||
@@ -306,6 +307,9 @@ function isPackagedDistPath(
|
||||
if (isOmittedPluginSdkTestPath(relativePath)) {
|
||||
return false;
|
||||
}
|
||||
if (relativePath.startsWith(OMITTED_DEEP_PLUGIN_SDK_DECLARATION_PREFIX)) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
OMITTED_PRIVATE_QA_PLUGIN_SDK_PREFIXES.some((prefix) => relativePath.startsWith(prefix)) ||
|
||||
OMITTED_PRIVATE_QA_PLUGIN_SDK_FILES.has(relativePath) ||
|
||||
@@ -319,10 +323,7 @@ function isPackagedDistPath(
|
||||
return true;
|
||||
}
|
||||
|
||||
function isOmittedDistSubtree(
|
||||
relativePath: string,
|
||||
rules: PackageDistInventoryRules,
|
||||
): boolean {
|
||||
function isOmittedDistSubtree(relativePath: string, rules: PackageDistInventoryRules): boolean {
|
||||
return (
|
||||
isExternalizedBundledExtensionDistPath(relativePath, rules.externalizedExtensionIds) ||
|
||||
isLegacyPluginDependencyDirPath(relativePath) ||
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// Numeric coercion helpers for plugin runtime inputs.
|
||||
|
||||
export { parseFiniteNumber } from "../infra/parse-finite-number.js";
|
||||
export {
|
||||
parseFiniteNumber,
|
||||
parseStrictFiniteNumber,
|
||||
parseStrictPositiveInteger,
|
||||
} from "../infra/parse-finite-number.js";
|
||||
|
||||
@@ -4,7 +4,10 @@ import { dirname, join, win32 } from "node:path";
|
||||
import { bundledDistPluginFile, bundledPluginFile } from "openclaw/plugin-sdk/test-fixtures";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { listBundledPluginPackArtifacts } from "../scripts/lib/bundled-plugin-build-entries.mjs";
|
||||
import { listPluginSdkDistArtifacts } from "../scripts/lib/plugin-sdk-entries.mjs";
|
||||
import {
|
||||
listPluginSdkDistArtifacts,
|
||||
listPrivateLocalOnlyPluginSdkDistArtifacts,
|
||||
} from "../scripts/lib/plugin-sdk-entries.mjs";
|
||||
import {
|
||||
WORKSPACE_TEMPLATE_PACK_PATHS,
|
||||
createWorkspaceBootstrapSmokeEnv,
|
||||
@@ -20,6 +23,7 @@ import {
|
||||
collectSkillShellScriptExecutableErrors,
|
||||
collectPackUnpackedSizeErrors,
|
||||
collectPackedInstalledPackageVerificationErrors,
|
||||
createPackedPluginSdkTypescriptSmokeProject,
|
||||
createPackedCompletionSmokeEnv,
|
||||
createPackedCliSmokeEnv,
|
||||
createPackedBundledPluginPostinstallEnv,
|
||||
@@ -46,6 +50,7 @@ function makePackResult(filename: string, unpackedSize: number) {
|
||||
}
|
||||
|
||||
const requiredPluginSdkPackPaths = [...listPluginSdkDistArtifacts(), "dist/plugin-sdk/compat.js"];
|
||||
const privateLocalOnlyPluginSdkPackPaths = listPrivateLocalOnlyPluginSdkDistArtifacts();
|
||||
const requiredBundledPluginPackPaths = listBundledPluginPackArtifacts();
|
||||
|
||||
describe("collectAppcastSparkleVersionErrors", () => {
|
||||
@@ -442,6 +447,21 @@ describe("collectForbiddenPackPaths", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it("blocks the old deep plugin SDK declaration tree from npm pack output", () => {
|
||||
expect(
|
||||
collectForbiddenPackPaths([
|
||||
"dist/index.js",
|
||||
"dist/plugin-sdk/index.d.ts",
|
||||
"dist/plugin-sdk/types-abc123.d.ts",
|
||||
"dist/plugin-sdk/src/channels/plugins/types.public.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/provider-entry.d.ts",
|
||||
]),
|
||||
).toEqual([
|
||||
"dist/plugin-sdk/src/channels/plugins/types.public.d.ts",
|
||||
"dist/plugin-sdk/src/plugin-sdk/provider-entry.d.ts",
|
||||
]);
|
||||
});
|
||||
|
||||
it("blocks local build metadata from npm pack output", () => {
|
||||
expect(
|
||||
collectForbiddenPackPaths(["dist/index.js", ...LOCAL_BUILD_METADATA_DIST_PATHS]),
|
||||
@@ -453,6 +473,21 @@ describe("collectForbiddenPackPaths", () => {
|
||||
for (const entry of LOCAL_BUILD_METADATA_DIST_PATHS) {
|
||||
expect(pkg.files).toContain(`!${entry}`);
|
||||
}
|
||||
expect(pkg.files).toContain("!dist/plugin-sdk/src/**");
|
||||
});
|
||||
|
||||
it("blocks private local-only plugin SDK artifacts from npm pack output", () => {
|
||||
expect(
|
||||
collectForbiddenPackPaths(["dist/index.js", ...privateLocalOnlyPluginSdkPackPaths]),
|
||||
).toEqual([...privateLocalOnlyPluginSdkPackPaths].toSorted());
|
||||
});
|
||||
|
||||
it("keeps private local-only plugin SDK artifacts excluded by package files", () => {
|
||||
const pkg = JSON.parse(readFileSync("package.json", "utf8")) as { files?: string[] };
|
||||
|
||||
for (const entry of privateLocalOnlyPluginSdkPackPaths) {
|
||||
expect(pkg.files).toContain(`!${entry}`);
|
||||
}
|
||||
});
|
||||
|
||||
it("blocks legacy runtime dependency stamps from npm pack output", () => {
|
||||
@@ -539,6 +574,25 @@ describe("collectForbiddenPackPaths", () => {
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
it("blocks root plugin SDK declarations that still reference private test helpers", () => {
|
||||
const tempRoot = mkdtempSync(join(tmpdir(), "openclaw-release-private-sdk-"));
|
||||
|
||||
try {
|
||||
mkdirSync(join(tempRoot, "dist", "plugin-sdk"), { recursive: true });
|
||||
writeFileSync(
|
||||
join(tempRoot, "dist", "plugin-sdk", "testing.d.ts"),
|
||||
"//#region src/plugin-sdk/test-helpers/session.ts\n",
|
||||
"utf8",
|
||||
);
|
||||
|
||||
expect(collectForbiddenPackContentPaths(["dist/plugin-sdk/testing.d.ts"], tempRoot)).toEqual([
|
||||
"dist/plugin-sdk/testing.d.ts",
|
||||
]);
|
||||
} finally {
|
||||
rmSync(tempRoot, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("collectMissingPackPaths", () => {
|
||||
@@ -699,6 +753,46 @@ describe("resolveMissingPackBuildHint", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("createPackedPluginSdkTypescriptSmokeProject", () => {
|
||||
it("writes a consumer project that imports representative public SDK subpaths", () => {
|
||||
const root = mkdtempSync(join(tmpdir(), "release-check-plugin-sdk-types-"));
|
||||
try {
|
||||
const consumerDir = join(root, "consumer");
|
||||
const packageRoot = join(root, "openclaw");
|
||||
createPackedPluginSdkTypescriptSmokeProject({
|
||||
consumerDir,
|
||||
packageSpec: `file:${packageRoot}`,
|
||||
});
|
||||
|
||||
const packageJson = JSON.parse(readFileSync(join(consumerDir, "package.json"), "utf8")) as {
|
||||
dependencies?: Record<string, string>;
|
||||
};
|
||||
const tsconfig = JSON.parse(readFileSync(join(consumerDir, "tsconfig.json"), "utf8")) as {
|
||||
compilerOptions?: Record<string, unknown>;
|
||||
};
|
||||
const source = readFileSync(join(consumerDir, "src", "index.ts"), "utf8");
|
||||
const fixtureSource = readFileSync(
|
||||
"scripts/fixtures/packed-plugin-sdk-type-smoke.ts",
|
||||
"utf8",
|
||||
);
|
||||
|
||||
expect(packageJson.dependencies?.openclaw).toBe(`file:${packageRoot}`);
|
||||
expect(tsconfig.compilerOptions?.skipLibCheck).toBe(true);
|
||||
expect(source).toBe(fixtureSource);
|
||||
expect(source).toContain('"openclaw/plugin-sdk"');
|
||||
expect(source).toContain('"openclaw/plugin-sdk/provider-entry"');
|
||||
expect(source).toContain('"openclaw/plugin-sdk/channel-entry-contract"');
|
||||
expect(source).toContain('"openclaw/plugin-sdk/config-contracts"');
|
||||
expect(source).toContain('"openclaw/plugin-sdk/runtime-env"');
|
||||
expect(source).toContain("type PublicPluginSdkModules = [");
|
||||
expect(source).not.toContain("TelegramAccountConfig");
|
||||
expect(source).not.toContain("openclaw/plugin-sdk/channel-contract-testing");
|
||||
} finally {
|
||||
rmSync(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("collectPackUnpackedSizeErrors", () => {
|
||||
it("accepts pack results within the unpacked size budget", () => {
|
||||
expect(
|
||||
|
||||
@@ -6,6 +6,8 @@ import { describe, expect, it } from "vitest";
|
||||
import { LOCAL_BUILD_METADATA_DIST_PATHS } from "../../scripts/lib/local-build-metadata-paths.mjs";
|
||||
|
||||
const CHECK_SCRIPT = "scripts/check-openclaw-package-tarball.mjs";
|
||||
const FLAT_PLUGIN_SDK_DECLARATION = "dist/plugin-sdk/provider-entry.d.ts";
|
||||
const DEEP_PLUGIN_SDK_DECLARATION = "dist/plugin-sdk/src/plugin-sdk/provider-entry.d.ts";
|
||||
|
||||
function withTarball(
|
||||
inventory: string[],
|
||||
@@ -110,6 +112,34 @@ describe("check-openclaw-package-tarball", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects stale deep plugin SDK declaration inventory entries", () => {
|
||||
withTarball(
|
||||
[FLAT_PLUGIN_SDK_DECLARATION, DEEP_PLUGIN_SDK_DECLARATION],
|
||||
{ [FLAT_PLUGIN_SDK_DECLARATION]: "export {};\n" },
|
||||
(tarball) => {
|
||||
const result = spawnSync("node", [CHECK_SCRIPT, tarball], { encoding: "utf8" });
|
||||
|
||||
expect(result.status).not.toBe(0);
|
||||
expect(result.stderr).toContain(
|
||||
`inventory references missing tar entry ${DEEP_PLUGIN_SDK_DECLARATION}`,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("accepts flat plugin SDK declaration inventory without the old deep tree", () => {
|
||||
withTarball(
|
||||
[FLAT_PLUGIN_SDK_DECLARATION],
|
||||
{ [FLAT_PLUGIN_SDK_DECLARATION]: "export {};\n" },
|
||||
(tarball) => {
|
||||
const result = spawnSync("node", [CHECK_SCRIPT, tarball], { encoding: "utf8" });
|
||||
|
||||
expect(result.status, result.stderr).toBe(0);
|
||||
expect(result.stdout).toContain("OpenClaw package tarball integrity passed.");
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects dist files that import missing relative chunks", () => {
|
||||
withTarball(
|
||||
["dist/cli/run-main.js"],
|
||||
|
||||
Reference in New Issue
Block a user