mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-19 05:50:47 +00:00
Build: isolate optional bundled plugin-sdk clusters
This commit is contained in:
@@ -14,3 +14,17 @@ export const optionalBundledClusters = [
|
||||
];
|
||||
|
||||
export const optionalBundledClusterSet = new Set(optionalBundledClusters);
|
||||
|
||||
export const OPTIONAL_BUNDLED_BUILD_ENV = "OPENCLAW_INCLUDE_OPTIONAL_BUNDLED";
|
||||
|
||||
export function isOptionalBundledCluster(cluster) {
|
||||
return optionalBundledClusterSet.has(cluster);
|
||||
}
|
||||
|
||||
export function shouldIncludeOptionalBundledClusters(env = process.env) {
|
||||
return env[OPTIONAL_BUNDLED_BUILD_ENV] === "1";
|
||||
}
|
||||
|
||||
export function shouldBuildBundledCluster(cluster, env = process.env) {
|
||||
return shouldIncludeOptionalBundledClusters(env) || !isOptionalBundledCluster(cluster);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
// Narrow plugin-sdk surface for the bundled googlechat plugin.
|
||||
// Keep this list additive and scoped to symbols used under extensions/googlechat.
|
||||
|
||||
import { resolveChannelGroupRequireMention } from "./channel-policy.js";
|
||||
import {
|
||||
createOptionalChannelSetupAdapter,
|
||||
createOptionalChannelSetupWizard,
|
||||
} from "./optional-channel-setup.js";
|
||||
|
||||
export {
|
||||
createActionGate,
|
||||
jsonResult,
|
||||
@@ -20,7 +26,6 @@ export {
|
||||
export { buildComputedAccountStatusSnapshot } from "./status-helpers.js";
|
||||
export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js";
|
||||
export { createAccountStatusSink, runPassiveAccountLifecycle } from "./channel-lifecycle.js";
|
||||
export { resolveGoogleChatGroupRequireMention } from "../../extensions/googlechat/src/group-policy.js";
|
||||
export { formatPairingApproveHint } from "../channels/plugins/helpers.js";
|
||||
export { resolveChannelMediaMaxBytes } from "../channels/plugins/media-limits.js";
|
||||
export {
|
||||
@@ -65,8 +70,6 @@ export { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.j
|
||||
export { resolveDmGroupAccessWithLists } from "../security/dm-policy-shared.js";
|
||||
export { formatDocsLink } from "../terminal/links.js";
|
||||
export type { WizardPrompter } from "../wizard/prompts.js";
|
||||
export { googlechatSetupAdapter } from "../../extensions/googlechat/api.js";
|
||||
export { googlechatSetupWizard } from "../../extensions/googlechat/api.js";
|
||||
export { resolveInboundRouteEnvelopeBuilderWithRuntime } from "./inbound-envelope.js";
|
||||
export { createScopedPairingAccess } from "./pairing-access.js";
|
||||
export { issuePairingChallenge } from "../pairing/pairing-challenge.js";
|
||||
@@ -88,3 +91,32 @@ export {
|
||||
resolveWebhookTargetWithAuthOrReject,
|
||||
withResolvedWebhookRequestPipeline,
|
||||
} from "./webhook-targets.js";
|
||||
|
||||
type GoogleChatGroupContext = {
|
||||
cfg: import("../config/config.js").OpenClawConfig;
|
||||
accountId?: string | null;
|
||||
groupId?: string | null;
|
||||
};
|
||||
|
||||
export function resolveGoogleChatGroupRequireMention(params: GoogleChatGroupContext): boolean {
|
||||
return resolveChannelGroupRequireMention({
|
||||
cfg: params.cfg,
|
||||
channel: "googlechat",
|
||||
groupId: params.groupId,
|
||||
accountId: params.accountId,
|
||||
});
|
||||
}
|
||||
|
||||
export const googlechatSetupAdapter = createOptionalChannelSetupAdapter({
|
||||
channel: "googlechat",
|
||||
label: "Google Chat",
|
||||
npmSpec: "@openclaw/googlechat",
|
||||
docsPath: "/channels/googlechat",
|
||||
});
|
||||
|
||||
export const googlechatSetupWizard = createOptionalChannelSetupWizard({
|
||||
channel: "googlechat",
|
||||
label: "Google Chat",
|
||||
npmSpec: "@openclaw/googlechat",
|
||||
docsPath: "/channels/googlechat",
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// Narrow plugin-sdk surface for the bundled matrix plugin.
|
||||
// Keep this list additive and scoped to symbols used under extensions/matrix.
|
||||
|
||||
import {
|
||||
createOptionalChannelSetupAdapter,
|
||||
createOptionalChannelSetupWizard,
|
||||
} from "./optional-channel-setup.js";
|
||||
|
||||
export {
|
||||
createActionGate,
|
||||
jsonResult,
|
||||
@@ -108,5 +113,17 @@ export {
|
||||
buildProbeChannelStatusSummary,
|
||||
collectStatusIssuesFromLastError,
|
||||
} from "./status-helpers.js";
|
||||
export { matrixSetupWizard } from "../../extensions/matrix/api.js";
|
||||
export { matrixSetupAdapter } from "../../extensions/matrix/api.js";
|
||||
|
||||
export const matrixSetupWizard = createOptionalChannelSetupWizard({
|
||||
channel: "matrix",
|
||||
label: "Matrix",
|
||||
npmSpec: "@openclaw/matrix",
|
||||
docsPath: "/channels/matrix",
|
||||
});
|
||||
|
||||
export const matrixSetupAdapter = createOptionalChannelSetupAdapter({
|
||||
channel: "matrix",
|
||||
label: "Matrix",
|
||||
npmSpec: "@openclaw/matrix",
|
||||
docsPath: "/channels/matrix",
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// Narrow plugin-sdk surface for the bundled msteams plugin.
|
||||
// Keep this list additive and scoped to symbols used under extensions/msteams.
|
||||
|
||||
import {
|
||||
createOptionalChannelSetupAdapter,
|
||||
createOptionalChannelSetupWizard,
|
||||
} from "./optional-channel-setup.js";
|
||||
|
||||
export type { ChunkMode } from "../auto-reply/chunk.js";
|
||||
export type { HistoryEntry } from "../auto-reply/reply/history.js";
|
||||
export {
|
||||
@@ -117,5 +122,17 @@ export {
|
||||
createDefaultChannelRuntimeState,
|
||||
} from "./status-helpers.js";
|
||||
export { normalizeStringEntries } from "../shared/string-normalization.js";
|
||||
export { msteamsSetupWizard } from "../../extensions/msteams/api.js";
|
||||
export { msteamsSetupAdapter } from "../../extensions/msteams/api.js";
|
||||
|
||||
export const msteamsSetupWizard = createOptionalChannelSetupWizard({
|
||||
channel: "msteams",
|
||||
label: "Microsoft Teams",
|
||||
npmSpec: "@openclaw/msteams",
|
||||
docsPath: "/channels/msteams",
|
||||
});
|
||||
|
||||
export const msteamsSetupAdapter = createOptionalChannelSetupAdapter({
|
||||
channel: "msteams",
|
||||
label: "Microsoft Teams",
|
||||
npmSpec: "@openclaw/msteams",
|
||||
docsPath: "/channels/msteams",
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// Narrow plugin-sdk surface for the bundled nostr plugin.
|
||||
// Keep this list additive and scoped to symbols used under extensions/nostr.
|
||||
|
||||
import {
|
||||
createOptionalChannelSetupAdapter,
|
||||
createOptionalChannelSetupWizard,
|
||||
} from "./optional-channel-setup.js";
|
||||
|
||||
export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js";
|
||||
export type { ChannelSetupAdapter } from "../channels/plugins/types.adapters.js";
|
||||
export { formatPairingApproveHint } from "../channels/plugins/helpers.js";
|
||||
@@ -19,4 +24,17 @@ export {
|
||||
} from "./status-helpers.js";
|
||||
export { createFixedWindowRateLimiter } from "./webhook-memory-guards.js";
|
||||
export { mapAllowFromEntries } from "./channel-config-helpers.js";
|
||||
export { nostrSetupAdapter, nostrSetupWizard } from "../../extensions/nostr/setup-api.js";
|
||||
|
||||
export const nostrSetupAdapter = createOptionalChannelSetupAdapter({
|
||||
channel: "nostr",
|
||||
label: "Nostr",
|
||||
npmSpec: "@openclaw/nostr",
|
||||
docsPath: "/channels/nostr",
|
||||
});
|
||||
|
||||
export const nostrSetupWizard = createOptionalChannelSetupWizard({
|
||||
channel: "nostr",
|
||||
label: "Nostr",
|
||||
npmSpec: "@openclaw/nostr",
|
||||
docsPath: "/channels/nostr",
|
||||
});
|
||||
|
||||
56
src/plugin-sdk/optional-channel-setup.ts
Normal file
56
src/plugin-sdk/optional-channel-setup.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { ChannelSetupWizard } from "../channels/plugins/setup-wizard.js";
|
||||
import type { ChannelSetupAdapter } from "../channels/plugins/types.adapters.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
|
||||
type OptionalChannelSetupParams = {
|
||||
channel: string;
|
||||
label: string;
|
||||
npmSpec?: string;
|
||||
docsPath?: string;
|
||||
};
|
||||
|
||||
function buildOptionalChannelSetupMessage(params: OptionalChannelSetupParams): string {
|
||||
const installTarget = params.npmSpec ?? `the ${params.label} plugin`;
|
||||
const message = [`${params.label} setup requires ${installTarget} to be installed.`];
|
||||
if (params.docsPath) {
|
||||
message.push(`Docs: ${formatDocsLink(params.docsPath, params.docsPath.replace(/^\/+/u, ""))}`);
|
||||
}
|
||||
return message.join(" ");
|
||||
}
|
||||
|
||||
export function createOptionalChannelSetupAdapter(
|
||||
params: OptionalChannelSetupParams,
|
||||
): ChannelSetupAdapter {
|
||||
const message = buildOptionalChannelSetupMessage(params);
|
||||
return {
|
||||
resolveAccountId: ({ accountId }) => accountId ?? DEFAULT_ACCOUNT_ID,
|
||||
applyAccountConfig: () => {
|
||||
throw new Error(message);
|
||||
},
|
||||
validateInput: () => message,
|
||||
};
|
||||
}
|
||||
|
||||
export function createOptionalChannelSetupWizard(
|
||||
params: OptionalChannelSetupParams,
|
||||
): ChannelSetupWizard {
|
||||
const message = buildOptionalChannelSetupMessage(params);
|
||||
return {
|
||||
channel: params.channel,
|
||||
status: {
|
||||
configuredLabel: `${params.label} plugin installed`,
|
||||
unconfiguredLabel: `install ${params.label} plugin`,
|
||||
configuredHint: message,
|
||||
unconfiguredHint: message,
|
||||
unconfiguredScore: 0,
|
||||
resolveConfigured: () => false,
|
||||
resolveStatusLines: () => [message],
|
||||
resolveSelectionHint: () => message,
|
||||
},
|
||||
credentials: [],
|
||||
finalize: async () => {
|
||||
throw new Error(message);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
// Narrow plugin-sdk surface for the bundled tlon plugin.
|
||||
// Keep this list additive and scoped to symbols used under extensions/tlon.
|
||||
|
||||
import {
|
||||
createOptionalChannelSetupAdapter,
|
||||
createOptionalChannelSetupWizard,
|
||||
} from "./optional-channel-setup.js";
|
||||
|
||||
export type { ReplyPayload } from "../auto-reply/types.js";
|
||||
export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js";
|
||||
export {
|
||||
@@ -27,4 +32,17 @@ export type { RuntimeEnv } from "../runtime.js";
|
||||
export { formatDocsLink } from "../terminal/links.js";
|
||||
export type { WizardPrompter } from "../wizard/prompts.js";
|
||||
export { createLoggerBackedRuntime } from "./runtime.js";
|
||||
export { tlonSetupAdapter, tlonSetupWizard } from "../../extensions/tlon/setup-api.js";
|
||||
|
||||
export const tlonSetupAdapter = createOptionalChannelSetupAdapter({
|
||||
channel: "tlon",
|
||||
label: "Tlon",
|
||||
npmSpec: "@openclaw/tlon",
|
||||
docsPath: "/channels/tlon",
|
||||
});
|
||||
|
||||
export const tlonSetupWizard = createOptionalChannelSetupWizard({
|
||||
channel: "tlon",
|
||||
label: "Tlon",
|
||||
npmSpec: "@openclaw/tlon",
|
||||
docsPath: "/channels/tlon",
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// Narrow plugin-sdk surface for the bundled twitch plugin.
|
||||
// Keep this list additive and scoped to symbols used under extensions/twitch.
|
||||
|
||||
import {
|
||||
createOptionalChannelSetupAdapter,
|
||||
createOptionalChannelSetupWizard,
|
||||
} from "./optional-channel-setup.js";
|
||||
|
||||
export type { ReplyPayload } from "../auto-reply/types.js";
|
||||
export { buildChannelConfigSchema } from "../channels/plugins/config-schema.js";
|
||||
export type {
|
||||
@@ -33,7 +38,15 @@ export type { OpenClawPluginApi } from "../plugins/types.js";
|
||||
export type { RuntimeEnv } from "../runtime.js";
|
||||
export { formatDocsLink } from "../terminal/links.js";
|
||||
export type { WizardPrompter } from "../wizard/prompts.js";
|
||||
export {
|
||||
twitchSetupAdapter,
|
||||
twitchSetupWizard,
|
||||
} from "../../extensions/twitch/src/setup-surface.js";
|
||||
|
||||
export const twitchSetupAdapter = createOptionalChannelSetupAdapter({
|
||||
channel: "twitch",
|
||||
label: "Twitch",
|
||||
npmSpec: "@openclaw/twitch",
|
||||
});
|
||||
|
||||
export const twitchSetupWizard = createOptionalChannelSetupWizard({
|
||||
channel: "twitch",
|
||||
label: "Twitch",
|
||||
npmSpec: "@openclaw/twitch",
|
||||
});
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
// Narrow plugin-sdk surface for the bundled zalouser plugin.
|
||||
// Keep this list additive and scoped to symbols used under extensions/zalouser.
|
||||
|
||||
import {
|
||||
createOptionalChannelSetupAdapter,
|
||||
createOptionalChannelSetupWizard,
|
||||
} from "./optional-channel-setup.js";
|
||||
|
||||
export type { ReplyPayload } from "../auto-reply/types.js";
|
||||
export { mergeAllowlist, summarizeMapping } from "../channels/allowlists/resolve-utils.js";
|
||||
export { resolveMentionGatingWithBypass } from "../channels/mention-gating.js";
|
||||
@@ -53,8 +58,6 @@ export type { WizardPrompter } from "../wizard/prompts.js";
|
||||
export { formatAllowFromLowercase } from "./allow-from.js";
|
||||
export { resolveSenderCommandAuthorization } from "./command-auth.js";
|
||||
export { resolveChannelAccountConfigBasePath } from "./config-paths.js";
|
||||
export { zalouserSetupAdapter } from "../../extensions/zalouser/api.js";
|
||||
export { zalouserSetupWizard } from "../../extensions/zalouser/api.js";
|
||||
export {
|
||||
evaluateGroupRouteAccessForPolicy,
|
||||
resolveSenderScopedGroupPolicy,
|
||||
@@ -73,3 +76,17 @@ export {
|
||||
export { formatResolvedUnresolvedNote } from "./resolution-notes.js";
|
||||
export { buildBaseAccountStatusSnapshot } from "./status-helpers.js";
|
||||
export { chunkTextForOutbound } from "./text-chunking.js";
|
||||
|
||||
export const zalouserSetupAdapter = createOptionalChannelSetupAdapter({
|
||||
channel: "zalouser",
|
||||
label: "Zalo Personal",
|
||||
npmSpec: "@openclaw/zalouser",
|
||||
docsPath: "/channels/zalouser",
|
||||
});
|
||||
|
||||
export const zalouserSetupWizard = createOptionalChannelSetupWizard({
|
||||
channel: "zalouser",
|
||||
label: "Zalo Personal",
|
||||
npmSpec: "@openclaw/zalouser",
|
||||
docsPath: "/channels/zalouser",
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { defineConfig, type UserConfig } from "tsdown";
|
||||
import { shouldBuildBundledCluster } from "./scripts/lib/optional-bundled-clusters.mjs";
|
||||
import { buildPluginSdkEntrySources } from "./scripts/lib/plugin-sdk-entries.mjs";
|
||||
|
||||
type InputOptionsFactory = Extract<NonNullable<UserConfig["inputOptions"]>, Function>;
|
||||
@@ -81,6 +82,9 @@ function listBundledPluginBuildEntries(): Record<string, string> {
|
||||
if (!dirent.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
if (!shouldBuildBundledCluster(dirent.name, process.env)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const pluginDir = path.join(extensionsRoot, dirent.name);
|
||||
const manifestPath = path.join(pluginDir, "openclaw.plugin.json");
|
||||
|
||||
Reference in New Issue
Block a user