refactor: rename clawdbot to moltbot with legacy compat

This commit is contained in:
Peter Steinberger
2026-01-27 12:19:58 +00:00
parent 83460df96f
commit 6d16a658e5
1839 changed files with 11250 additions and 11199 deletions

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { MoltbotConfig } from "clawdbot/plugin-sdk";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "clawdbot/plugin-sdk";
import { normalizeBlueBubblesServerUrl, type BlueBubblesAccountConfig } from "./types.js";
@@ -11,26 +11,26 @@ export type ResolvedBlueBubblesAccount = {
baseUrl?: string;
};
function listConfiguredAccountIds(cfg: ClawdbotConfig): string[] {
function listConfiguredAccountIds(cfg: MoltbotConfig): string[] {
const accounts = cfg.channels?.bluebubbles?.accounts;
if (!accounts || typeof accounts !== "object") return [];
return Object.keys(accounts).filter(Boolean);
}
export function listBlueBubblesAccountIds(cfg: ClawdbotConfig): string[] {
export function listBlueBubblesAccountIds(cfg: MoltbotConfig): string[] {
const ids = listConfiguredAccountIds(cfg);
if (ids.length === 0) return [DEFAULT_ACCOUNT_ID];
return ids.sort((a, b) => a.localeCompare(b));
}
export function resolveDefaultBlueBubblesAccountId(cfg: ClawdbotConfig): string {
export function resolveDefaultBlueBubblesAccountId(cfg: MoltbotConfig): string {
const ids = listBlueBubblesAccountIds(cfg);
if (ids.includes(DEFAULT_ACCOUNT_ID)) return DEFAULT_ACCOUNT_ID;
return ids[0] ?? DEFAULT_ACCOUNT_ID;
}
function resolveAccountConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
accountId: string,
): BlueBubblesAccountConfig | undefined {
const accounts = cfg.channels?.bluebubbles?.accounts;
@@ -39,7 +39,7 @@ function resolveAccountConfig(
}
function mergeBlueBubblesAccountConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
accountId: string,
): BlueBubblesAccountConfig {
const base = (cfg.channels?.bluebubbles ?? {}) as BlueBubblesAccountConfig & {
@@ -52,7 +52,7 @@ function mergeBlueBubblesAccountConfig(
}
export function resolveBlueBubblesAccount(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
accountId?: string | null;
}): ResolvedBlueBubblesAccount {
const accountId = normalizeAccountId(params.accountId);
@@ -73,7 +73,7 @@ export function resolveBlueBubblesAccount(params: {
};
}
export function listEnabledBlueBubblesAccounts(cfg: ClawdbotConfig): ResolvedBlueBubblesAccount[] {
export function listEnabledBlueBubblesAccounts(cfg: MoltbotConfig): ResolvedBlueBubblesAccount[] {
return listBlueBubblesAccountIds(cfg)
.map((accountId) => resolveBlueBubblesAccount({ cfg, accountId }))
.filter((account) => account.enabled);

View File

@@ -1,7 +1,7 @@
import { describe, expect, it, vi, beforeEach } from "vitest";
import { bluebubblesMessageActions } from "./actions.js";
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { MoltbotConfig } from "clawdbot/plugin-sdk";
vi.mock("./accounts.js", () => ({
resolveBlueBubblesAccount: vi.fn(({ cfg, accountId }) => {
@@ -49,7 +49,7 @@ describe("bluebubblesMessageActions", () => {
describe("listActions", () => {
it("returns empty array when account is not enabled", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: { bluebubbles: { enabled: false } },
};
const actions = bluebubblesMessageActions.listActions({ cfg });
@@ -57,7 +57,7 @@ describe("bluebubblesMessageActions", () => {
});
it("returns empty array when account is not configured", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: { bluebubbles: { enabled: true } },
};
const actions = bluebubblesMessageActions.listActions({ cfg });
@@ -65,7 +65,7 @@ describe("bluebubblesMessageActions", () => {
});
it("returns react action when enabled and configured", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
enabled: true,
@@ -79,7 +79,7 @@ describe("bluebubblesMessageActions", () => {
});
it("excludes react action when reactions are gated off", () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
enabled: true,
@@ -153,7 +153,7 @@ describe("bluebubblesMessageActions", () => {
describe("handleAction", () => {
it("throws for unsupported actions", async () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -172,7 +172,7 @@ describe("bluebubblesMessageActions", () => {
});
it("throws when emoji is missing for react action", async () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -191,7 +191,7 @@ describe("bluebubblesMessageActions", () => {
});
it("throws when messageId is missing", async () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -213,7 +213,7 @@ describe("bluebubblesMessageActions", () => {
const { resolveChatGuidForTarget } = await import("./send.js");
vi.mocked(resolveChatGuidForTarget).mockResolvedValueOnce(null);
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -234,7 +234,7 @@ describe("bluebubblesMessageActions", () => {
it("sends reaction successfully with chatGuid", async () => {
const { sendBlueBubblesReaction } = await import("./reactions.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -269,7 +269,7 @@ describe("bluebubblesMessageActions", () => {
it("sends reaction removal successfully", async () => {
const { sendBlueBubblesReaction } = await import("./reactions.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -305,7 +305,7 @@ describe("bluebubblesMessageActions", () => {
const { resolveChatGuidForTarget } = await import("./send.js");
vi.mocked(resolveChatGuidForTarget).mockResolvedValueOnce("iMessage;-;+15559876543");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -335,7 +335,7 @@ describe("bluebubblesMessageActions", () => {
it("passes partIndex when provided", async () => {
const { sendBlueBubblesReaction } = await import("./reactions.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -367,7 +367,7 @@ describe("bluebubblesMessageActions", () => {
const { resolveChatGuidForTarget } = await import("./send.js");
vi.mocked(resolveChatGuidForTarget).mockResolvedValueOnce("iMessage;-;+15550001111");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -405,7 +405,7 @@ describe("bluebubblesMessageActions", () => {
const { sendBlueBubblesReaction } = await import("./reactions.js");
vi.mocked(resolveBlueBubblesMessageId).mockReturnValueOnce("resolved-uuid");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -439,7 +439,7 @@ describe("bluebubblesMessageActions", () => {
throw new Error("short id expired");
});
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -465,7 +465,7 @@ describe("bluebubblesMessageActions", () => {
it("accepts message param for edit action", async () => {
const { editBlueBubblesMessage } = await import("./chat.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -491,7 +491,7 @@ describe("bluebubblesMessageActions", () => {
it("accepts message/target aliases for sendWithEffect", async () => {
const { sendMessageBlueBubbles } = await import("./send.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -524,7 +524,7 @@ describe("bluebubblesMessageActions", () => {
it("passes asVoice through sendAttachment", async () => {
const { sendBlueBubblesAttachment } = await import("./attachments.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -558,7 +558,7 @@ describe("bluebubblesMessageActions", () => {
});
it("throws when buffer is missing for setGroupIcon", async () => {
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -580,7 +580,7 @@ describe("bluebubblesMessageActions", () => {
it("sets group icon successfully with chatGuid and buffer", async () => {
const { setGroupIconBlueBubbles } = await import("./chat.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",
@@ -619,7 +619,7 @@ describe("bluebubblesMessageActions", () => {
it("uses default filename when not provided for setGroupIcon", async () => {
const { setGroupIconBlueBubbles } = await import("./chat.js");
const cfg: ClawdbotConfig = {
const cfg: MoltbotConfig = {
channels: {
bluebubbles: {
serverUrl: "http://localhost:1234",

View File

@@ -9,7 +9,7 @@ import {
type ChannelMessageActionAdapter,
type ChannelMessageActionName,
type ChannelToolSend,
type ClawdbotConfig,
type MoltbotConfig,
} from "clawdbot/plugin-sdk";
import { resolveBlueBubblesAccount } from "./accounts.js";
@@ -66,9 +66,9 @@ const SUPPORTED_ACTIONS = new Set<ChannelMessageActionName>(BLUEBUBBLES_ACTION_N
export const bluebubblesMessageActions: ChannelMessageActionAdapter = {
listActions: ({ cfg }) => {
const account = resolveBlueBubblesAccount({ cfg: cfg as ClawdbotConfig });
const account = resolveBlueBubblesAccount({ cfg: cfg as MoltbotConfig });
if (!account.enabled || !account.configured) return [];
const gate = createActionGate((cfg as ClawdbotConfig).channels?.bluebubbles?.actions);
const gate = createActionGate((cfg as MoltbotConfig).channels?.bluebubbles?.actions);
const actions = new Set<ChannelMessageActionName>();
const macOS26 = isMacOS26OrHigher(account.accountId);
for (const action of BLUEBUBBLES_ACTION_NAMES) {
@@ -90,12 +90,12 @@ export const bluebubblesMessageActions: ChannelMessageActionAdapter = {
},
handleAction: async ({ action, params, cfg, accountId, toolContext }) => {
const account = resolveBlueBubblesAccount({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId: accountId ?? undefined,
});
const baseUrl = account.config.serverUrl?.trim();
const password = account.config.password?.trim();
const opts = { cfg: cfg as ClawdbotConfig, accountId: accountId ?? undefined };
const opts = { cfg: cfg as MoltbotConfig, accountId: accountId ?? undefined };
// Helper to resolve chatGuid from various params or session context
const resolveChatGuid = async (): Promise<string> => {

View File

@@ -1,6 +1,6 @@
import crypto from "node:crypto";
import path from "node:path";
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { MoltbotConfig } from "clawdbot/plugin-sdk";
import { resolveBlueBubblesAccount } from "./accounts.js";
import { resolveChatGuidForTarget } from "./send.js";
import { parseBlueBubblesTarget, normalizeBlueBubblesHandle } from "./targets.js";
@@ -16,7 +16,7 @@ export type BlueBubblesAttachmentOpts = {
password?: string;
accountId?: string;
timeoutMs?: number;
cfg?: ClawdbotConfig;
cfg?: MoltbotConfig;
};
const DEFAULT_ATTACHMENT_MAX_BYTES = 8 * 1024 * 1024;

View File

@@ -1,4 +1,4 @@
import type { ChannelAccountSnapshot, ChannelPlugin, ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { ChannelAccountSnapshot, ChannelPlugin, MoltbotConfig } from "clawdbot/plugin-sdk";
import {
applyAccountNameToChannelSection,
buildChannelConfigSchema,
@@ -78,13 +78,13 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
configSchema: buildChannelConfigSchema(BlueBubblesConfigSchema),
onboarding: blueBubblesOnboardingAdapter,
config: {
listAccountIds: (cfg) => listBlueBubblesAccountIds(cfg as ClawdbotConfig),
listAccountIds: (cfg) => listBlueBubblesAccountIds(cfg as MoltbotConfig),
resolveAccount: (cfg, accountId) =>
resolveBlueBubblesAccount({ cfg: cfg as ClawdbotConfig, accountId }),
defaultAccountId: (cfg) => resolveDefaultBlueBubblesAccountId(cfg as ClawdbotConfig),
resolveBlueBubblesAccount({ cfg: cfg as MoltbotConfig, accountId }),
defaultAccountId: (cfg) => resolveDefaultBlueBubblesAccountId(cfg as MoltbotConfig),
setAccountEnabled: ({ cfg, accountId, enabled }) =>
setAccountEnabledInConfigSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
sectionKey: "bluebubbles",
accountId,
enabled,
@@ -92,7 +92,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
}),
deleteAccount: ({ cfg, accountId }) =>
deleteAccountFromConfigSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
sectionKey: "bluebubbles",
accountId,
clearBaseFields: ["serverUrl", "password", "name", "webhookPath"],
@@ -106,7 +106,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
baseUrl: account.baseUrl,
}),
resolveAllowFrom: ({ cfg, accountId }) =>
(resolveBlueBubblesAccount({ cfg: cfg as ClawdbotConfig, accountId }).config.allowFrom ??
(resolveBlueBubblesAccount({ cfg: cfg as MoltbotConfig, accountId }).config.allowFrom ??
[]).map(
(entry) => String(entry),
),
@@ -122,7 +122,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
resolveDmPolicy: ({ cfg, accountId, account }) => {
const resolvedAccountId = accountId ?? account.accountId ?? DEFAULT_ACCOUNT_ID;
const useAccountPath = Boolean(
(cfg as ClawdbotConfig).channels?.bluebubbles?.accounts?.[resolvedAccountId],
(cfg as MoltbotConfig).channels?.bluebubbles?.accounts?.[resolvedAccountId],
);
const basePath = useAccountPath
? `channels.bluebubbles.accounts.${resolvedAccountId}.`
@@ -207,7 +207,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
applyAccountName: ({ cfg, accountId, name }) =>
applyAccountNameToChannelSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
channelKey: "bluebubbles",
accountId,
name,
@@ -222,7 +222,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
},
applyAccountConfig: ({ cfg, accountId, input }) => {
const namedConfig = applyAccountNameToChannelSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
channelKey: "bluebubbles",
accountId,
name: input.name,
@@ -247,7 +247,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
...(input.webhookPath ? { webhookPath: input.webhookPath } : {}),
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
}
return {
...next,
@@ -268,7 +268,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
},
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
},
},
pairing: {
@@ -276,7 +276,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
normalizeAllowEntry: (entry) => normalizeBlueBubblesHandle(entry.replace(/^bluebubbles:/i, "")),
notifyApproval: async ({ cfg, id }) => {
await sendMessageBlueBubbles(id, PAIRING_APPROVED_MESSAGE, {
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
});
},
},
@@ -300,7 +300,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
? resolveBlueBubblesMessageId(rawReplyToId, { requireKnownShortId: true })
: "";
const result = await sendMessageBlueBubbles(to, text, {
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId: accountId ?? undefined,
replyToMessageGuid: replyToMessageGuid || undefined,
});
@@ -317,7 +317,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
};
const resolvedCaption = caption ?? text;
const result = await sendBlueBubblesMedia({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
to,
mediaUrl,
mediaPath,
@@ -388,7 +388,7 @@ export const bluebubblesPlugin: ChannelPlugin<ResolvedBlueBubblesAccount> = {
ctx.log?.info(`[${account.accountId}] starting provider (webhook=${webhookPath})`);
return monitorBlueBubblesProvider({
account,
config: ctx.cfg as ClawdbotConfig,
config: ctx.cfg as MoltbotConfig,
runtime: ctx.runtime,
abortSignal: ctx.abortSignal,
statusSink: (patch) => ctx.setStatus({ accountId: ctx.accountId, ...patch }),

View File

@@ -1,6 +1,6 @@
import crypto from "node:crypto";
import { resolveBlueBubblesAccount } from "./accounts.js";
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { MoltbotConfig } from "clawdbot/plugin-sdk";
import { blueBubblesFetchWithTimeout, buildBlueBubblesApiUrl } from "./types.js";
export type BlueBubblesChatOpts = {
@@ -8,7 +8,7 @@ export type BlueBubblesChatOpts = {
password?: string;
accountId?: string;
timeoutMs?: number;
cfg?: ClawdbotConfig;
cfg?: MoltbotConfig;
};
function resolveAccount(params: BlueBubblesChatOpts) {

View File

@@ -1,7 +1,7 @@
import path from "node:path";
import { fileURLToPath } from "node:url";
import { resolveChannelMediaMaxBytes, type ClawdbotConfig } from "clawdbot/plugin-sdk";
import { resolveChannelMediaMaxBytes, type MoltbotConfig } from "clawdbot/plugin-sdk";
import { sendBlueBubblesAttachment } from "./attachments.js";
import { resolveBlueBubblesMessageId } from "./monitor.js";
@@ -49,7 +49,7 @@ function resolveFilenameFromSource(source?: string): string | undefined {
}
export async function sendBlueBubblesMedia(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
to: string;
mediaUrl?: string;
mediaPath?: string;

View File

@@ -3,7 +3,7 @@ import type { IncomingMessage, ServerResponse } from "node:http";
import { EventEmitter } from "node:events";
import { removeAckReactionAfterReply, shouldAckReaction } from "clawdbot/plugin-sdk";
import type { ClawdbotConfig, PluginRuntime } from "clawdbot/plugin-sdk";
import type { MoltbotConfig, PluginRuntime } from "clawdbot/plugin-sdk";
import {
handleBlueBubblesWebhookRequest,
registerBlueBubblesWebhookTarget,
@@ -178,7 +178,7 @@ function createMockRuntime(): PluginRuntime {
})) as unknown as PluginRuntime["logging"]["getChildLogger"],
},
state: {
resolveStateDir: vi.fn(() => "/tmp/clawdbot") as unknown as PluginRuntime["state"]["resolveStateDir"],
resolveStateDir: vi.fn(() => "/tmp/moltbot") as unknown as PluginRuntime["state"]["resolveStateDir"],
},
};
}
@@ -264,7 +264,7 @@ describe("BlueBubbles webhook monitor", () => {
describe("webhook parsing + auth handling", () => {
it("rejects non-POST requests", async () => {
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -287,7 +287,7 @@ describe("BlueBubbles webhook monitor", () => {
it("accepts POST requests with valid JSON payload", async () => {
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -323,7 +323,7 @@ describe("BlueBubbles webhook monitor", () => {
it("rejects requests with invalid JSON", async () => {
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -346,7 +346,7 @@ describe("BlueBubbles webhook monitor", () => {
it("authenticates via password query parameter", async () => {
const account = createMockAccount({ password: "secret-token" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -380,7 +380,7 @@ describe("BlueBubbles webhook monitor", () => {
it("authenticates via x-password header", async () => {
const account = createMockAccount({ password: "secret-token" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -418,7 +418,7 @@ describe("BlueBubbles webhook monitor", () => {
it("rejects unauthorized requests with wrong password", async () => {
const account = createMockAccount({ password: "secret-token" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -451,7 +451,7 @@ describe("BlueBubbles webhook monitor", () => {
it("allows localhost requests without authentication", async () => {
const account = createMockAccount({ password: "secret-token" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -497,7 +497,7 @@ describe("BlueBubbles webhook monitor", () => {
vi.mocked(resolveChatGuidForTarget).mockClear();
const account = createMockAccount({ groupPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -545,7 +545,7 @@ describe("BlueBubbles webhook monitor", () => {
});
const account = createMockAccount({ groupPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -591,7 +591,7 @@ describe("BlueBubbles webhook monitor", () => {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -632,7 +632,7 @@ describe("BlueBubbles webhook monitor", () => {
dmPolicy: "allowlist",
allowFrom: ["+15559999999"], // Different number
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -673,7 +673,7 @@ describe("BlueBubbles webhook monitor", () => {
dmPolicy: "pairing",
allowFrom: ["+15559999999"], // Different number than sender
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -716,7 +716,7 @@ describe("BlueBubbles webhook monitor", () => {
dmPolicy: "pairing",
allowFrom: ["+15559999999"], // Different number than sender
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -757,7 +757,7 @@ describe("BlueBubbles webhook monitor", () => {
dmPolicy: "open",
allowFrom: [],
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -794,7 +794,7 @@ describe("BlueBubbles webhook monitor", () => {
const account = createMockAccount({
dmPolicy: "disabled",
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -833,7 +833,7 @@ describe("BlueBubbles webhook monitor", () => {
const account = createMockAccount({
groupPolicy: "open",
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -871,7 +871,7 @@ describe("BlueBubbles webhook monitor", () => {
const account = createMockAccount({
groupPolicy: "disabled",
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -910,7 +910,7 @@ describe("BlueBubbles webhook monitor", () => {
groupPolicy: "allowlist",
dmPolicy: "open",
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -949,7 +949,7 @@ describe("BlueBubbles webhook monitor", () => {
groupPolicy: "allowlist",
groupAllowFrom: ["chat_guid:iMessage;+;chat123456"],
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -990,7 +990,7 @@ describe("BlueBubbles webhook monitor", () => {
mockMatchesMentionPatterns.mockReturnValue(true);
const account = createMockAccount({ groupPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1031,7 +1031,7 @@ describe("BlueBubbles webhook monitor", () => {
mockMatchesMentionPatterns.mockReturnValue(false);
const account = createMockAccount({ groupPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1069,7 +1069,7 @@ describe("BlueBubbles webhook monitor", () => {
mockResolveRequireMention.mockReturnValue(false);
const account = createMockAccount({ groupPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1107,7 +1107,7 @@ describe("BlueBubbles webhook monitor", () => {
describe("group metadata", () => {
it("includes group subject + members in ctx", async () => {
const account = createMockAccount({ groupPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1153,7 +1153,7 @@ describe("BlueBubbles webhook monitor", () => {
describe("reply metadata", () => {
it("surfaces reply fields in ctx when provided", async () => {
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1201,7 +1201,7 @@ describe("BlueBubbles webhook monitor", () => {
it("preserves part index prefixes in reply tags when short IDs are unavailable", async () => {
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1246,7 +1246,7 @@ describe("BlueBubbles webhook monitor", () => {
it("hydrates missing reply sender/body from the recent-message cache", async () => {
const account = createMockAccount({ dmPolicy: "open", groupPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1316,7 +1316,7 @@ describe("BlueBubbles webhook monitor", () => {
it("falls back to threadOriginatorGuid when reply metadata is absent", async () => {
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1357,7 +1357,7 @@ describe("BlueBubbles webhook monitor", () => {
describe("tapback text parsing", () => {
it("does not rewrite tapback-like text without metadata", async () => {
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1397,7 +1397,7 @@ describe("BlueBubbles webhook monitor", () => {
it("parses tapback text with custom emoji when metadata is present", async () => {
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1442,7 +1442,7 @@ describe("BlueBubbles webhook monitor", () => {
vi.mocked(sendBlueBubblesReaction).mockClear();
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {
const config: MoltbotConfig = {
messages: {
ackReaction: "❤️",
ackReactionScope: "direct",
@@ -1500,7 +1500,7 @@ describe("BlueBubbles webhook monitor", () => {
groupPolicy: "open",
allowFrom: ["+15551234567"],
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1543,7 +1543,7 @@ describe("BlueBubbles webhook monitor", () => {
groupPolicy: "open",
allowFrom: [], // No one authorized
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1586,7 +1586,7 @@ describe("BlueBubbles webhook monitor", () => {
const account = createMockAccount({
sendReadReceipts: true,
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1627,7 +1627,7 @@ describe("BlueBubbles webhook monitor", () => {
const account = createMockAccount({
sendReadReceipts: false,
});
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1666,7 +1666,7 @@ describe("BlueBubbles webhook monitor", () => {
vi.mocked(sendBlueBubblesTyping).mockClear();
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1714,7 +1714,7 @@ describe("BlueBubbles webhook monitor", () => {
vi.mocked(sendBlueBubblesTyping).mockClear();
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1763,7 +1763,7 @@ describe("BlueBubbles webhook monitor", () => {
vi.mocked(sendBlueBubblesTyping).mockClear();
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1813,7 +1813,7 @@ describe("BlueBubbles webhook monitor", () => {
});
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1859,7 +1859,7 @@ describe("BlueBubbles webhook monitor", () => {
mockEnqueueSystemEvent.mockClear();
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1899,7 +1899,7 @@ describe("BlueBubbles webhook monitor", () => {
mockEnqueueSystemEvent.mockClear();
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1939,7 +1939,7 @@ describe("BlueBubbles webhook monitor", () => {
mockEnqueueSystemEvent.mockClear();
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -1976,7 +1976,7 @@ describe("BlueBubbles webhook monitor", () => {
mockEnqueueSystemEvent.mockClear();
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -2017,7 +2017,7 @@ describe("BlueBubbles webhook monitor", () => {
describe("short message ID mapping", () => {
it("assigns sequential short IDs to messages", async () => {
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -2057,7 +2057,7 @@ describe("BlueBubbles webhook monitor", () => {
it("resolves short ID back to UUID", async () => {
const account = createMockAccount({ dmPolicy: "open" });
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);
@@ -2110,7 +2110,7 @@ describe("BlueBubbles webhook monitor", () => {
describe("fromMe messages", () => {
it("ignores messages from self (fromMe=true)", async () => {
const account = createMockAccount();
const config: ClawdbotConfig = {};
const config: MoltbotConfig = {};
const core = createMockRuntime();
setBlueBubblesRuntime(core);

View File

@@ -1,6 +1,6 @@
import type { IncomingMessage, ServerResponse } from "node:http";
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { MoltbotConfig } from "clawdbot/plugin-sdk";
import {
logAckFailure,
logInboundDrop,
@@ -26,7 +26,7 @@ export type BlueBubblesRuntimeEnv = {
export type BlueBubblesMonitorOptions = {
account: ResolvedBlueBubblesAccount;
config: ClawdbotConfig;
config: MoltbotConfig;
runtime: BlueBubblesRuntimeEnv;
abortSignal: AbortSignal;
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
@@ -243,7 +243,7 @@ function logGroupAllowlistHint(params: {
type WebhookTarget = {
account: ResolvedBlueBubblesAccount;
config: ClawdbotConfig;
config: MoltbotConfig;
runtime: BlueBubblesRuntimeEnv;
core: BlueBubblesCoreRuntime;
path: string;
@@ -340,7 +340,7 @@ const targetDebouncers = new Map<
>();
function resolveBlueBubblesDebounceMs(
config: ClawdbotConfig,
config: MoltbotConfig,
core: BlueBubblesCoreRuntime,
): number {
const inbound = config.messages?.inbound;
@@ -940,7 +940,7 @@ function maskSecret(value: string): string {
}
function resolveBlueBubblesAckReaction(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
agentId: string;
core: BlueBubblesCoreRuntime;
runtime: BlueBubblesRuntimeEnv;

View File

@@ -1,7 +1,7 @@
import type {
ChannelOnboardingAdapter,
ChannelOnboardingDmPolicy,
ClawdbotConfig,
MoltbotConfig,
DmPolicy,
WizardPrompter,
} from "clawdbot/plugin-sdk";
@@ -22,7 +22,7 @@ import { parseBlueBubblesAllowTarget, normalizeBlueBubblesHandle } from "./targe
const channel = "bluebubbles" as const;
function setBlueBubblesDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy): ClawdbotConfig {
function setBlueBubblesDmPolicy(cfg: MoltbotConfig, dmPolicy: DmPolicy): MoltbotConfig {
const allowFrom =
dmPolicy === "open" ? addWildcardAllowFrom(cfg.channels?.bluebubbles?.allowFrom) : undefined;
return {
@@ -39,10 +39,10 @@ function setBlueBubblesDmPolicy(cfg: ClawdbotConfig, dmPolicy: DmPolicy): Clawdb
}
function setBlueBubblesAllowFrom(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
accountId: string,
allowFrom: string[],
): ClawdbotConfig {
): MoltbotConfig {
if (accountId === DEFAULT_ACCOUNT_ID) {
return {
...cfg,
@@ -81,10 +81,10 @@ function parseBlueBubblesAllowFromInput(raw: string): string[] {
}
async function promptBlueBubblesAllowFrom(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
prompter: WizardPrompter;
accountId?: string;
}): Promise<ClawdbotConfig> {
}): Promise<MoltbotConfig> {
const accountId =
params.accountId && normalizeAccountId(params.accountId)
? (normalizeAccountId(params.accountId) ?? DEFAULT_ACCOUNT_ID)
@@ -318,7 +318,7 @@ export const blueBubblesOnboardingAdapter: ChannelOnboardingAdapter = {
[
"Configure the webhook URL in BlueBubbles Server:",
"1. Open BlueBubbles Server → Settings → Webhooks",
"2. Add your Clawdbot gateway URL + webhook path",
"2. Add your Moltbot gateway URL + webhook path",
" Example: https://your-gateway-host:3000/bluebubbles-webhook",
"3. Enable the webhook and save",
"",

View File

@@ -1,5 +1,5 @@
import { resolveBlueBubblesAccount } from "./accounts.js";
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { MoltbotConfig } from "clawdbot/plugin-sdk";
import { blueBubblesFetchWithTimeout, buildBlueBubblesApiUrl } from "./types.js";
export type BlueBubblesReactionOpts = {
@@ -7,7 +7,7 @@ export type BlueBubblesReactionOpts = {
password?: string;
accountId?: string;
timeoutMs?: number;
cfg?: ClawdbotConfig;
cfg?: MoltbotConfig;
};
const REACTION_TYPES = new Set([

View File

@@ -6,7 +6,7 @@ import {
normalizeBlueBubblesHandle,
parseBlueBubblesTarget,
} from "./targets.js";
import type { ClawdbotConfig } from "clawdbot/plugin-sdk";
import type { MoltbotConfig } from "clawdbot/plugin-sdk";
import {
blueBubblesFetchWithTimeout,
buildBlueBubblesApiUrl,
@@ -18,7 +18,7 @@ export type BlueBubblesSendOpts = {
password?: string;
accountId?: string;
timeoutMs?: number;
cfg?: ClawdbotConfig;
cfg?: MoltbotConfig;
/** Message GUID to reply to (reply threading) */
replyToMessageGuid?: string;
/** Part index for reply (default: 0) */