diff --git a/packages/gateway-protocol/src/index.ts b/packages/gateway-protocol/src/index.ts index 998fdedce958..52b744c767c8 100644 --- a/packages/gateway-protocol/src/index.ts +++ b/packages/gateway-protocol/src/index.ts @@ -462,11 +462,17 @@ import { WizardStepSchema, } from "./schema.js"; +/** Normalized validation error shape exposed by every protocol validator. */ export type ValidationError = { + /** Failed schema keyword, when the validator can report one. */ keyword?: string; + /** JSON-pointer path to the failing data location. */ instancePath?: string; + /** JSON-pointer path to the failing schema location. */ schemaPath?: string; + /** Validator-specific keyword parameters for richer diagnostics. */ params?: Record; + /** Human-readable validation message. */ message?: string; }; diff --git a/src/plugin-sdk/api-baseline.ts b/src/plugin-sdk/api-baseline.ts index 7c5c83e994d7..0f0153139e6f 100644 --- a/src/plugin-sdk/api-baseline.ts +++ b/src/plugin-sdk/api-baseline.ts @@ -12,6 +12,7 @@ import { } from "../../scripts/lib/plugin-sdk-doc-metadata.ts"; import { publicPluginSdkEntrypoints } from "../../scripts/lib/plugin-sdk-entries.mjs"; +/** Declaration kind recorded for each public SDK export in the API baseline. */ export type PluginSdkApiExportKind = | "class" | "const" @@ -23,42 +24,69 @@ export type PluginSdkApiExportKind = | "unknown" | "variable"; +/** Repo source location for a public SDK declaration or module. */ export type PluginSdkApiSourceLink = { + /** One-based source line for docs and review links. */ line: number; + /** Repo-relative source file path. */ path: string; }; +/** One named export captured from a public SDK entrypoint. */ export type PluginSdkApiExport = { + /** Normalized TypeScript declaration text, or null when TypeScript cannot print it. */ declaration: string | null; + /** Exported symbol name as plugin authors import it. */ exportName: string; + /** Coarse declaration kind used by docs and drift reports. */ kind: PluginSdkApiExportKind; + /** Source location for the exported declaration when available. */ source: PluginSdkApiSourceLink | null; }; +/** API baseline record for one public SDK module/subpath. */ export type PluginSdkApiModule = { + /** Documentation category used to group SDK entrypoints. */ category: PluginSdkDocCategory; + /** Entry point metadata from the SDK docs registry. */ entrypoint: PluginSdkDocEntrypoint; + /** Public exports discovered from the TypeScript program. */ exports: PluginSdkApiExport[]; + /** Package specifier shown to plugin authors. */ importSpecifier: string; + /** Repo source for the SDK entrypoint file. */ source: PluginSdkApiSourceLink; }; +/** Full generated SDK API baseline payload. */ export type PluginSdkApiBaseline = { + /** Generator identifier used to reject hand-authored baseline files. */ generatedBy: "scripts/generate-plugin-sdk-api-baseline.ts"; + /** Public SDK modules included in the baseline. */ modules: PluginSdkApiModule[]; }; +/** Rendered baseline variants written to JSON and statefile outputs. */ export type PluginSdkApiBaselineRender = { + /** Structured baseline data before serialization. */ baseline: PluginSdkApiBaseline; + /** Pretty JSON artifact for humans and docs tooling. */ json: string; + /** Line-delimited export records used by lightweight contract checks. */ jsonl: string; }; +/** Result returned when writing SDK API baseline artifacts. */ export type PluginSdkApiBaselineWriteResult = { + /** True when any generated artifact content differs from disk. */ changed: boolean; + /** True when changed artifacts were actually written. */ wrote: boolean; + /** JSON baseline artifact path. */ jsonPath: string; + /** JSONL statefile artifact path. */ statefilePath: string; + /** SHA-256 hash artifact path. */ hashPath: string; }; @@ -77,6 +105,7 @@ function resolveRepoRoot(): string { return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); } +/** Normalize compiler source paths into stable repo-relative or node_modules-relative paths. */ export function normalizePluginSdkApiSourcePath(repoRoot: string, filePath: string): string { const resolvedPath = path.resolve(filePath); const relative = path.relative(repoRoot, resolvedPath); @@ -119,6 +148,7 @@ function normalizeDeclarationImportSpecifier(repoRoot: string, value: string): s return relative.split(path.sep).join(path.posix.sep); } +/** Strip machine-local absolute paths from declaration text before hashing baseline output. */ export function normalizePluginSdkApiDeclarationText(repoRoot: string, value: string): string { return value.replaceAll( /import\("([^"]+)"((?:\s*,[^)]*)?)\)/g, @@ -475,6 +505,7 @@ function buildJsonlLines(baseline: PluginSdkApiBaseline): string[] { return lines; } +/** Render the current public SDK API baseline without writing generated artifacts. */ export async function renderPluginSdkApiBaseline(params?: { repoRoot?: string; }): Promise { @@ -543,6 +574,7 @@ function validateMetadata(): void { } } +/** Write or check SDK API baseline artifacts used by docs and contract tests. */ export async function writePluginSdkApiBaselineStatefile(params?: { repoRoot?: string; check?: boolean; diff --git a/src/plugin-sdk/entrypoints.ts b/src/plugin-sdk/entrypoints.ts index 878ce294ba30..4e66368cb08b 100644 --- a/src/plugin-sdk/entrypoints.ts +++ b/src/plugin-sdk/entrypoints.ts @@ -4,8 +4,10 @@ import deprecatedPublicPluginSdkSubpathList from "../../scripts/lib/plugin-sdk-d import pluginSdkEntryList from "../../scripts/lib/plugin-sdk-entrypoints.json" with { type: "json" }; import privateLocalOnlyPluginSdkSubpathList from "../../scripts/lib/plugin-sdk-private-local-only-subpaths.json" with { type: "json" }; +/** All declared SDK entrypoints, including public, deprecated, and local-only subpaths. */ export const pluginSdkEntrypoints = [...pluginSdkEntryList]; +/** SDK subpaths without the root `openclaw/plugin-sdk` barrel entry. */ export const pluginSdkSubpaths = pluginSdkEntrypoints.filter((entry) => entry !== "index"); const privateLocalOnlyPluginSdkSubpathSet = new Set( @@ -14,32 +16,41 @@ const privateLocalOnlyPluginSdkSubpathSet = new Set( ), ); +/** Entrypoints reserved for local repo/runtime checks and excluded from package exports. */ export const privateLocalOnlyPluginSdkEntrypoints = pluginSdkSubpaths.filter((entry) => privateLocalOnlyPluginSdkSubpathSet.has(entry), ); +/** Entrypoints exported by the published package for third-party plugin imports. */ export const publicPluginSdkEntrypoints = pluginSdkEntrypoints.filter( (entry) => entry === "index" || !privateLocalOnlyPluginSdkSubpathSet.has(entry), ); +/** Published SDK subpaths, excluding the root barrel. */ export const publicPluginSdkSubpaths = publicPluginSdkEntrypoints.filter( (entry) => entry !== "index", ); +/** Public SDK subpaths that remain importable but are marked deprecated in docs/contracts. */ export const deprecatedPublicPluginSdkEntrypoints = publicPluginSdkSubpaths.filter((entry) => deprecatedPublicPluginSdkSubpathList.includes(entry), ); +/** Deprecated subpaths still re-exported by the root SDK barrel for compatibility. */ export const deprecatedBarrelPluginSdkEntrypoints = pluginSdkSubpaths.filter((entry) => deprecatedBarrelPluginSdkSubpathList.includes(entry), ); -// Transitional compatibility/helper surfaces owned by their matching bundled plugin. -// Cross-owner extension imports are blocked by the package contract guardrails. +/** + * Transitional compatibility/helper surfaces owned by their matching bundled plugin. + * + * Cross-owner extension imports are blocked by package contract guardrails. + */ export const reservedBundledPluginSdkEntrypoints = ["codex-mcp-projection"] as const; -// Supported SDK facades backed by bundled plugins. These are intentionally public -// until they move to generic, plugin-neutral contracts. +/** + * Supported SDK facades backed by bundled plugins until generic contracts replace them. + */ export const supportedBundledFacadeSdkEntrypoints = [ "discord", "lmstudio", @@ -54,7 +65,7 @@ export const supportedBundledFacadeSdkEntrypoints = [ "zalouser", ] as const; -// Plugin-owned surfaces that are intentionally public and documented for third-party plugins. +/** Plugin-owned surfaces intentionally public and documented for third-party plugins. */ export const publicPluginOwnedSdkEntrypoints = [ "browser-config", "image-generation-core", diff --git a/src/plugin-sdk/tool-plugin.ts b/src/plugin-sdk/tool-plugin.ts index d0d20fc8d5ae..682c9b140fe3 100644 --- a/src/plugin-sdk/tool-plugin.ts +++ b/src/plugin-sdk/tool-plugin.ts @@ -14,8 +14,10 @@ import { const EMPTY_TOOL_PLUGIN_CONFIG_SCHEMA = Type.Object({}, { additionalProperties: false }); +/** Non-enumerable metadata symbol attached to entries created by `defineToolPlugin`. */ export const toolPluginMetadataSymbol = Symbol.for("openclaw.plugin-sdk.tool-plugin.metadata"); +/** Runtime context supplied to a concrete tool plugin execution handler. */ export type ToolPluginExecutionContext = { /** Plugin runtime API for tool implementations that need OpenClaw services. */ api: OpenClawPluginApi; @@ -35,6 +37,7 @@ type ToolPluginToolFactory = ( definition: ToolPluginToolDefinition, ) => DefinedToolPluginTool; +/** Context passed to a tool factory that builds runtime-specific tool definitions. */ export type ToolPluginFactoryContext = { /** Plugin runtime API passed to context-sensitive tool factories. */ api: OpenClawPluginApi; @@ -57,6 +60,7 @@ type ToolPluginToolDefinitionBase = { optional?: boolean; }; +/** Static tool declaration accepted by the tool-plugin factory callback. */ export type ToolPluginToolDefinition< TConfig, TParamsSchema extends TSchema, @@ -92,6 +96,7 @@ type DefinedToolPluginTool = { ) => AnyAgentTool | AnyAgentTool[] | null | undefined; }; +/** Model-facing metadata extracted from each statically declared tool. */ export type ToolPluginStaticToolMetadata = { name: string; label: string; @@ -100,6 +105,7 @@ export type ToolPluginStaticToolMetadata = { optional?: boolean; }; +/** Metadata attached to a defined tool plugin for manifest/catalog generation. */ export type ToolPluginMetadata = { id: string; name: string; @@ -109,6 +115,7 @@ export type ToolPluginMetadata = { tools: ToolPluginStaticToolMetadata[]; }; +/** Options for declaring a plugin whose primary surface is one or more tools. */ export type DefineToolPluginOptions = { /** Stable plugin id used in config, manifests, and generated metadata. */ id: string; @@ -126,6 +133,7 @@ export type DefineToolPluginOptions readonly DefinedToolPluginTool[]; }; +/** Plugin entry returned by `defineToolPlugin`, including hidden metadata. */ export type DefinedToolPluginEntry = ReturnType & { [toolPluginMetadataSymbol]: ToolPluginMetadata; }; @@ -149,6 +157,7 @@ function createToolPluginToolFactory(): ToolPluginToolFactory })) as ToolPluginToolFactory; } +/** Define a tool-focused plugin entry and register its tools at plugin startup. */ export function defineToolPlugin( definition: DefineToolPluginOptions, ): DefinedToolPluginEntry { @@ -232,6 +241,7 @@ export function defineToolPlugin