Merge branch 'main' into feat/deepseek-provider

This commit is contained in:
07akioni
2026-03-17 15:02:24 +08:00
committed by GitHub
119 changed files with 1326 additions and 993 deletions

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { registerSingleProviderPlugin } from "../../src/test-utils/plugin-registration.js";
import { registerSingleProviderPlugin } from "../test-utils/plugin-registration.js";
import amazonBedrockPlugin from "./index.js";
describe("amazon-bedrock provider plugin", () => {

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/bluebubbles";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/bluebubbles";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { bluebubblesPlugin } from "./src/channel.js";
import { setBlueBubblesRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "bluebubbles",
name: "BlueBubbles",
description: "BlueBubbles channel plugin (macOS app)",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setBlueBubblesRuntime(api.runtime);
api.registerChannel({ plugin: bluebubblesPlugin });
},
};
export default plugin;
plugin: bluebubblesPlugin,
setRuntime: setBlueBubblesRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { bluebubblesPlugin } from "./src/channel.js";
export default {
plugin: bluebubblesPlugin,
};
export default defineSetupPluginEntry(bluebubblesPlugin);

View File

@@ -1,13 +1,101 @@
export { sendBlueBubblesAttachment } from "./attachments.js";
export {
addBlueBubblesParticipant,
editBlueBubblesMessage,
leaveBlueBubblesChat,
removeBlueBubblesParticipant,
renameBlueBubblesChat,
setGroupIconBlueBubbles,
unsendBlueBubblesMessage,
import { sendBlueBubblesAttachment as sendBlueBubblesAttachmentImpl } from "./attachments.js";
import {
addBlueBubblesParticipant as addBlueBubblesParticipantImpl,
editBlueBubblesMessage as editBlueBubblesMessageImpl,
leaveBlueBubblesChat as leaveBlueBubblesChatImpl,
removeBlueBubblesParticipant as removeBlueBubblesParticipantImpl,
renameBlueBubblesChat as renameBlueBubblesChatImpl,
setGroupIconBlueBubbles as setGroupIconBlueBubblesImpl,
unsendBlueBubblesMessage as unsendBlueBubblesMessageImpl,
} from "./chat.js";
export { resolveBlueBubblesMessageId } from "./monitor.js";
export { sendBlueBubblesReaction } from "./reactions.js";
export { resolveChatGuidForTarget, sendMessageBlueBubbles } from "./send.js";
import { resolveBlueBubblesMessageId as resolveBlueBubblesMessageIdImpl } from "./monitor.js";
import { sendBlueBubblesReaction as sendBlueBubblesReactionImpl } from "./reactions.js";
import {
resolveChatGuidForTarget as resolveChatGuidForTargetImpl,
sendMessageBlueBubbles as sendMessageBlueBubblesImpl,
} from "./send.js";
type SendBlueBubblesAttachment = typeof import("./attachments.js").sendBlueBubblesAttachment;
type AddBlueBubblesParticipant = typeof import("./chat.js").addBlueBubblesParticipant;
type EditBlueBubblesMessage = typeof import("./chat.js").editBlueBubblesMessage;
type LeaveBlueBubblesChat = typeof import("./chat.js").leaveBlueBubblesChat;
type RemoveBlueBubblesParticipant = typeof import("./chat.js").removeBlueBubblesParticipant;
type RenameBlueBubblesChat = typeof import("./chat.js").renameBlueBubblesChat;
type SetGroupIconBlueBubbles = typeof import("./chat.js").setGroupIconBlueBubbles;
type UnsendBlueBubblesMessage = typeof import("./chat.js").unsendBlueBubblesMessage;
type ResolveBlueBubblesMessageId = typeof import("./monitor.js").resolveBlueBubblesMessageId;
type SendBlueBubblesReaction = typeof import("./reactions.js").sendBlueBubblesReaction;
type ResolveChatGuidForTarget = typeof import("./send.js").resolveChatGuidForTarget;
type SendMessageBlueBubbles = typeof import("./send.js").sendMessageBlueBubbles;
export function sendBlueBubblesAttachment(
...args: Parameters<SendBlueBubblesAttachment>
): ReturnType<SendBlueBubblesAttachment> {
return sendBlueBubblesAttachmentImpl(...args);
}
export function addBlueBubblesParticipant(
...args: Parameters<AddBlueBubblesParticipant>
): ReturnType<AddBlueBubblesParticipant> {
return addBlueBubblesParticipantImpl(...args);
}
export function editBlueBubblesMessage(
...args: Parameters<EditBlueBubblesMessage>
): ReturnType<EditBlueBubblesMessage> {
return editBlueBubblesMessageImpl(...args);
}
export function leaveBlueBubblesChat(
...args: Parameters<LeaveBlueBubblesChat>
): ReturnType<LeaveBlueBubblesChat> {
return leaveBlueBubblesChatImpl(...args);
}
export function removeBlueBubblesParticipant(
...args: Parameters<RemoveBlueBubblesParticipant>
): ReturnType<RemoveBlueBubblesParticipant> {
return removeBlueBubblesParticipantImpl(...args);
}
export function renameBlueBubblesChat(
...args: Parameters<RenameBlueBubblesChat>
): ReturnType<RenameBlueBubblesChat> {
return renameBlueBubblesChatImpl(...args);
}
export function setGroupIconBlueBubbles(
...args: Parameters<SetGroupIconBlueBubbles>
): ReturnType<SetGroupIconBlueBubbles> {
return setGroupIconBlueBubblesImpl(...args);
}
export function unsendBlueBubblesMessage(
...args: Parameters<UnsendBlueBubblesMessage>
): ReturnType<UnsendBlueBubblesMessage> {
return unsendBlueBubblesMessageImpl(...args);
}
export function resolveBlueBubblesMessageId(
...args: Parameters<ResolveBlueBubblesMessageId>
): ReturnType<ResolveBlueBubblesMessageId> {
return resolveBlueBubblesMessageIdImpl(...args);
}
export function sendBlueBubblesReaction(
...args: Parameters<SendBlueBubblesReaction>
): ReturnType<SendBlueBubblesReaction> {
return sendBlueBubblesReactionImpl(...args);
}
export function resolveChatGuidForTarget(
...args: Parameters<ResolveChatGuidForTarget>
): ReturnType<ResolveChatGuidForTarget> {
return resolveChatGuidForTargetImpl(...args);
}
export function sendMessageBlueBubbles(
...args: Parameters<SendMessageBlueBubbles>
): ReturnType<SendMessageBlueBubbles> {
return sendMessageBlueBubblesImpl(...args);
}

View File

@@ -1,6 +1,57 @@
export { sendBlueBubblesMedia } from "./media-send.js";
export { resolveBlueBubblesMessageId } from "./monitor.js";
export { monitorBlueBubblesProvider, resolveWebhookPathFromConfig } from "./monitor.js";
export { type BlueBubblesProbe, probeBlueBubbles } from "./probe.js";
export { sendMessageBlueBubbles } from "./send.js";
export { blueBubblesSetupWizard } from "./setup-surface.js";
import { sendBlueBubblesMedia as sendBlueBubblesMediaImpl } from "./media-send.js";
import {
monitorBlueBubblesProvider as monitorBlueBubblesProviderImpl,
resolveBlueBubblesMessageId as resolveBlueBubblesMessageIdImpl,
resolveWebhookPathFromConfig as resolveWebhookPathFromConfigImpl,
} from "./monitor.js";
import { probeBlueBubbles as probeBlueBubblesImpl } from "./probe.js";
import { sendMessageBlueBubbles as sendMessageBlueBubblesImpl } from "./send.js";
import { blueBubblesSetupWizard as blueBubblesSetupWizardImpl } from "./setup-surface.js";
export type { BlueBubblesProbe } from "./probe.js";
type SendBlueBubblesMedia = typeof import("./media-send.js").sendBlueBubblesMedia;
type ResolveBlueBubblesMessageId = typeof import("./monitor.js").resolveBlueBubblesMessageId;
type MonitorBlueBubblesProvider = typeof import("./monitor.js").monitorBlueBubblesProvider;
type ResolveWebhookPathFromConfig = typeof import("./monitor.js").resolveWebhookPathFromConfig;
type ProbeBlueBubbles = typeof import("./probe.js").probeBlueBubbles;
type SendMessageBlueBubbles = typeof import("./send.js").sendMessageBlueBubbles;
type BlueBubblesSetupWizard = typeof import("./setup-surface.js").blueBubblesSetupWizard;
export function sendBlueBubblesMedia(
...args: Parameters<SendBlueBubblesMedia>
): ReturnType<SendBlueBubblesMedia> {
return sendBlueBubblesMediaImpl(...args);
}
export function resolveBlueBubblesMessageId(
...args: Parameters<ResolveBlueBubblesMessageId>
): ReturnType<ResolveBlueBubblesMessageId> {
return resolveBlueBubblesMessageIdImpl(...args);
}
export function monitorBlueBubblesProvider(
...args: Parameters<MonitorBlueBubblesProvider>
): ReturnType<MonitorBlueBubblesProvider> {
return monitorBlueBubblesProviderImpl(...args);
}
export function resolveWebhookPathFromConfig(
...args: Parameters<ResolveWebhookPathFromConfig>
): ReturnType<ResolveWebhookPathFromConfig> {
return resolveWebhookPathFromConfigImpl(...args);
}
export function probeBlueBubbles(
...args: Parameters<ProbeBlueBubbles>
): ReturnType<ProbeBlueBubbles> {
return probeBlueBubblesImpl(...args);
}
export function sendMessageBlueBubbles(
...args: Parameters<SendMessageBlueBubbles>
): ReturnType<SendMessageBlueBubbles> {
return sendMessageBlueBubblesImpl(...args);
}
export const blueBubblesSetupWizard: BlueBubblesSetupWizard = { ...blueBubblesSetupWizardImpl };

View File

@@ -1,7 +1,7 @@
import type { IncomingMessage } from "node:http";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/diffs";
import { describe, expect, it, vi } from "vitest";
import { createMockServerResponse } from "../../src/test-utils/mock-http-response.js";
import { createMockServerResponse } from "../test-utils/mock-http-response.js";
import { createTestPluginApi } from "../test-utils/plugin-api.js";
import plugin from "./index.js";

View File

@@ -1,6 +1,6 @@
import type { IncomingMessage } from "node:http";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { createMockServerResponse } from "../../../src/test-utils/mock-http-response.js";
import { createMockServerResponse } from "../../test-utils/mock-http-response.js";
import { createDiffsHttpHandler } from "./http.js";
import { DiffArtifactStore } from "./store.js";
import { createDiffStoreHarness } from "./test-helpers.js";

View File

@@ -1,22 +1,13 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/core";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { discordPlugin } from "./src/channel.js";
import { setDiscordRuntime } from "./src/runtime.js";
import { registerDiscordSubagentHooks } from "./src/subagent-hooks.js";
const plugin = {
export default defineChannelPluginEntry({
id: "discord",
name: "Discord",
description: "Discord channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setDiscordRuntime(api.runtime);
api.registerChannel({ plugin: discordPlugin });
if (api.registrationMode !== "full") {
return;
}
registerDiscordSubagentHooks(api);
},
};
export default plugin;
plugin: discordPlugin,
setRuntime: setDiscordRuntime,
registerFull: registerDiscordSubagentHooks,
});

View File

@@ -1,3 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { discordSetupPlugin } from "./src/channel.setup.js";
export default { plugin: discordSetupPlugin };
export default defineSetupPluginEntry(discordSetupPlugin);

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { withFetchPreconnect } from "../../../src/test-utils/fetch-mock.js";
import { withFetchPreconnect } from "../../test-utils/fetch-mock.js";
import { fetchDiscord } from "./api.js";
import { jsonResponse } from "./test-http-helpers.js";

View File

@@ -1 +1,5 @@
export { discordSetupWizard } from "./setup-surface.js";
import { discordSetupWizard as discordSetupWizardImpl } from "./setup-surface.js";
type DiscordSetupWizard = typeof import("./setup-surface.js").discordSetupWizard;
export const discordSetupWizard: DiscordSetupWizard = { ...discordSetupWizardImpl };

View File

@@ -10,11 +10,7 @@ import {
} from "openclaw/plugin-sdk/channel-config-helpers";
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime";
import { normalizeMessageChannel } from "openclaw/plugin-sdk/channel-runtime";
import {
buildOutboundBaseSessionKey,
normalizeOutboundThreadId,
} from "openclaw/plugin-sdk/core";
import { resolveThreadSessionKeys, type RoutePeer } from "openclaw/plugin-sdk/routing";
import { buildOutboundBaseSessionKey, normalizeOutboundThreadId } from "openclaw/plugin-sdk/core";
import {
buildComputedAccountStatusSnapshot,
buildTokenChannelStatusSummary,
@@ -31,6 +27,7 @@ import {
type ChannelPlugin,
type OpenClawConfig,
} from "openclaw/plugin-sdk/discord";
import { resolveThreadSessionKeys, type RoutePeer } from "openclaw/plugin-sdk/routing";
import {
listDiscordAccountIds,
resolveDiscordAccount,
@@ -51,7 +48,7 @@ import { resolveDiscordUserAllowlist } from "./resolve-users.js";
import { getDiscordRuntime } from "./runtime.js";
import { fetchChannelPermissionsDiscord } from "./send.js";
import { discordSetupAdapter } from "./setup-core.js";
import { createDiscordPluginBase } from "./shared.js";
import { createDiscordPluginBase, discordConfigAccessors } from "./shared.js";
import { collectDiscordStatusIssues } from "./status-issues.js";
import { parseDiscordTarget } from "./targets.js";
import { DiscordUiContainer } from "./ui.js";

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { countLines, hasBalancedFences } from "../../../src/test-utils/chunk-test-helpers.js";
import { countLines, hasBalancedFences } from "../../test-utils/chunk-test-helpers.js";
import { chunkDiscordText, chunkDiscordTextWithMode } from "./chunk.js";
describe("chunkDiscordText", () => {

View File

@@ -1,6 +1,6 @@
import { ChannelType, type Guild } from "@buape/carbon";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { typedCases } from "../../../src/test-utils/typed-cases.js";
import { typedCases } from "../../test-utils/typed-cases.js";
import {
allowListMatches,
buildDiscordMediaPayload,

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { withFetchPreconnect } from "../../../src/test-utils/fetch-mock.js";
import { withFetchPreconnect } from "../../test-utils/fetch-mock.js";
import { resolveDiscordChannelAllowlist } from "./resolve-channels.js";
import { jsonResponse, urlToString } from "./test-http-helpers.js";

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import { withFetchPreconnect } from "../../../src/test-utils/fetch-mock.js";
import { withFetchPreconnect } from "../../test-utils/fetch-mock.js";
import { resolveDiscordUserAllowlist } from "./resolve-users.js";
import { jsonResponse, urlToString } from "./test-http-helpers.js";

View File

@@ -100,28 +100,20 @@ async function resolveDiscordGroupAllowlist(params: {
});
}
export const discordSetupWizard: ChannelSetupWizard = createDiscordSetupWizardBase(async () => ({
discordSetupWizard: {
dmPolicy: {
promptAllowFrom: promptDiscordAllowFrom,
},
groupAccess: {
resolveAllowlist: async ({ cfg, accountId, credentialValues, entries }) =>
await resolveDiscordGroupAllowlist({
cfg,
accountId,
credentialValues,
entries,
}),
},
allowFrom: {
resolveEntries: async ({ cfg, accountId, credentialValues, entries }) =>
await resolveDiscordAllowFromEntries({
token:
resolveDiscordAccount({ cfg, accountId }).token ||
(typeof credentialValues.token === "string" ? credentialValues.token : ""),
entries,
}),
},
} as ChannelSetupWizard,
}));
export const discordSetupWizard: ChannelSetupWizard = createDiscordSetupWizardBase({
promptAllowFrom: promptDiscordAllowFrom,
resolveAllowFromEntries: async ({ cfg, accountId, credentialValues, entries }) =>
await resolveDiscordAllowFromEntries({
token:
resolveDiscordAccount({ cfg, accountId }).token ||
(typeof credentialValues.token === "string" ? credentialValues.token : ""),
entries,
}),
resolveGroupAllowlist: async ({ cfg, accountId, credentialValues, entries }) =>
await resolveDiscordGroupAllowlist({
cfg,
accountId,
credentialValues,
entries,
}),
});

View File

@@ -1 +1,8 @@
export { DiscordVoiceManager, DiscordVoiceReadyListener } from "./manager.js";
import {
DiscordVoiceManager as DiscordVoiceManagerImpl,
DiscordVoiceReadyListener as DiscordVoiceReadyListenerImpl,
} from "./manager.js";
export class DiscordVoiceManager extends DiscordVoiceManagerImpl {}
export class DiscordVoiceReadyListener extends DiscordVoiceReadyListenerImpl {}

View File

@@ -1,5 +1,4 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/feishu";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/feishu";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { registerFeishuBitableTools } from "./src/bitable.js";
import { feishuPlugin } from "./src/channel.js";
import { registerFeishuChatTools } from "./src/chat.js";
@@ -46,17 +45,13 @@ export {
} from "./src/mention.js";
export { feishuPlugin } from "./src/channel.js";
const plugin = {
export default defineChannelPluginEntry({
id: "feishu",
name: "Feishu",
description: "Feishu/Lark channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setFeishuRuntime(api.runtime);
api.registerChannel({ plugin: feishuPlugin });
if (api.registrationMode !== "full") {
return;
}
plugin: feishuPlugin,
setRuntime: setFeishuRuntime,
registerFull(api) {
registerFeishuSubagentHooks(api);
registerFeishuDocTools(api);
registerFeishuChatTools(api);
@@ -65,6 +60,4 @@ const plugin = {
registerFeishuPermTools(api);
registerFeishuBitableTools(api);
},
};
export default plugin;
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { feishuPlugin } from "./src/channel.js";
export default {
plugin: feishuPlugin,
};
export default defineSetupPluginEntry(feishuPlugin);

View File

@@ -1,7 +1,129 @@
export { listFeishuDirectoryGroupsLive, listFeishuDirectoryPeersLive } from "./directory.js";
export { feishuOutbound } from "./outbound.js";
export { createPinFeishu, listPinsFeishu, removePinFeishu } from "./pins.js";
export { probeFeishu } from "./probe.js";
export { addReactionFeishu, listReactionsFeishu, removeReactionFeishu } from "./reactions.js";
export { getChatInfo, getChatMembers, getFeishuMemberInfo } from "./chat.js";
export { editMessageFeishu, getMessageFeishu, sendCardFeishu, sendMessageFeishu } from "./send.js";
import {
getChatInfo as getChatInfoImpl,
getChatMembers as getChatMembersImpl,
getFeishuMemberInfo as getFeishuMemberInfoImpl,
} from "./chat.js";
import {
listFeishuDirectoryGroupsLive as listFeishuDirectoryGroupsLiveImpl,
listFeishuDirectoryPeersLive as listFeishuDirectoryPeersLiveImpl,
} from "./directory.js";
import { feishuOutbound as feishuOutboundImpl } from "./outbound.js";
import {
createPinFeishu as createPinFeishuImpl,
listPinsFeishu as listPinsFeishuImpl,
removePinFeishu as removePinFeishuImpl,
} from "./pins.js";
import { probeFeishu as probeFeishuImpl } from "./probe.js";
import {
addReactionFeishu as addReactionFeishuImpl,
listReactionsFeishu as listReactionsFeishuImpl,
removeReactionFeishu as removeReactionFeishuImpl,
} from "./reactions.js";
import {
editMessageFeishu as editMessageFeishuImpl,
getMessageFeishu as getMessageFeishuImpl,
sendCardFeishu as sendCardFeishuImpl,
sendMessageFeishu as sendMessageFeishuImpl,
} from "./send.js";
type ListFeishuDirectoryGroupsLive = typeof import("./directory.js").listFeishuDirectoryGroupsLive;
type ListFeishuDirectoryPeersLive = typeof import("./directory.js").listFeishuDirectoryPeersLive;
type FeishuOutbound = typeof import("./outbound.js").feishuOutbound;
type CreatePinFeishu = typeof import("./pins.js").createPinFeishu;
type ListPinsFeishu = typeof import("./pins.js").listPinsFeishu;
type RemovePinFeishu = typeof import("./pins.js").removePinFeishu;
type ProbeFeishu = typeof import("./probe.js").probeFeishu;
type AddReactionFeishu = typeof import("./reactions.js").addReactionFeishu;
type ListReactionsFeishu = typeof import("./reactions.js").listReactionsFeishu;
type RemoveReactionFeishu = typeof import("./reactions.js").removeReactionFeishu;
type GetChatInfo = typeof import("./chat.js").getChatInfo;
type GetChatMembers = typeof import("./chat.js").getChatMembers;
type GetFeishuMemberInfo = typeof import("./chat.js").getFeishuMemberInfo;
type EditMessageFeishu = typeof import("./send.js").editMessageFeishu;
type GetMessageFeishu = typeof import("./send.js").getMessageFeishu;
type SendCardFeishu = typeof import("./send.js").sendCardFeishu;
type SendMessageFeishu = typeof import("./send.js").sendMessageFeishu;
export function listFeishuDirectoryGroupsLive(
...args: Parameters<ListFeishuDirectoryGroupsLive>
): ReturnType<ListFeishuDirectoryGroupsLive> {
return listFeishuDirectoryGroupsLiveImpl(...args);
}
export function listFeishuDirectoryPeersLive(
...args: Parameters<ListFeishuDirectoryPeersLive>
): ReturnType<ListFeishuDirectoryPeersLive> {
return listFeishuDirectoryPeersLiveImpl(...args);
}
export const feishuOutbound: FeishuOutbound = { ...feishuOutboundImpl };
export function createPinFeishu(...args: Parameters<CreatePinFeishu>): ReturnType<CreatePinFeishu> {
return createPinFeishuImpl(...args);
}
export function listPinsFeishu(...args: Parameters<ListPinsFeishu>): ReturnType<ListPinsFeishu> {
return listPinsFeishuImpl(...args);
}
export function removePinFeishu(...args: Parameters<RemovePinFeishu>): ReturnType<RemovePinFeishu> {
return removePinFeishuImpl(...args);
}
export function probeFeishu(...args: Parameters<ProbeFeishu>): ReturnType<ProbeFeishu> {
return probeFeishuImpl(...args);
}
export function addReactionFeishu(
...args: Parameters<AddReactionFeishu>
): ReturnType<AddReactionFeishu> {
return addReactionFeishuImpl(...args);
}
export function listReactionsFeishu(
...args: Parameters<ListReactionsFeishu>
): ReturnType<ListReactionsFeishu> {
return listReactionsFeishuImpl(...args);
}
export function removeReactionFeishu(
...args: Parameters<RemoveReactionFeishu>
): ReturnType<RemoveReactionFeishu> {
return removeReactionFeishuImpl(...args);
}
export function getChatInfo(...args: Parameters<GetChatInfo>): ReturnType<GetChatInfo> {
return getChatInfoImpl(...args);
}
export function getChatMembers(...args: Parameters<GetChatMembers>): ReturnType<GetChatMembers> {
return getChatMembersImpl(...args);
}
export function getFeishuMemberInfo(
...args: Parameters<GetFeishuMemberInfo>
): ReturnType<GetFeishuMemberInfo> {
return getFeishuMemberInfoImpl(...args);
}
export function editMessageFeishu(
...args: Parameters<EditMessageFeishu>
): ReturnType<EditMessageFeishu> {
return editMessageFeishuImpl(...args);
}
export function getMessageFeishu(
...args: Parameters<GetMessageFeishu>
): ReturnType<GetMessageFeishu> {
return getMessageFeishuImpl(...args);
}
export function sendCardFeishu(...args: Parameters<SendCardFeishu>): ReturnType<SendCardFeishu> {
return sendCardFeishuImpl(...args);
}
export function sendMessageFeishu(
...args: Parameters<SendMessageFeishu>
): ReturnType<SendMessageFeishu> {
return sendMessageFeishuImpl(...args);
}

View File

@@ -1,8 +1,5 @@
import { describe, expect, it } from "vitest";
import {
createProviderUsageFetch,
makeResponse,
} from "../../src/test-utils/provider-usage-fetch.js";
import { createProviderUsageFetch, makeResponse } from "../test-utils/provider-usage-fetch.js";
import { fetchCopilotUsage } from "./usage.js";
describe("fetchCopilotUsage", () => {

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/googlechat";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/googlechat";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { googlechatPlugin } from "./src/channel.js";
import { setGoogleChatRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "googlechat",
name: "Google Chat",
description: "OpenClaw Google Chat channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setGoogleChatRuntime(api.runtime);
api.registerChannel(googlechatPlugin);
},
};
export default plugin;
plugin: googlechatPlugin,
setRuntime: setGoogleChatRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { googlechatPlugin } from "./src/channel.js";
export default {
plugin: googlechatPlugin,
};
export default defineSetupPluginEntry(googlechatPlugin);

View File

@@ -1,2 +1,43 @@
export { probeGoogleChat, sendGoogleChatMessage, uploadGoogleChatAttachment } from "./api.js";
export { resolveGoogleChatWebhookPath, startGoogleChatMonitor } from "./monitor.js";
import {
probeGoogleChat as probeGoogleChatImpl,
sendGoogleChatMessage as sendGoogleChatMessageImpl,
uploadGoogleChatAttachment as uploadGoogleChatAttachmentImpl,
} from "./api.js";
import {
resolveGoogleChatWebhookPath as resolveGoogleChatWebhookPathImpl,
startGoogleChatMonitor as startGoogleChatMonitorImpl,
} from "./monitor.js";
type ProbeGoogleChat = typeof import("./api.js").probeGoogleChat;
type SendGoogleChatMessage = typeof import("./api.js").sendGoogleChatMessage;
type UploadGoogleChatAttachment = typeof import("./api.js").uploadGoogleChatAttachment;
type ResolveGoogleChatWebhookPath = typeof import("./monitor.js").resolveGoogleChatWebhookPath;
type StartGoogleChatMonitor = typeof import("./monitor.js").startGoogleChatMonitor;
export function probeGoogleChat(...args: Parameters<ProbeGoogleChat>): ReturnType<ProbeGoogleChat> {
return probeGoogleChatImpl(...args);
}
export function sendGoogleChatMessage(
...args: Parameters<SendGoogleChatMessage>
): ReturnType<SendGoogleChatMessage> {
return sendGoogleChatMessageImpl(...args);
}
export function uploadGoogleChatAttachment(
...args: Parameters<UploadGoogleChatAttachment>
): ReturnType<UploadGoogleChatAttachment> {
return uploadGoogleChatAttachmentImpl(...args);
}
export function resolveGoogleChatWebhookPath(
...args: Parameters<ResolveGoogleChatWebhookPath>
): ReturnType<ResolveGoogleChatWebhookPath> {
return resolveGoogleChatWebhookPathImpl(...args);
}
export function startGoogleChatMonitor(
...args: Parameters<StartGoogleChatMonitor>
): ReturnType<StartGoogleChatMonitor> {
return startGoogleChatMonitorImpl(...args);
}

View File

@@ -4,7 +4,7 @@ import type { OpenClawConfig, PluginRuntime } from "openclaw/plugin-sdk/googlech
import { afterEach, describe, expect, it, vi } from "vitest";
import { createEmptyPluginRegistry } from "../../../src/plugins/registry.js";
import { setActivePluginRegistry } from "../../../src/plugins/runtime.js";
import { createMockServerResponse } from "../../../src/test-utils/mock-http-response.js";
import { createMockServerResponse } from "../../test-utils/mock-http-response.js";
import type { ResolvedGoogleChatAccount } from "./accounts.js";
import { verifyGoogleChatRequest } from "./auth.js";
import { handleGoogleChatWebhookRequest, registerGoogleChatWebhookTarget } from "./monitor.js";

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/core";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { imessagePlugin } from "./src/channel.js";
import { setIMessageRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "imessage",
name: "iMessage",
description: "iMessage channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setIMessageRuntime(api.runtime);
api.registerChannel({ plugin: imessagePlugin });
},
};
export default plugin;
plugin: imessagePlugin,
setRuntime: setIMessageRuntime,
});

View File

@@ -1,3 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { imessageSetupPlugin } from "./src/channel.setup.js";
export default { plugin: imessageSetupPlugin };
export default defineSetupPluginEntry(imessageSetupPlugin);

View File

@@ -1,17 +1,12 @@
import type { ChannelPlugin, OpenClawPluginApi } from "openclaw/plugin-sdk/irc";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/irc";
import type { ChannelPlugin } from "openclaw/plugin-sdk/core";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { ircPlugin } from "./src/channel.js";
import { setIrcRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "irc",
name: "IRC",
description: "IRC channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setIrcRuntime(api.runtime);
api.registerChannel({ plugin: ircPlugin as ChannelPlugin });
},
};
export default plugin;
plugin: ircPlugin as ChannelPlugin,
setRuntime: setIrcRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { ircPlugin } from "./src/channel.js";
export default {
plugin: ircPlugin,
};
export default defineSetupPluginEntry(ircPlugin);

View File

@@ -1,22 +1,13 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/line";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/line";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { registerLineCardCommand } from "./src/card-command.js";
import { linePlugin } from "./src/channel.js";
import { setLineRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "line",
name: "LINE",
description: "LINE Messaging API channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setLineRuntime(api.runtime);
api.registerChannel({ plugin: linePlugin });
if (api.registrationMode !== "full") {
return;
}
registerLineCardCommand(api);
},
};
export default plugin;
plugin: linePlugin,
setRuntime: setLineRuntime,
registerFull: registerLineCardCommand,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { lineSetupPlugin } from "./src/channel.setup.js";
export default {
plugin: lineSetupPlugin,
};
export default defineSetupPluginEntry(lineSetupPlugin);

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/matrix";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/matrix";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { matrixPlugin } from "./src/channel.js";
import { setMatrixRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "matrix",
name: "Matrix",
description: "Matrix channel plugin (matrix-js-sdk)",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setMatrixRuntime(api.runtime);
api.registerChannel({ plugin: matrixPlugin });
},
};
export default plugin;
description: "Matrix channel plugin",
plugin: matrixPlugin,
setRuntime: setMatrixRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { matrixPlugin } from "./src/channel.js";
export default {
plugin: matrixPlugin,
};
export default defineSetupPluginEntry(matrixPlugin);

View File

@@ -1,6 +1,55 @@
export { listMatrixDirectoryGroupsLive, listMatrixDirectoryPeersLive } from "./directory-live.js";
export { resolveMatrixAuth } from "./matrix/client.js";
export { probeMatrix } from "./matrix/probe.js";
export { sendMessageMatrix } from "./matrix/send.js";
export { resolveMatrixTargets } from "./resolve-targets.js";
export { matrixOutbound } from "./outbound.js";
import {
listMatrixDirectoryGroupsLive as listMatrixDirectoryGroupsLiveImpl,
listMatrixDirectoryPeersLive as listMatrixDirectoryPeersLiveImpl,
} from "./directory-live.js";
import { resolveMatrixAuth as resolveMatrixAuthImpl } from "./matrix/client.js";
import { probeMatrix as probeMatrixImpl } from "./matrix/probe.js";
import { sendMessageMatrix as sendMessageMatrixImpl } from "./matrix/send.js";
import { matrixOutbound as matrixOutboundImpl } from "./outbound.js";
import { resolveMatrixTargets as resolveMatrixTargetsImpl } from "./resolve-targets.js";
type ListMatrixDirectoryGroupsLive =
typeof import("./directory-live.js").listMatrixDirectoryGroupsLive;
type ListMatrixDirectoryPeersLive =
typeof import("./directory-live.js").listMatrixDirectoryPeersLive;
type ResolveMatrixAuth = typeof import("./matrix/client.js").resolveMatrixAuth;
type ProbeMatrix = typeof import("./matrix/probe.js").probeMatrix;
type SendMessageMatrix = typeof import("./matrix/send.js").sendMessageMatrix;
type ResolveMatrixTargets = typeof import("./resolve-targets.js").resolveMatrixTargets;
type MatrixOutbound = typeof import("./outbound.js").matrixOutbound;
export function listMatrixDirectoryGroupsLive(
...args: Parameters<ListMatrixDirectoryGroupsLive>
): ReturnType<ListMatrixDirectoryGroupsLive> {
return listMatrixDirectoryGroupsLiveImpl(...args);
}
export function listMatrixDirectoryPeersLive(
...args: Parameters<ListMatrixDirectoryPeersLive>
): ReturnType<ListMatrixDirectoryPeersLive> {
return listMatrixDirectoryPeersLiveImpl(...args);
}
export function resolveMatrixAuth(
...args: Parameters<ResolveMatrixAuth>
): ReturnType<ResolveMatrixAuth> {
return resolveMatrixAuthImpl(...args);
}
export function probeMatrix(...args: Parameters<ProbeMatrix>): ReturnType<ProbeMatrix> {
return probeMatrixImpl(...args);
}
export function sendMessageMatrix(
...args: Parameters<SendMessageMatrix>
): ReturnType<SendMessageMatrix> {
return sendMessageMatrixImpl(...args);
}
export function resolveMatrixTargets(
...args: Parameters<ResolveMatrixTargets>
): ReturnType<ResolveMatrixTargets> {
return resolveMatrixTargetsImpl(...args);
}
export const matrixOutbound: MatrixOutbound = { ...matrixOutboundImpl };

View File

@@ -1,26 +1,17 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/mattermost";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/mattermost";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { mattermostPlugin } from "./src/channel.js";
import { getSlashCommandState, registerSlashCommandRoute } from "./src/mattermost/slash-state.js";
import { registerSlashCommandRoute } from "./src/mattermost/slash-state.js";
import { setMattermostRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "mattermost",
name: "Mattermost",
description: "Mattermost channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setMattermostRuntime(api.runtime);
api.registerChannel({ plugin: mattermostPlugin });
if (api.registrationMode !== "full") {
return;
}
// Register the HTTP route for slash command callbacks.
// The actual command registration with MM happens in the monitor
// after the bot connects and we know the team ID.
plugin: mattermostPlugin,
setRuntime: setMattermostRuntime,
registerFull(api) {
// Actual slash-command registration happens after the monitor connects and
// knows the team id; the route itself can be wired here.
registerSlashCommandRoute(api);
},
};
export default plugin;
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { mattermostPlugin } from "./src/channel.js";
export default {
plugin: mattermostPlugin,
};
export default defineSetupPluginEntry(mattermostPlugin);

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/msteams";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/msteams";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { msteamsPlugin } from "./src/channel.js";
import { setMSTeamsRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "msteams",
name: "Microsoft Teams",
description: "Microsoft Teams channel plugin (Bot Framework)",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setMSTeamsRuntime(api.runtime);
api.registerChannel({ plugin: msteamsPlugin });
},
};
export default plugin;
plugin: msteamsPlugin,
setRuntime: setMSTeamsRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { msteamsPlugin } from "./src/channel.js";
export default {
plugin: msteamsPlugin,
};
export default defineSetupPluginEntry(msteamsPlugin);

View File

@@ -1,4 +1,49 @@
export { listMSTeamsDirectoryGroupsLive, listMSTeamsDirectoryPeersLive } from "./directory-live.js";
export { msteamsOutbound } from "./outbound.js";
export { probeMSTeams } from "./probe.js";
export { sendAdaptiveCardMSTeams, sendMessageMSTeams } from "./send.js";
import {
listMSTeamsDirectoryGroupsLive as listMSTeamsDirectoryGroupsLiveImpl,
listMSTeamsDirectoryPeersLive as listMSTeamsDirectoryPeersLiveImpl,
} from "./directory-live.js";
import { msteamsOutbound as msteamsOutboundImpl } from "./outbound.js";
import { probeMSTeams as probeMSTeamsImpl } from "./probe.js";
import {
sendAdaptiveCardMSTeams as sendAdaptiveCardMSTeamsImpl,
sendMessageMSTeams as sendMessageMSTeamsImpl,
} from "./send.js";
type ListMSTeamsDirectoryGroupsLive =
typeof import("./directory-live.js").listMSTeamsDirectoryGroupsLive;
type ListMSTeamsDirectoryPeersLive =
typeof import("./directory-live.js").listMSTeamsDirectoryPeersLive;
type MSTeamsOutbound = typeof import("./outbound.js").msteamsOutbound;
type ProbeMSTeams = typeof import("./probe.js").probeMSTeams;
type SendAdaptiveCardMSTeams = typeof import("./send.js").sendAdaptiveCardMSTeams;
type SendMessageMSTeams = typeof import("./send.js").sendMessageMSTeams;
export function listMSTeamsDirectoryGroupsLive(
...args: Parameters<ListMSTeamsDirectoryGroupsLive>
): ReturnType<ListMSTeamsDirectoryGroupsLive> {
return listMSTeamsDirectoryGroupsLiveImpl(...args);
}
export function listMSTeamsDirectoryPeersLive(
...args: Parameters<ListMSTeamsDirectoryPeersLive>
): ReturnType<ListMSTeamsDirectoryPeersLive> {
return listMSTeamsDirectoryPeersLiveImpl(...args);
}
export const msteamsOutbound: MSTeamsOutbound = { ...msteamsOutboundImpl };
export function probeMSTeams(...args: Parameters<ProbeMSTeams>): ReturnType<ProbeMSTeams> {
return probeMSTeamsImpl(...args);
}
export function sendAdaptiveCardMSTeams(
...args: Parameters<SendAdaptiveCardMSTeams>
): ReturnType<SendAdaptiveCardMSTeams> {
return sendAdaptiveCardMSTeamsImpl(...args);
}
export function sendMessageMSTeams(
...args: Parameters<SendMessageMSTeams>
): ReturnType<SendMessageMSTeams> {
return sendMessageMSTeamsImpl(...args);
}

View File

@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from "vitest";
import { withFetchPreconnect } from "../../../src/test-utils/fetch-mock.js";
import { withFetchPreconnect } from "../../test-utils/fetch-mock.js";
import { uploadToOneDrive, uploadToSharePoint } from "./graph-upload.js";
describe("graph upload helpers", () => {

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/nextcloud-talk";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/nextcloud-talk";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { nextcloudTalkPlugin } from "./src/channel.js";
import { setNextcloudTalkRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "nextcloud-talk",
name: "Nextcloud Talk",
description: "Nextcloud Talk channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setNextcloudTalkRuntime(api.runtime);
api.registerChannel({ plugin: nextcloudTalkPlugin });
},
};
export default plugin;
plugin: nextcloudTalkPlugin,
setRuntime: setNextcloudTalkRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { nextcloudTalkPlugin } from "./src/channel.js";
export default {
plugin: nextcloudTalkPlugin,
};
export default defineSetupPluginEntry(nextcloudTalkPlugin);

View File

@@ -1,24 +1,17 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/nostr";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/nostr";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { nostrPlugin } from "./src/channel.js";
import type { NostrProfile } from "./src/config-schema.js";
import { createNostrProfileHttpHandler } from "./src/nostr-profile-http.js";
import { setNostrRuntime, getNostrRuntime } from "./src/runtime.js";
import { getNostrRuntime, setNostrRuntime } from "./src/runtime.js";
import { resolveNostrAccount } from "./src/types.js";
const plugin = {
export default defineChannelPluginEntry({
id: "nostr",
name: "Nostr",
description: "Nostr DM channel plugin via NIP-04",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setNostrRuntime(api.runtime);
api.registerChannel({ plugin: nostrPlugin });
if (api.registrationMode !== "full") {
return;
}
// Register HTTP handler for profile management
plugin: nostrPlugin,
setRuntime: setNostrRuntime,
registerFull(api) {
const httpHandler = createNostrProfileHttpHandler({
getConfigProfile: (accountId: string) => {
const runtime = getNostrRuntime();
@@ -30,23 +23,18 @@ const plugin = {
const runtime = getNostrRuntime();
const cfg = runtime.config.loadConfig();
// Build the config patch for channels.nostr.profile
const channels = (cfg.channels ?? {}) as Record<string, unknown>;
const nostrConfig = (channels.nostr ?? {}) as Record<string, unknown>;
const updatedNostrConfig = {
...nostrConfig,
profile,
};
const updatedChannels = {
...channels,
nostr: updatedNostrConfig,
};
await runtime.config.writeConfigFile({
...cfg,
channels: updatedChannels,
channels: {
...channels,
nostr: {
...nostrConfig,
profile,
},
},
});
},
getAccountInfo: (accountId: string) => {
@@ -71,6 +59,4 @@ const plugin = {
handler: httpHandler,
});
},
};
export default plugin;
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { nostrPlugin } from "./src/channel.js";
export default {
plugin: nostrPlugin,
};
export default defineSetupPluginEntry(nostrPlugin);

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/core";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { signalPlugin } from "./src/channel.js";
import { setSignalRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "signal",
name: "Signal",
description: "Signal channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setSignalRuntime(api.runtime);
api.registerChannel({ plugin: signalPlugin });
},
};
export default plugin;
plugin: signalPlugin,
setRuntime: setSignalRuntime,
});

View File

@@ -1,3 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { signalSetupPlugin } from "./src/channel.setup.js";
export default { plugin: signalSetupPlugin };
export default defineSetupPluginEntry(signalSetupPlugin);

View File

@@ -1 +1,5 @@
export { signalSetupWizard } from "./setup-surface.js";
import { signalSetupWizard as signalSetupWizardImpl } from "./setup-surface.js";
type SignalSetupWizard = typeof import("./setup-surface.js").signalSetupWizard;
export const signalSetupWizard: SignalSetupWizard = { ...signalSetupWizardImpl };

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/core";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { slackPlugin } from "./src/channel.js";
import { setSlackRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "slack",
name: "Slack",
description: "Slack channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setSlackRuntime(api.runtime);
api.registerChannel({ plugin: slackPlugin });
},
};
export default plugin;
plugin: slackPlugin,
setRuntime: setSlackRuntime,
});

View File

@@ -1,3 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { slackSetupPlugin } from "./src/channel.setup.js";
export default { plugin: slackSetupPlugin };
export default defineSetupPluginEntry(slackSetupPlugin);

View File

@@ -1 +1,5 @@
export { slackSetupWizard } from "./setup-surface.js";
import { slackSetupWizard as slackSetupWizardImpl } from "./setup-surface.js";
type SlackSetupWizard = typeof import("./setup-surface.js").slackSetupWizard;
export const slackSetupWizard: SlackSetupWizard = { ...slackSetupWizardImpl };

View File

@@ -8,10 +8,7 @@ import {
collectOpenProviderGroupPolicyWarnings,
} from "openclaw/plugin-sdk/channel-config-helpers";
import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime";
import {
buildOutboundBaseSessionKey,
normalizeOutboundThreadId,
} from "openclaw/plugin-sdk/core";
import { buildOutboundBaseSessionKey, normalizeOutboundThreadId } from "openclaw/plugin-sdk/core";
import { resolveThreadSessionKeys, type RoutePeer } from "openclaw/plugin-sdk/routing";
import {
buildComputedAccountStatusSnapshot,
@@ -28,6 +25,7 @@ import {
type ChannelPlugin,
type OpenClawConfig,
} from "openclaw/plugin-sdk/slack";
import type { SlackActionContext } from "../../../src/agents/tools/slack-actions.js";
import { createSlackActions } from "../../../src/channels/plugins/slack.actions.js";
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
import {
@@ -489,7 +487,11 @@ export const slackPlugin: ChannelPlugin<ResolvedSlackAccount> = {
},
actions: createSlackActions(SLACK_CHANNEL, {
invoke: async (action, cfg, toolContext) =>
await getSlackRuntime().channel.slack.handleSlackAction(action, cfg, toolContext),
await getSlackRuntime().channel.slack.handleSlackAction(
action,
cfg as OpenClawConfig,
toolContext as SlackActionContext | undefined,
),
}),
setup: slackSetupAdapter,
outbound: {

View File

@@ -4,7 +4,7 @@ import * as mediaFetch from "../../../../src/media/fetch.js";
import type { SavedMedia } from "../../../../src/media/store.js";
import * as mediaStore from "../../../../src/media/store.js";
import { mockPinnedHostnameResolution } from "../../../../src/test-helpers/ssrf.js";
import { type FetchMock, withFetchPreconnect } from "../../../../src/test-utils/fetch-mock.js";
import { type FetchMock, withFetchPreconnect } from "../../../test-utils/fetch-mock.js";
import {
fetchWithSlackAuth,
resolveSlackAttachmentContent,

View File

@@ -130,27 +130,19 @@ async function resolveSlackGroupAllowlist(params: {
return keys;
}
export const slackSetupWizard: ChannelSetupWizard = createSlackSetupWizardBase(async () => ({
slackSetupWizard: {
dmPolicy: {
promptAllowFrom: promptSlackAllowFrom,
},
allowFrom: {
resolveEntries: async ({ credentialValues, entries }) =>
await resolveSlackAllowFromEntries({
token: credentialValues.botToken,
entries,
}),
},
groupAccess: {
resolveAllowlist: async ({ cfg, accountId, credentialValues, entries, prompter }) =>
await resolveSlackGroupAllowlist({
cfg,
accountId,
credentialValues,
entries,
prompter,
}),
},
} as ChannelSetupWizard,
}));
export const slackSetupWizard: ChannelSetupWizard = createSlackSetupWizardBase({
promptAllowFrom: promptSlackAllowFrom,
resolveAllowFromEntries: async ({ credentialValues, entries }) =>
await resolveSlackAllowFromEntries({
token: credentialValues.botToken,
entries,
}),
resolveGroupAllowlist: async ({ cfg, accountId, credentialValues, entries, prompter }) =>
await resolveSlackGroupAllowlist({
cfg,
accountId,
credentialValues,
entries,
prompter,
}),
});

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/synology-chat";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/synology-chat";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { synologyChatPlugin } from "./src/channel.js";
import { setSynologyRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "synology-chat",
name: "Synology Chat",
description: "Native Synology Chat channel plugin for OpenClaw",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setSynologyRuntime(api.runtime);
api.registerChannel({ plugin: synologyChatPlugin });
},
};
export default plugin;
plugin: synologyChatPlugin,
setRuntime: setSynologyRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { synologyChatPlugin } from "./src/channel.js";
export default {
plugin: synologyChatPlugin,
};
export default defineSetupPluginEntry(synologyChatPlugin);

View File

@@ -1,5 +1,5 @@
import { describe, expect, it, vi } from "vitest";
import type { OpenClawPluginCommandDefinition } from "../../src/plugins/types.js";
import type { OpenClawPluginCommandDefinition } from "../test-utils/plugin-command.js";
import { createPluginRuntimeMock } from "../test-utils/plugin-runtime-mock.js";
import register from "./index.js";

View File

@@ -1,17 +1,12 @@
import type { ChannelPlugin, OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/core";
import type { ChannelPlugin } from "openclaw/plugin-sdk/core";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { telegramPlugin } from "./src/channel.js";
import { setTelegramRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "telegram",
name: "Telegram",
description: "Telegram channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setTelegramRuntime(api.runtime);
api.registerChannel({ plugin: telegramPlugin as ChannelPlugin });
},
};
export default plugin;
plugin: telegramPlugin as ChannelPlugin,
setRuntime: setTelegramRuntime,
});

View File

@@ -1,3 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { telegramSetupPlugin } from "./src/channel.setup.js";
export default { plugin: telegramSetupPlugin };
export default defineSetupPluginEntry(telegramSetupPlugin);

View File

@@ -3,7 +3,7 @@ import os from "node:os";
import path from "node:path";
import { describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../../../src/config/config.js";
import { withEnv } from "../../../src/test-utils/env.js";
import { withEnv } from "../../test-utils/env.js";
import { inspectTelegramAccount } from "./account-inspect.js";
describe("inspectTelegramAccount SecretRef resolution", () => {

View File

@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../../src/config/config.js";
import * as subsystemModule from "../../../src/logging/subsystem.js";
import { withEnv } from "../../../src/test-utils/env.js";
import { withEnv } from "../../test-utils/env.js";
import {
listTelegramAccountIds,
resetMissingDefaultWarnFlag,

View File

@@ -2,9 +2,9 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
import { withEnvAsync } from "../../../src/test-utils/env.js";
import { useFrozenTime, useRealTime } from "../../../src/test-utils/frozen-time.js";
import { escapeRegExp, formatEnvelopeTimestamp } from "../../../test/helpers/envelope-timestamp.js";
import { withEnvAsync } from "../../test-utils/env.js";
import { useFrozenTime, useRealTime } from "../../test-utils/frozen-time.js";
import {
answerCallbackQuerySpy,
botCtorSpy,

View File

@@ -1,11 +1,11 @@
import { rm } from "node:fs/promises";
import type { PluginInteractiveTelegramHandlerContext } from "openclaw/plugin-sdk/core";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { expectChannelInboundContextContract as expectInboundContextContract } from "../../../src/channels/plugins/contracts/suites.js";
import {
clearPluginInteractiveHandlers,
registerPluginInteractiveHandler,
} from "../../../src/plugins/interactive.js";
import type { PluginInteractiveTelegramHandlerContext } from "../../../src/plugins/types.js";
import { escapeRegExp, formatEnvelopeTimestamp } from "../../../test/helpers/envelope-timestamp.js";
import {
answerCallbackQuerySpy,

View File

@@ -6,12 +6,9 @@ import {
} from "openclaw/plugin-sdk/channel-config-helpers";
import { type OutboundSendDeps, resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-runtime";
import { normalizeMessageChannel } from "openclaw/plugin-sdk/channel-runtime";
import { buildOutboundBaseSessionKey, normalizeOutboundThreadId } from "openclaw/plugin-sdk/core";
import { resolveExecApprovalCommandDisplay } from "openclaw/plugin-sdk/infra-runtime";
import { buildExecApprovalPendingReplyPayload } from "openclaw/plugin-sdk/infra-runtime";
import {
buildOutboundBaseSessionKey,
normalizeOutboundThreadId,
} from "openclaw/plugin-sdk/core";
import { resolveThreadSessionKeys, type RoutePeer } from "openclaw/plugin-sdk/routing";
import { parseTelegramTopicConversation } from "openclaw/plugin-sdk/telegram";
import {

View File

@@ -1,5 +1,5 @@
import { afterEach, type Mock, describe, expect, it, vi } from "vitest";
import { withFetchPreconnect } from "../../../src/test-utils/fetch-mock.js";
import { withFetchPreconnect } from "../../test-utils/fetch-mock.js";
import { probeTelegram, resetTelegramProbeFetcherCacheForTests } from "./probe.js";
const resolveTelegramFetch = vi.hoisted(() => vi.fn());

View File

@@ -0,0 +1 @@
export { countLines, hasBalancedFences } from "../../src/test-utils/chunk-test-helpers.js";

View File

@@ -0,0 +1 @@
export { captureEnv, withEnv, withEnvAsync } from "../../src/test-utils/env.js";

View File

@@ -0,0 +1 @@
export { withFetchPreconnect, type FetchMock } from "../../src/test-utils/fetch-mock.js";

View File

@@ -0,0 +1 @@
export { useFrozenTime, useRealTime } from "../../src/test-utils/frozen-time.js";

View File

@@ -0,0 +1 @@
export { createMockServerResponse } from "../../src/test-utils/mock-http-response.js";

View File

@@ -0,0 +1 @@
export type { OpenClawPluginCommandDefinition } from "openclaw/plugin-sdk/core";

View File

@@ -0,0 +1 @@
export { registerSingleProviderPlugin } from "../../src/test-utils/plugin-registration.js";

View File

@@ -0,0 +1,4 @@
export {
createProviderUsageFetch,
makeResponse,
} from "../../src/test-utils/provider-usage-fetch.js";

View File

@@ -0,0 +1 @@
export { withTempDir } from "../../src/test-utils/temp-dir.js";

View File

@@ -0,0 +1 @@
export { typedCases } from "../../src/test-utils/typed-cases.js";

View File

@@ -2,14 +2,12 @@ import { spawn } from "node:child_process";
import { existsSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/tlon";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/tlon";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { tlonPlugin } from "./src/channel.js";
import { setTlonRuntime } from "./src/runtime.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
// Whitelist of allowed tlon subcommands
const ALLOWED_TLON_COMMANDS = new Set([
"activity",
"channels",
@@ -24,40 +22,29 @@ const ALLOWED_TLON_COMMANDS = new Set([
"version",
]);
/**
* Find the tlon binary from the skill package
*/
let cachedTlonBinary: string | undefined;
function findTlonBinary(): string {
if (cachedTlonBinary) {
return cachedTlonBinary;
}
// Check in node_modules/.bin
const skillBin = join(__dirname, "node_modules", ".bin", "tlon");
if (existsSync(skillBin)) {
cachedTlonBinary = skillBin;
return skillBin;
}
// Check for platform-specific binary directly
const platform = process.platform;
const arch = process.arch;
const platformPkg = `@tloncorp/tlon-skill-${platform}-${arch}`;
const platformPkg = `@tloncorp/tlon-skill-${process.platform}-${process.arch}`;
const platformBin = join(__dirname, "node_modules", platformPkg, "tlon");
if (existsSync(platformBin)) {
cachedTlonBinary = platformBin;
return platformBin;
}
// Fallback to PATH
cachedTlonBinary = "tlon";
return cachedTlonBinary;
}
/**
* Shell-like argument splitter that respects quotes
*/
function shellSplit(str: string): string[] {
const args: string[] = [];
let cur = "";
@@ -92,18 +79,15 @@ function shellSplit(str: string): string[] {
}
cur += ch;
}
if (cur) args.push(cur);
if (cur) {
args.push(cur);
}
return args;
}
/**
* Run the tlon command and return the result
*/
function runTlonCommand(binary: string, args: string[]): Promise<string> {
return new Promise((resolve, reject) => {
const child = spawn(binary, args, {
env: process.env,
});
const child = spawn(binary, args, { env: process.env });
let stdout = "";
let stderr = "";
@@ -123,25 +107,20 @@ function runTlonCommand(binary: string, args: string[]): Promise<string> {
child.on("close", (code) => {
if (code !== 0) {
reject(new Error(stderr || `tlon exited with code ${code}`));
} else {
resolve(stdout);
return;
}
resolve(stdout);
});
});
}
const plugin = {
export default defineChannelPluginEntry({
id: "tlon",
name: "Tlon",
description: "Tlon/Urbit channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setTlonRuntime(api.runtime);
api.registerChannel({ plugin: tlonPlugin });
if (api.registrationMode !== "full") {
return;
}
plugin: tlonPlugin,
setRuntime: setTlonRuntime,
registerFull(api) {
api.logger.debug?.("[tlon] Registering tlon tool");
api.registerTool({
name: "tlon",
@@ -164,9 +143,6 @@ const plugin = {
async execute(_id: string, params: { command: string }) {
try {
const args = shellSplit(params.command);
const tlonBinary = findTlonBinary();
// Validate first argument is a whitelisted tlon subcommand
const subcommand = args[0];
if (!ALLOWED_TLON_COMMANDS.has(subcommand)) {
return {
@@ -180,7 +156,7 @@ const plugin = {
};
}
const output = await runTlonCommand(tlonBinary, args);
const output = await runTlonCommand(findTlonBinary(), args);
return {
content: [{ type: "text" as const, text: output }],
details: undefined,
@@ -194,6 +170,4 @@ const plugin = {
},
});
},
};
export default plugin;
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { tlonPlugin } from "./src/channel.js";
export default {
plugin: tlonPlugin,
};
export default defineSetupPluginEntry(tlonPlugin);

View File

@@ -1,20 +1,13 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/twitch";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/twitch";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { twitchPlugin } from "./src/plugin.js";
import { setTwitchRuntime } from "./src/runtime.js";
export { monitorTwitchProvider } from "./src/monitor.js";
const plugin = {
export default defineChannelPluginEntry({
id: "twitch",
name: "Twitch",
description: "Twitch channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setTwitchRuntime(api.runtime);
// oxlint-disable-next-line typescript/no-explicit-any
api.registerChannel({ plugin: twitchPlugin as any });
},
};
export default plugin;
description: "Twitch chat channel plugin",
plugin: twitchPlugin,
setRuntime: setTwitchRuntime,
});

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/core";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { whatsappPlugin } from "./src/channel.js";
import { setWhatsAppRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "whatsapp",
name: "WhatsApp",
description: "WhatsApp channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setWhatsAppRuntime(api.runtime);
api.registerChannel({ plugin: whatsappPlugin });
},
};
export default plugin;
plugin: whatsappPlugin,
setRuntime: setWhatsAppRuntime,
});

View File

@@ -1,3 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { whatsappSetupPlugin } from "./src/channel.setup.js";
export default { plugin: whatsappSetupPlugin };
export default defineSetupPluginEntry(whatsappSetupPlugin);

View File

@@ -2,7 +2,7 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { captureEnv } from "../../../src/test-utils/env.js";
import { captureEnv } from "../../test-utils/env.js";
import { hasAnyWhatsAppAuth, listWhatsAppAuthDirs } from "./accounts.js";
describe("hasAnyWhatsAppAuth", () => {

View File

@@ -4,8 +4,8 @@ import fs from "node:fs/promises";
import { beforeAll, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../../../src/config/config.js";
import { setLoggerOverride } from "../../../src/logging.js";
import { withEnvAsync } from "../../../src/test-utils/env.js";
import { escapeRegExp, formatEnvelopeTimestamp } from "../../../test/helpers/envelope-timestamp.js";
import { withEnvAsync } from "../../test-utils/env.js";
import {
createMockWebListener,
createWebListenerFactoryCapture,

View File

@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
import path from "node:path";
import { describe, expect, it, vi } from "vitest";
import { saveSessionStore } from "../../../../src/config/sessions.js";
import { withTempDir } from "../../../../src/test-utils/temp-dir.js";
import { withTempDir } from "../../../test-utils/temp-dir.js";
import {
debugMention,
isBotMentionedFromTargets,

View File

@@ -1,18 +1,73 @@
export { getActiveWebListener } from "./active-listener.js";
export {
getWebAuthAgeMs,
logWebSelfId,
logoutWeb,
readWebSelfId,
webAuthExists,
} from "./auth-store.js";
export { loginWeb } from "./login.js";
export { startWebLoginWithQr, waitForWebLogin } from "./login-qr.js";
export { whatsappSetupWizard } from "./setup-surface.js";
import { monitorWebChannel as monitorWebChannelImpl } from "openclaw/plugin-sdk/whatsapp";
import { getActiveWebListener as getActiveWebListenerImpl } from "./active-listener.js";
import {
getWebAuthAgeMs as getWebAuthAgeMsImpl,
logWebSelfId as logWebSelfIdImpl,
logoutWeb as logoutWebImpl,
readWebSelfId as readWebSelfIdImpl,
webAuthExists as webAuthExistsImpl,
} from "./auth-store.js";
import {
startWebLoginWithQr as startWebLoginWithQrImpl,
waitForWebLogin as waitForWebLoginImpl,
} from "./login-qr.js";
import { loginWeb as loginWebImpl } from "./login.js";
import { whatsappSetupWizard as whatsappSetupWizardImpl } from "./setup-surface.js";
type GetActiveWebListener = typeof import("./active-listener.js").getActiveWebListener;
type GetWebAuthAgeMs = typeof import("./auth-store.js").getWebAuthAgeMs;
type LogWebSelfId = typeof import("./auth-store.js").logWebSelfId;
type LogoutWeb = typeof import("./auth-store.js").logoutWeb;
type ReadWebSelfId = typeof import("./auth-store.js").readWebSelfId;
type WebAuthExists = typeof import("./auth-store.js").webAuthExists;
type LoginWeb = typeof import("./login.js").loginWeb;
type StartWebLoginWithQr = typeof import("./login-qr.js").startWebLoginWithQr;
type WaitForWebLogin = typeof import("./login-qr.js").waitForWebLogin;
type WhatsAppSetupWizard = typeof import("./setup-surface.js").whatsappSetupWizard;
type MonitorWebChannel = typeof import("openclaw/plugin-sdk/whatsapp").monitorWebChannel;
export function getActiveWebListener(
...args: Parameters<GetActiveWebListener>
): ReturnType<GetActiveWebListener> {
return getActiveWebListenerImpl(...args);
}
export function getWebAuthAgeMs(...args: Parameters<GetWebAuthAgeMs>): ReturnType<GetWebAuthAgeMs> {
return getWebAuthAgeMsImpl(...args);
}
export function logWebSelfId(...args: Parameters<LogWebSelfId>): ReturnType<LogWebSelfId> {
return logWebSelfIdImpl(...args);
}
export function logoutWeb(...args: Parameters<LogoutWeb>): ReturnType<LogoutWeb> {
return logoutWebImpl(...args);
}
export function readWebSelfId(...args: Parameters<ReadWebSelfId>): ReturnType<ReadWebSelfId> {
return readWebSelfIdImpl(...args);
}
export function webAuthExists(...args: Parameters<WebAuthExists>): ReturnType<WebAuthExists> {
return webAuthExistsImpl(...args);
}
export function loginWeb(...args: Parameters<LoginWeb>): ReturnType<LoginWeb> {
return loginWebImpl(...args);
}
export function startWebLoginWithQr(
...args: Parameters<StartWebLoginWithQr>
): ReturnType<StartWebLoginWithQr> {
return startWebLoginWithQrImpl(...args);
}
export function waitForWebLogin(...args: Parameters<WaitForWebLogin>): ReturnType<WaitForWebLogin> {
return waitForWebLoginImpl(...args);
}
export const whatsappSetupWizard: WhatsAppSetupWizard = { ...whatsappSetupWizardImpl };
export async function monitorWebChannel(
...args: Parameters<MonitorWebChannel>
): ReturnType<MonitorWebChannel> {

View File

@@ -7,8 +7,8 @@ import { resolveStateDir } from "../../../src/config/paths.js";
import { resolvePreferredOpenClawTmpDir } from "../../../src/infra/tmp-openclaw-dir.js";
import { optimizeImageToPng } from "../../../src/media/image-ops.js";
import { mockPinnedHostnameResolution } from "../../../src/test-helpers/ssrf.js";
import { captureEnv } from "../../../src/test-utils/env.js";
import { sendVoiceMessageDiscord } from "../../discord/src/send.js";
import { captureEnv } from "../../test-utils/env.js";
import {
LocalMediaAccessError,
loadWebMedia,

View File

@@ -1,17 +1,11 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/zalo";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/zalo";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import { zaloPlugin } from "./src/channel.js";
import { setZaloRuntime } from "./src/runtime.js";
const plugin = {
export default defineChannelPluginEntry({
id: "zalo",
name: "Zalo",
description: "Zalo channel plugin (Bot API)",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setZaloRuntime(api.runtime);
api.registerChannel(zaloPlugin);
},
};
export default plugin;
description: "Zalo channel plugin",
plugin: zaloPlugin,
setRuntime: setZaloRuntime,
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { zaloPlugin } from "./src/channel.js";
export default {
plugin: zaloPlugin,
};
export default defineSetupPluginEntry(zaloPlugin);

View File

@@ -1 +1,7 @@
export { sendMessageZalo } from "./send.js";
import { sendMessageZalo as sendMessageZaloImpl } from "./send.js";
type SendMessageZalo = typeof import("./send.js").sendMessageZalo;
export function sendMessageZalo(...args: Parameters<SendMessageZalo>): ReturnType<SendMessageZalo> {
return sendMessageZaloImpl(...args);
}

View File

@@ -1,21 +1,16 @@
import type { AnyAgentTool, OpenClawPluginApi } from "openclaw/plugin-sdk/zalouser";
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/zalouser";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
import type { AnyAgentTool } from "openclaw/plugin-sdk/zalouser";
import { zalouserPlugin } from "./src/channel.js";
import { setZalouserRuntime } from "./src/runtime.js";
import { ZalouserToolSchema, executeZalouserTool } from "./src/tool.js";
const plugin = {
export default defineChannelPluginEntry({
id: "zalouser",
name: "Zalo Personal",
description: "Zalo personal account messaging via native zca-js integration",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
setZalouserRuntime(api.runtime);
api.registerChannel(zalouserPlugin);
if (api.registrationMode !== "full") {
return;
}
plugin: zalouserPlugin,
setRuntime: setZalouserRuntime,
registerFull(api) {
api.registerTool({
name: "zalouser",
label: "Zalo Personal",
@@ -27,6 +22,4 @@ const plugin = {
execute: executeZalouserTool,
} as AnyAgentTool);
},
};
export default plugin;
});

View File

@@ -1,5 +1,4 @@
import { defineSetupPluginEntry } from "openclaw/plugin-sdk/core";
import { zalouserPlugin } from "./src/channel.js";
export default {
plugin: zalouserPlugin,
};
export default defineSetupPluginEntry(zalouserPlugin);