mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-23 02:01:12 +00:00
* refactor(plugin-sdk): narrow wildcard barrels to explicit used exports * refactor(tools): delete dead tool-planning module exposed by barrel narrowing * fix(plugin-sdk): restore deprecation tag on OpenClawSchemaType alias * test(agents): drop test for deleted runtime proxy module * refactor(tools): trim descriptor types to cache consumers * refactor(deadcode): harvest exports orphaned by barrel narrowing * refactor(deadcode): harvest exports orphaned by barrel narrowing (rest) * fix(agents): restore sdk imports and test markers via public predicate * fix(plugin-sdk): named type re-exports in plugin-entry; trim types barrel precisely * chore(plugin-sdk): account unmasked deprecated provider types in budgets * fix(plugins): name star-only type rows for dts bundling * fix(plugins): restore host-hook surface; unexport internal api compositions * fix(plugins): named type imports for api composition; restore needed source exports * fix(plugins): knip-visible type imports for registry surfaces * test: adapt tests to privatized media and command internals * fix(qa-lab): re-export snapshot conversation type * style: format sessions sdk imports * fix(plugins): restore smoke entry export; pin budgets to exact actuals * fix(plugins): canonical smoke-entry import; drop orphaned root shims * fix(plugins): allowlist manifest probe, repoint qa web import, drop dead browser barrels * fix(plugin-sdk): pin codex auth marker and scaffold provider type * fix(qa-lab): keep web-facing model-selection shim within boundary rules * fix(plugin-sdk): preserve merged contracts through narrowed barrels * chore(plugin-sdk): pin post-rebase surface budgets
300 lines
8.9 KiB
TypeScript
300 lines
8.9 KiB
TypeScript
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
import type { Duplex } from "node:stream";
|
|
import type { Command } from "commander";
|
|
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
|
import type {
|
|
DiagnosticEventPrivateData,
|
|
DiagnosticEventInput,
|
|
DiagnosticEventMetadata,
|
|
DiagnosticEventPayload,
|
|
} from "../infra/diagnostic-events.js";
|
|
import type { SecurityAuditFinding } from "../security/audit.types.js";
|
|
import type { PluginLogger } from "./logger-types.js";
|
|
|
|
type ChannelPlugin = import("../channels/plugins/types.plugin.js").ChannelPlugin;
|
|
|
|
type PluginInteractiveHandlerResult = {
|
|
handled?: boolean;
|
|
} | void;
|
|
|
|
export type PluginInteractiveRegistration<
|
|
TContext = unknown,
|
|
TChannel extends string = string,
|
|
TResult = PluginInteractiveHandlerResult,
|
|
> = {
|
|
channel: TChannel;
|
|
namespace: string;
|
|
handler: (ctx: TContext) => Promise<TResult> | TResult;
|
|
};
|
|
|
|
export type PluginInteractiveHandlerRegistration = PluginInteractiveRegistration;
|
|
|
|
export type OpenClawPluginHttpRouteAuth = "gateway" | "plugin";
|
|
export type OpenClawPluginHttpRouteMatch = "exact" | "prefix";
|
|
export type OpenClawPluginGatewayRuntimeScopeSurface = "write-default" | "trusted-operator";
|
|
|
|
export type OpenClawPluginHttpRouteHandler = (
|
|
req: IncomingMessage,
|
|
res: ServerResponse,
|
|
) => Promise<boolean | void> | boolean | void;
|
|
|
|
export type OpenClawPluginHttpRouteUpgradeHandler = (
|
|
req: IncomingMessage,
|
|
socket: Duplex,
|
|
head: Buffer,
|
|
) => Promise<boolean | void> | boolean | void;
|
|
|
|
export type OpenClawPluginHttpRouteParams = {
|
|
path: string;
|
|
handler: OpenClawPluginHttpRouteHandler;
|
|
handleUpgrade?: OpenClawPluginHttpRouteUpgradeHandler;
|
|
auth: OpenClawPluginHttpRouteAuth;
|
|
match?: OpenClawPluginHttpRouteMatch;
|
|
gatewayRuntimeScopeSurface?: OpenClawPluginGatewayRuntimeScopeSurface;
|
|
nodeCapability?: {
|
|
surface: string;
|
|
ttlMs?: number;
|
|
};
|
|
replaceExisting?: boolean;
|
|
};
|
|
|
|
export type OpenClawPluginHostedMediaResolver = (
|
|
mediaUrl: string,
|
|
) => string | null | undefined | Promise<string | null | undefined>;
|
|
|
|
export type OpenClawPluginCliContext = {
|
|
/**
|
|
* Command object where this plugin should register its commands.
|
|
*
|
|
* For root CLI registrations this is the root `openclaw` program. For nested
|
|
* registrations it is the resolved parent command from `parentPath`.
|
|
*/
|
|
program: Command;
|
|
parentPath: readonly string[];
|
|
config: OpenClawConfig;
|
|
workspaceDir?: string;
|
|
logger: PluginLogger;
|
|
};
|
|
|
|
export type OpenClawPluginCliRegistrar = (ctx: OpenClawPluginCliContext) => void | Promise<void>;
|
|
|
|
/**
|
|
* Top-level CLI metadata for plugin-owned commands.
|
|
*
|
|
* Descriptors are the parse-time contract for lazy plugin CLI registration.
|
|
* If you want OpenClaw to keep a plugin command lazy-loaded while still
|
|
* advertising it at the root CLI level, provide descriptors that cover every
|
|
* top-level command root registered by that plugin CLI surface.
|
|
*/
|
|
export type OpenClawPluginCliCommandDescriptor = {
|
|
name: string;
|
|
description: string;
|
|
hasSubcommands: boolean;
|
|
};
|
|
|
|
export type OpenClawPluginNodeCliFeatureOptions = {
|
|
/** Explicit node feature command names owned under `openclaw nodes`. */
|
|
commands?: string[];
|
|
/**
|
|
* Parse-time command descriptors for lazy node feature CLI registration.
|
|
*
|
|
* Descriptors are registered under `openclaw nodes`, so a descriptor named
|
|
* `"camera"` exposes `openclaw nodes camera`.
|
|
*/
|
|
descriptors?: OpenClawPluginCliCommandDescriptor[];
|
|
};
|
|
|
|
export type OpenClawPluginReloadRegistration = {
|
|
restartPrefixes?: string[];
|
|
hotPrefixes?: string[];
|
|
noopPrefixes?: string[];
|
|
};
|
|
|
|
export type {
|
|
OpenClawPluginNodeHostCommand,
|
|
OpenClawPluginNodeHostCommandAvailabilityContext,
|
|
OpenClawPluginNodeHostCommandIo,
|
|
} from "./types.node-host.js";
|
|
|
|
export type OpenClawPluginNodeInvokeTransportResult =
|
|
| {
|
|
ok: true;
|
|
payload?: unknown;
|
|
payloadJSON?: string | null;
|
|
}
|
|
| {
|
|
ok: false;
|
|
code?: string;
|
|
message: string;
|
|
details?: Record<string, unknown>;
|
|
};
|
|
|
|
type OpenClawPluginNodeInvokeApprovalDecision = "allow-once" | "allow-always" | "deny";
|
|
|
|
type OpenClawPluginNodeInvokePolicyApprovalRuntime = {
|
|
request: (input: {
|
|
title: string;
|
|
description: string;
|
|
severity?: "info" | "warning" | "critical";
|
|
toolName?: string;
|
|
toolCallId?: string;
|
|
agentId?: string;
|
|
sessionKey?: string;
|
|
timeoutMs?: number;
|
|
}) => Promise<{
|
|
id?: string;
|
|
decision?: OpenClawPluginNodeInvokeApprovalDecision | null;
|
|
}>;
|
|
};
|
|
|
|
export type OpenClawPluginNodeInvokePolicyContext = {
|
|
nodeId: string;
|
|
command: string;
|
|
params: unknown;
|
|
timeoutMs?: number;
|
|
idempotencyKey?: string;
|
|
config: OpenClawConfig;
|
|
pluginConfig?: Record<string, unknown>;
|
|
node?: {
|
|
nodeId: string;
|
|
displayName?: string;
|
|
platform?: string;
|
|
deviceFamily?: string;
|
|
commands?: string[];
|
|
};
|
|
client?: {
|
|
connId?: string;
|
|
scopes?: string[];
|
|
} | null;
|
|
approvals?: OpenClawPluginNodeInvokePolicyApprovalRuntime;
|
|
invokeNode: (input?: {
|
|
params?: unknown;
|
|
timeoutMs?: number;
|
|
idempotencyKey?: string;
|
|
}) => Promise<OpenClawPluginNodeInvokeTransportResult>;
|
|
};
|
|
|
|
export type OpenClawPluginNodeInvokePolicyResult =
|
|
| {
|
|
ok: true;
|
|
payload?: unknown;
|
|
payloadJSON?: string | null;
|
|
}
|
|
| {
|
|
ok: false;
|
|
message: string;
|
|
code?: string;
|
|
details?: Record<string, unknown>;
|
|
unavailable?: boolean;
|
|
};
|
|
|
|
export type OpenClawPluginNodeInvokePolicy = {
|
|
commands: string[];
|
|
/**
|
|
* Platforms where these node-handled commands should be allowlisted by default.
|
|
* Omit for commands that require explicit `gateway.nodes.allowCommands`.
|
|
*/
|
|
defaultPlatforms?: Array<"ios" | "android" | "macos" | "windows" | "linux" | "unknown">;
|
|
/**
|
|
* Dangerous policy commands are filtered out of default allowlists unless
|
|
* explicitly allowed by config.
|
|
*/
|
|
dangerous?: boolean;
|
|
/**
|
|
* iOS foreground-restricted commands should be queued for foreground delivery
|
|
* when an iOS node reports BACKGROUND_UNAVAILABLE.
|
|
*/
|
|
foregroundRestrictedOnIos?: boolean;
|
|
handle: (
|
|
ctx: OpenClawPluginNodeInvokePolicyContext,
|
|
) => Promise<OpenClawPluginNodeInvokePolicyResult> | OpenClawPluginNodeInvokePolicyResult;
|
|
};
|
|
|
|
export type OpenClawPluginSecurityAuditContext = {
|
|
config: OpenClawConfig;
|
|
sourceConfig: OpenClawConfig;
|
|
env: NodeJS.ProcessEnv;
|
|
stateDir: string;
|
|
configPath: string;
|
|
};
|
|
|
|
export type OpenClawPluginSecurityAuditCollector = (
|
|
ctx: OpenClawPluginSecurityAuditContext,
|
|
) => SecurityAuditFinding[] | Promise<SecurityAuditFinding[]>;
|
|
|
|
export type OpenClawGatewayDiscoveryAdvertiseContext = {
|
|
machineDisplayName: string;
|
|
gatewayPort: number;
|
|
gatewayTlsEnabled: boolean;
|
|
gatewayTlsFingerprintSha256?: string;
|
|
gatewayDirectReachable: boolean;
|
|
canvasPort?: number;
|
|
tailnetDns?: string;
|
|
sshPort?: number;
|
|
cliPath?: string;
|
|
minimal: boolean;
|
|
};
|
|
|
|
export type OpenClawGatewayDiscoveryService = {
|
|
id: string;
|
|
advertise: (
|
|
ctx: OpenClawGatewayDiscoveryAdvertiseContext,
|
|
) => void | Promise<void | { stop?: () => void | Promise<void> }>;
|
|
};
|
|
|
|
/** Context passed to long-lived plugin services. */
|
|
export type OpenClawPluginServiceContext = {
|
|
config: OpenClawConfig;
|
|
workspaceDir?: string;
|
|
stateDir: string;
|
|
logger: PluginLogger;
|
|
gatewayEvents?: import("./gateway-events.js").OpenClawPluginGatewayEvents;
|
|
startupTrace?: {
|
|
detail?: (name: string, metrics: ReadonlyArray<readonly [string, number | string]>) => void;
|
|
measure: <T>(name: string, run: () => T | Promise<T>) => Promise<T>;
|
|
};
|
|
internalDiagnostics?: {
|
|
emit: (event: DiagnosticEventInput, privateData?: DiagnosticEventPrivateData) => void;
|
|
onEvent: (
|
|
listener: (
|
|
event: DiagnosticEventPayload,
|
|
metadata: DiagnosticEventMetadata,
|
|
privateData: DiagnosticEventPrivateData,
|
|
) => void,
|
|
) => () => void;
|
|
};
|
|
};
|
|
|
|
/** Background service registered by a plugin during `register(api)`. */
|
|
export type OpenClawPluginService = {
|
|
id: string;
|
|
start: (ctx: OpenClawPluginServiceContext) => void | Promise<void>;
|
|
stop?: (ctx: OpenClawPluginServiceContext) => void | Promise<void>;
|
|
};
|
|
|
|
export type OpenClawPluginChannelRegistration = {
|
|
plugin: ChannelPlugin;
|
|
};
|
|
|
|
/**
|
|
* Public label exposed to plugin `register(api)` calls.
|
|
*
|
|
* Keep this as a compatibility signal for plugin authors. Loader internals
|
|
* should derive explicit capability booleans from the mode instead of branching
|
|
* on raw strings throughout the code path.
|
|
*
|
|
* - `full`: live runtime activation; long-lived side effects may start.
|
|
* - `discovery`: read-only capability discovery; skip sockets/workers/clients.
|
|
* - `tool-discovery`: capability discovery for executable tools; skip channel runtime hydration.
|
|
* - `setup-only`: lightweight channel setup entry only.
|
|
* - `setup-runtime`: setup flow that also needs the runtime channel entry.
|
|
* - `cli-metadata`: CLI command metadata collection.
|
|
*/
|
|
export type PluginRegistrationMode =
|
|
| "full"
|
|
| "discovery"
|
|
| "tool-discovery"
|
|
| "setup-only"
|
|
| "setup-runtime"
|
|
| "cli-metadata";
|