refactor(plugin-sdk): split runtime helper seams

This commit is contained in:
Peter Steinberger
2026-04-04 08:53:12 +01:00
parent 470898b5e1
commit edfaa01d1d
57 changed files with 605 additions and 333 deletions

View File

@@ -36,6 +36,8 @@ function isApprovalTargetsMode(cfg: OpenClawConfig): boolean {
return execApprovals.mode === "targets" || execApprovals.mode === "both";
}
export { getExecApprovalReplyMetadata, matchesApprovalRequestFilters };
export function isChannelExecApprovalClientEnabledFromConfig(params: {
enabled?: ChannelExecApprovalEnableMode;
approverCount: number;

View File

@@ -0,0 +1,7 @@
export {
createChannelExecApprovalProfile,
getExecApprovalReplyMetadata,
isChannelExecApprovalClientEnabledFromConfig,
isChannelExecApprovalTargetRecipient,
matchesApprovalRequestFilters,
} from "./approval-client-helpers.js";

View File

@@ -0,0 +1,6 @@
export {
createApproverRestrictedNativeApprovalAdapter,
createApproverRestrictedNativeApprovalCapability,
createChannelApprovalCapability,
splitChannelApprovalCapability,
} from "./approval-delivery-helpers.js";

View File

@@ -0,0 +1,15 @@
export {
createChannelApproverDmTargetResolver,
createChannelNativeOriginTargetResolver,
} from "./approval-native-helpers.js";
export {
resolveApprovalRequestOriginTarget,
resolveApprovalRequestSessionTarget,
resolveExecApprovalSessionTarget,
type ExecApprovalSessionTarget,
} from "../infra/exec-approval-session-target.js";
export {
doesApprovalRequestMatchChannelAccount,
resolveApprovalRequestAccountId,
resolveApprovalRequestChannelAccountId,
} from "../infra/approval-request-account-binding.js";

View File

@@ -0,0 +1,15 @@
export {
buildExecApprovalPendingReplyPayload,
getExecApprovalApproverDmNoticeText,
getExecApprovalReplyMetadata,
type ExecApprovalPendingReplyParams,
type ExecApprovalReplyDecision,
type ExecApprovalReplyMetadata,
} from "../infra/exec-approval-reply.js";
export { resolveExecApprovalCommandDisplay } from "../infra/exec-approval-command-display.js";
export {
resolveExecApprovalAllowedDecisions,
resolveExecApprovalRequestAllowedDecisions,
type ExecApprovalDecision,
} from "../infra/exec-approvals.js";
export { buildPluginApprovalPendingReplyPayload } from "./approval-renderers.js";

View File

@@ -24,14 +24,16 @@ export {
createChannelNativeOriginTargetResolver,
} from "./approval-native-helpers.js";
export {
doesApprovalRequestMatchChannelAccount,
resolveApprovalRequestOriginTarget,
resolveApprovalRequestAccountId,
resolveApprovalRequestChannelAccountId,
resolveApprovalRequestSessionTarget,
resolveExecApprovalSessionTarget,
type ExecApprovalSessionTarget,
} from "../infra/exec-approval-session-target.js";
export {
doesApprovalRequestMatchChannelAccount,
resolveApprovalRequestAccountId,
resolveApprovalRequestChannelAccountId,
} from "../infra/approval-request-account-binding.js";
export {
buildPluginApprovalExpiredMessage,
buildPluginApprovalRequestMessage,

View File

@@ -443,21 +443,15 @@ export function defineChannelPluginEntry<TPlugin>({
registerCliMetadata,
registerFull,
}: DefineChannelPluginEntryOptions<TPlugin>): DefinedChannelPluginEntry<TPlugin> {
let resolvedConfigSchema: ChannelEntryConfigSchema<TPlugin> | undefined;
const getConfigSchema = (): ChannelEntryConfigSchema<TPlugin> => {
resolvedConfigSchema ??=
typeof configSchema === "function"
? configSchema()
: ((configSchema ?? emptyChannelConfigSchema()) as ChannelEntryConfigSchema<TPlugin>);
return resolvedConfigSchema;
};
const resolvedConfigSchema: ChannelEntryConfigSchema<TPlugin> =
typeof configSchema === "function"
? configSchema()
: ((configSchema ?? emptyChannelConfigSchema()) as ChannelEntryConfigSchema<TPlugin>);
const entry = {
id,
name,
description,
get configSchema() {
return getConfigSchema();
},
configSchema: resolvedConfigSchema,
register(api: OpenClawPluginApi) {
if (api.registrationMode === "cli-metadata") {
registerCliMetadata?.(api);

View File

@@ -2,8 +2,10 @@ import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { createJiti } from "jiti";
import { loadConfig, type OpenClawConfig } from "../config/config.js";
import JSON5 from "json5";
import { resolveConfigPath } from "../config/paths.js";
import { applyPluginAutoEnable } from "../config/plugin-auto-enable.js";
import type { OpenClawConfig } from "../config/types.js";
import { openBoundaryFileSync } from "../infra/boundary-file-read.js";
import { resolveBundledPluginsDir } from "../plugins/bundled-dir.js";
import { resolveBundledPluginPublicSurfacePath } from "../plugins/bundled-plugin-metadata.js";
@@ -136,8 +138,15 @@ function getJiti(modulePath: string) {
function readFacadeBoundaryConfigSafely(): OpenClawConfig {
try {
const config = loadConfig();
return config && typeof config === "object" ? config : EMPTY_FACADE_BOUNDARY_CONFIG;
const configPath = resolveConfigPath();
if (!fs.existsSync(configPath)) {
return EMPTY_FACADE_BOUNDARY_CONFIG;
}
const raw = fs.readFileSync(configPath, "utf8");
const parsed = JSON5.parse(raw);
return parsed && typeof parsed === "object"
? (parsed as OpenClawConfig)
: EMPTY_FACADE_BOUNDARY_CONFIG;
} catch {
return EMPTY_FACADE_BOUNDARY_CONFIG;
}

View File

@@ -1,2 +1,2 @@
export { getRuntimeConfigSnapshot } from "../config/io.js";
export { getRuntimeConfigSnapshot } from "../config/runtime-snapshot.js";
export type { OpenClawConfig } from "../config/types.js";