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 { ClawdbotPluginApi } from "clawdbot/plugin-sdk";
import type { MoltbotPluginApi } from "clawdbot/plugin-sdk";
import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk";
import { googlechatDock, googlechatPlugin } from "./src/channel.js";
@@ -8,9 +8,9 @@ import { setGoogleChatRuntime } from "./src/runtime.js";
const plugin = {
id: "googlechat",
name: "Google Chat",
description: "Clawdbot Google Chat channel plugin",
description: "Moltbot Google Chat channel plugin",
configSchema: emptyPluginConfigSchema(),
register(api: ClawdbotPluginApi) {
register(api: MoltbotPluginApi) {
setGoogleChatRuntime(api.runtime);
api.registerChannel({ plugin: googlechatPlugin, dock: googlechatDock });
api.registerHttpHandler(handleGoogleChatWebhookRequest);

View File

@@ -2,8 +2,8 @@
"name": "@moltbot/googlechat",
"version": "2026.1.26",
"type": "module",
"description": "Clawdbot Google Chat channel plugin",
"clawdbot": {
"description": "Moltbot Google Chat channel plugin",
"moltbot": {
"extensions": [
"./index.ts"
],
@@ -31,9 +31,9 @@
"google-auth-library": "^10.5.0"
},
"devDependencies": {
"clawdbot": "workspace:*"
"moltbot": "workspace:*"
},
"peerDependencies": {
"clawdbot": ">=2026.1.26"
"moltbot": ">=2026.1.26"
}
}

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 type { GoogleChatAccountConfig, GoogleChatConfig } from "./types.config.js";
@@ -18,19 +18,19 @@ export type ResolvedGoogleChatAccount = {
const ENV_SERVICE_ACCOUNT = "GOOGLE_CHAT_SERVICE_ACCOUNT";
const ENV_SERVICE_ACCOUNT_FILE = "GOOGLE_CHAT_SERVICE_ACCOUNT_FILE";
function listConfiguredAccountIds(cfg: ClawdbotConfig): string[] {
function listConfiguredAccountIds(cfg: MoltbotConfig): string[] {
const accounts = (cfg.channels?.["googlechat"] as GoogleChatConfig | undefined)?.accounts;
if (!accounts || typeof accounts !== "object") return [];
return Object.keys(accounts).filter(Boolean);
}
export function listGoogleChatAccountIds(cfg: ClawdbotConfig): string[] {
export function listGoogleChatAccountIds(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 resolveDefaultGoogleChatAccountId(cfg: ClawdbotConfig): string {
export function resolveDefaultGoogleChatAccountId(cfg: MoltbotConfig): string {
const channel = cfg.channels?.["googlechat"] as GoogleChatConfig | undefined;
if (channel?.defaultAccount?.trim()) return channel.defaultAccount.trim();
const ids = listGoogleChatAccountIds(cfg);
@@ -39,7 +39,7 @@ export function resolveDefaultGoogleChatAccountId(cfg: ClawdbotConfig): string {
}
function resolveAccountConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
accountId: string,
): GoogleChatAccountConfig | undefined {
const accounts = (cfg.channels?.["googlechat"] as GoogleChatConfig | undefined)?.accounts;
@@ -48,7 +48,7 @@ function resolveAccountConfig(
}
function mergeGoogleChatAccountConfig(
cfg: ClawdbotConfig,
cfg: MoltbotConfig,
accountId: string,
): GoogleChatAccountConfig {
const raw = (cfg.channels?.["googlechat"] ?? {}) as GoogleChatConfig;
@@ -104,7 +104,7 @@ function resolveCredentialsFromConfig(params: {
}
export function resolveGoogleChatAccount(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
accountId?: string | null;
}): ResolvedGoogleChatAccount {
const accountId = normalizeAccountId(params.accountId);
@@ -126,7 +126,7 @@ export function resolveGoogleChatAccount(params: {
};
}
export function listEnabledGoogleChatAccounts(cfg: ClawdbotConfig): ResolvedGoogleChatAccount[] {
export function listEnabledGoogleChatAccounts(cfg: MoltbotConfig): ResolvedGoogleChatAccount[] {
return listGoogleChatAccountIds(cfg)
.map((accountId) => resolveGoogleChatAccount({ cfg, accountId }))
.filter((account) => account.enabled);

View File

@@ -1,7 +1,7 @@
import type {
ChannelMessageActionAdapter,
ChannelMessageActionName,
ClawdbotConfig,
MoltbotConfig,
} from "clawdbot/plugin-sdk";
import {
createActionGate,
@@ -24,13 +24,13 @@ import { resolveGoogleChatOutboundSpace } from "./targets.js";
const providerId = "googlechat";
function listEnabledAccounts(cfg: ClawdbotConfig) {
function listEnabledAccounts(cfg: MoltbotConfig) {
return listEnabledGoogleChatAccounts(cfg).filter(
(account) => account.enabled && account.credentialSource !== "none",
);
}
function isReactionsEnabled(accounts: ReturnType<typeof listEnabledAccounts>, cfg: ClawdbotConfig) {
function isReactionsEnabled(accounts: ReturnType<typeof listEnabledAccounts>, cfg: MoltbotConfig) {
for (const account of accounts) {
const gate = createActionGate(
(account.config.actions ?? (cfg.channels?.["googlechat"] as { actions?: unknown })?.actions) as Record<
@@ -49,11 +49,11 @@ function resolveAppUserNames(account: { config: { botUser?: string | null } }) {
export const googlechatMessageActions: ChannelMessageActionAdapter = {
listActions: ({ cfg }) => {
const accounts = listEnabledAccounts(cfg as ClawdbotConfig);
const accounts = listEnabledAccounts(cfg as MoltbotConfig);
if (accounts.length === 0) return [];
const actions = new Set<ChannelMessageActionName>([]);
actions.add("send");
if (isReactionsEnabled(accounts, cfg as ClawdbotConfig)) {
if (isReactionsEnabled(accounts, cfg as MoltbotConfig)) {
actions.add("react");
actions.add("reactions");
}
@@ -69,7 +69,7 @@ export const googlechatMessageActions: ChannelMessageActionAdapter = {
},
handleAction: async ({ action, params, cfg, accountId }) => {
const account = resolveGoogleChatAccount({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId,
});
if (account.credentialSource === "none") {

View File

@@ -153,7 +153,7 @@ export async function uploadGoogleChatAttachment(params: {
contentType?: string;
}): Promise<{ attachmentUploadToken?: string }> {
const { account, space, filename, buffer, contentType } = params;
const boundary = `clawdbot-${crypto.randomUUID()}`;
const boundary = `moltbot-${crypto.randomUUID()}`;
const metadata = JSON.stringify({ filename });
const header = `--${boundary}\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n${metadata}\r\n`;
const mediaHeader = `--${boundary}\r\nContent-Type: ${contentType ?? "application/octet-stream"}\r\n\r\n`;

View File

@@ -15,7 +15,7 @@ import {
type ChannelDock,
type ChannelMessageActionAdapter,
type ChannelPlugin,
type ClawdbotConfig,
type MoltbotConfig,
} from "clawdbot/plugin-sdk";
import { GoogleChatConfigSchema } from "clawdbot/plugin-sdk";
@@ -59,7 +59,7 @@ export const googlechatDock: ChannelDock = {
outbound: { textChunkLimit: 4000 },
config: {
resolveAllowFrom: ({ cfg, accountId }) =>
(resolveGoogleChatAccount({ cfg: cfg as ClawdbotConfig, accountId }).config.dm?.allowFrom ??
(resolveGoogleChatAccount({ cfg: cfg as MoltbotConfig, accountId }).config.dm?.allowFrom ??
[]
).map((entry) => String(entry)),
formatAllowFrom: ({ allowFrom }) =>
@@ -103,7 +103,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
idLabel: "googlechatUserId",
normalizeAllowEntry: (entry) => formatAllowFromEntry(entry),
notifyApproval: async ({ cfg, id }) => {
const account = resolveGoogleChatAccount({ cfg: cfg as ClawdbotConfig });
const account = resolveGoogleChatAccount({ cfg: cfg as MoltbotConfig });
if (account.credentialSource === "none") return;
const user = normalizeGoogleChatTarget(id) ?? id;
const target = isGoogleChatUserTarget(user) ? user : `users/${user}`;
@@ -129,13 +129,13 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
reload: { configPrefixes: ["channels.googlechat"] },
configSchema: buildChannelConfigSchema(GoogleChatConfigSchema),
config: {
listAccountIds: (cfg) => listGoogleChatAccountIds(cfg as ClawdbotConfig),
listAccountIds: (cfg) => listGoogleChatAccountIds(cfg as MoltbotConfig),
resolveAccount: (cfg, accountId) =>
resolveGoogleChatAccount({ cfg: cfg as ClawdbotConfig, accountId }),
defaultAccountId: (cfg) => resolveDefaultGoogleChatAccountId(cfg as ClawdbotConfig),
resolveGoogleChatAccount({ cfg: cfg as MoltbotConfig, accountId }),
defaultAccountId: (cfg) => resolveDefaultGoogleChatAccountId(cfg as MoltbotConfig),
setAccountEnabled: ({ cfg, accountId, enabled }) =>
setAccountEnabledInConfigSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
sectionKey: "googlechat",
accountId,
enabled,
@@ -143,7 +143,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
}),
deleteAccount: ({ cfg, accountId }) =>
deleteAccountFromConfigSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
sectionKey: "googlechat",
accountId,
clearBaseFields: [
@@ -167,7 +167,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
}),
resolveAllowFrom: ({ cfg, accountId }) =>
(resolveGoogleChatAccount({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId,
}).config.dm?.allowFrom ?? []
).map((entry) => String(entry)),
@@ -181,7 +181,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
resolveDmPolicy: ({ cfg, accountId, account }) => {
const resolvedAccountId = accountId ?? account.accountId ?? DEFAULT_ACCOUNT_ID;
const useAccountPath = Boolean(
(cfg as ClawdbotConfig).channels?.["googlechat"]?.accounts?.[resolvedAccountId],
(cfg as MoltbotConfig).channels?.["googlechat"]?.accounts?.[resolvedAccountId],
);
const allowFromPath = useAccountPath
? `channels.googlechat.accounts.${resolvedAccountId}.dm.`
@@ -231,7 +231,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
self: async () => null,
listPeers: async ({ cfg, accountId, query, limit }) => {
const account = resolveGoogleChatAccount({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId,
});
const q = query?.trim().toLowerCase() || "";
@@ -251,7 +251,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
},
listGroups: async ({ cfg, accountId, query, limit }) => {
const account = resolveGoogleChatAccount({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId,
});
const groups = account.config.groups ?? {};
@@ -291,7 +291,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
resolveAccountId: ({ accountId }) => normalizeAccountId(accountId),
applyAccountName: ({ cfg, accountId, name }) =>
applyAccountNameToChannelSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
channelKey: "googlechat",
accountId,
name,
@@ -307,7 +307,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
},
applyAccountConfig: ({ cfg, accountId, input }) => {
const namedConfig = applyAccountNameToChannelSection({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
channelKey: "googlechat",
accountId,
name: input.name,
@@ -315,7 +315,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
const next =
accountId !== DEFAULT_ACCOUNT_ID
? migrateBaseNameToDefaultAccount({
cfg: namedConfig as ClawdbotConfig,
cfg: namedConfig as MoltbotConfig,
channelKey: "googlechat",
})
: namedConfig;
@@ -348,7 +348,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
...configPatch,
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
}
return {
...next,
@@ -367,7 +367,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
},
},
},
} as ClawdbotConfig;
} as MoltbotConfig;
},
},
outbound: {
@@ -414,7 +414,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
},
sendText: async ({ cfg, to, text, accountId, replyToId, threadId }) => {
const account = resolveGoogleChatAccount({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId,
});
const space = await resolveGoogleChatOutboundSpace({ account, target: to });
@@ -436,14 +436,14 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
throw new Error("Google Chat mediaUrl is required.");
}
const account = resolveGoogleChatAccount({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
accountId,
});
const space = await resolveGoogleChatOutboundSpace({ account, target: to });
const thread = (threadId ?? replyToId ?? undefined) as string | undefined;
const runtime = getGoogleChatRuntime();
const maxBytes = resolveChannelMediaMaxBytes({
cfg: cfg as ClawdbotConfig,
cfg: cfg as MoltbotConfig,
resolveChannelLimitMb: ({ cfg, accountId }) =>
(cfg.channels?.["googlechat"] as { accounts?: Record<string, { mediaMaxMb?: number }>; mediaMaxMb?: number } | undefined)
?.accounts?.[accountId]?.mediaMaxMb ??
@@ -560,7 +560,7 @@ export const googlechatPlugin: ChannelPlugin<ResolvedGoogleChatAccount> = {
});
const unregister = await startGoogleChatMonitor({
account,
config: ctx.cfg as ClawdbotConfig,
config: ctx.cfg as MoltbotConfig,
runtime: ctx.runtime,
abortSignal: ctx.abortSignal,
webhookPath: account.config.webhookPath,

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 { resolveMentionGatingWithBypass } from "clawdbot/plugin-sdk";
import {
@@ -30,7 +30,7 @@ export type GoogleChatRuntimeEnv = {
export type GoogleChatMonitorOptions = {
account: ResolvedGoogleChatAccount;
config: ClawdbotConfig;
config: MoltbotConfig;
runtime: GoogleChatRuntimeEnv;
abortSignal: AbortSignal;
webhookPath?: string;
@@ -42,7 +42,7 @@ type GoogleChatCoreRuntime = ReturnType<typeof getGoogleChatRuntime>;
type WebhookTarget = {
account: ResolvedGoogleChatAccount;
config: ClawdbotConfig;
config: MoltbotConfig;
runtime: GoogleChatRuntimeEnv;
core: GoogleChatCoreRuntime;
path: string;
@@ -357,24 +357,24 @@ function extractMentionInfo(annotations: GoogleChatAnnotation[], botUser?: strin
* Resolve bot display name with fallback chain:
* 1. Account config name
* 2. Agent name from config
* 3. "Clawdbot" as generic fallback
* 3. "Moltbot" as generic fallback
*/
function resolveBotDisplayName(params: {
accountName?: string;
agentId: string;
config: ClawdbotConfig;
config: MoltbotConfig;
}): string {
const { accountName, agentId, config } = params;
if (accountName?.trim()) return accountName.trim();
const agent = config.agents?.list?.find((a) => a.id === agentId);
if (agent?.name?.trim()) return agent.name.trim();
return "Clawdbot";
return "Moltbot";
}
async function processMessageWithPipeline(params: {
event: GoogleChatEvent;
account: ResolvedGoogleChatAccount;
config: ClawdbotConfig;
config: MoltbotConfig;
runtime: GoogleChatRuntimeEnv;
core: GoogleChatCoreRuntime;
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
@@ -726,7 +726,7 @@ async function deliverGoogleChatReply(params: {
spaceId: string;
runtime: GoogleChatRuntimeEnv;
core: GoogleChatCoreRuntime;
config: ClawdbotConfig;
config: MoltbotConfig;
statusSink?: (patch: { lastInboundAt?: number; lastOutboundAt?: number }) => void;
typingMessageName?: string;
}): Promise<void> {

View File

@@ -1,4 +1,4 @@
import type { ClawdbotConfig, DmPolicy } from "clawdbot/plugin-sdk";
import type { MoltbotConfig, DmPolicy } from "clawdbot/plugin-sdk";
import {
addWildcardAllowFrom,
formatDocsLink,
@@ -22,7 +22,7 @@ const channel = "googlechat" as const;
const ENV_SERVICE_ACCOUNT = "GOOGLE_CHAT_SERVICE_ACCOUNT";
const ENV_SERVICE_ACCOUNT_FILE = "GOOGLE_CHAT_SERVICE_ACCOUNT_FILE";
function setGoogleChatDmPolicy(cfg: ClawdbotConfig, policy: DmPolicy) {
function setGoogleChatDmPolicy(cfg: MoltbotConfig, policy: DmPolicy) {
const allowFrom =
policy === "open"
? addWildcardAllowFrom(cfg.channels?.["googlechat"]?.dm?.allowFrom)
@@ -51,9 +51,9 @@ function parseAllowFromInput(raw: string): string[] {
}
async function promptAllowFrom(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
prompter: WizardPrompter;
}): Promise<ClawdbotConfig> {
}): Promise<MoltbotConfig> {
const current = params.cfg.channels?.["googlechat"]?.dm?.allowFrom ?? [];
const entry = await params.prompter.text({
message: "Google Chat allowFrom (user id or email)",
@@ -91,10 +91,10 @@ const dmPolicy: ChannelOnboardingDmPolicy = {
};
function applyAccountConfig(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
accountId: string;
patch: Record<string, unknown>;
}): ClawdbotConfig {
}): MoltbotConfig {
const { cfg, accountId, patch } = params;
if (accountId === DEFAULT_ACCOUNT_ID) {
return {
@@ -130,10 +130,10 @@ function applyAccountConfig(params: {
}
async function promptCredentials(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
prompter: WizardPrompter;
accountId: string;
}): Promise<ClawdbotConfig> {
}): Promise<MoltbotConfig> {
const { cfg, prompter, accountId } = params;
const envReady =
accountId === DEFAULT_ACCOUNT_ID &&
@@ -184,10 +184,10 @@ async function promptCredentials(params: {
}
async function promptAudience(params: {
cfg: ClawdbotConfig;
cfg: MoltbotConfig;
prompter: WizardPrompter;
accountId: string;
}): Promise<ClawdbotConfig> {
}): Promise<MoltbotConfig> {
const account = resolveGoogleChatAccount({
cfg: params.cfg,
accountId: params.accountId,