refactor: rename to openclaw

This commit is contained in:
Peter Steinberger
2026-01-30 03:15:10 +01:00
parent 4583f88626
commit 9a7160786a
2357 changed files with 16688 additions and 16788 deletions

View File

@@ -7,8 +7,8 @@ export function normalizeSlackSlashCommandName(raw: string) {
export function resolveSlackSlashCommandConfig(
raw?: SlackSlashCommandConfig,
): Required<SlackSlashCommandConfig> {
const normalizedName = normalizeSlackSlashCommandName(raw?.name?.trim() || "clawd");
const name = normalizedName || "clawd";
const normalizedName = normalizeSlackSlashCommandName(raw?.name?.trim() || "openclaw");
const name = normalizedName || "openclaw";
return {
enabled: raw?.enabled === true,
name,
@@ -18,6 +18,7 @@ export function resolveSlackSlashCommandConfig(
}
export function buildSlackSlashCommandMatcher(name: string) {
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const normalized = normalizeSlackSlashCommandName(name);
const escaped = normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
return new RegExp(`^/?${escaped}$`);
}

View File

@@ -1,12 +1,12 @@
import type { App } from "@slack/bolt";
import { describe, expect, it } from "vitest";
import type { MoltbotConfig } from "../../config/config.js";
import type { OpenClawConfig } from "../../config/config.js";
import type { RuntimeEnv } from "../../runtime.js";
import { createSlackMonitorContext, normalizeSlackChannelType } from "./context.js";
const baseParams = () => ({
cfg: {} as MoltbotConfig,
cfg: {} as OpenClawConfig,
accountId: "default",
botToken: "token",
app: { client: {} } as App,
@@ -30,7 +30,7 @@ const baseParams = () => ({
replyToMode: "off" as const,
slashCommand: {
enabled: false,
name: "clawd",
name: "openclaw",
sessionPrefix: "slack:slash",
ephemeral: true,
},

View File

@@ -1,6 +1,6 @@
import type { App } from "@slack/bolt";
import type { HistoryEntry } from "../../auto-reply/reply/history.js";
import type { MoltbotConfig, SlackReactionNotificationMode } from "../../config/config.js";
import type { OpenClawConfig, SlackReactionNotificationMode } from "../../config/config.js";
import { resolveSessionKey, type SessionScope } from "../../config/sessions.js";
import type { DmPolicy, GroupPolicy } from "../../config/types.js";
import { logVerbose } from "../../globals.js";
@@ -42,7 +42,7 @@ export function normalizeSlackChannelType(
}
export type SlackMonitorContext = {
cfg: MoltbotConfig;
cfg: OpenClawConfig;
accountId: string;
botToken: string;
app: App;
@@ -115,7 +115,7 @@ export type SlackMonitorContext = {
};
export function createSlackMonitorContext(params: {
cfg: MoltbotConfig;
cfg: OpenClawConfig;
accountId: string;
botToken: string;
app: App;

View File

@@ -1,7 +1,7 @@
import type { App } from "@slack/bolt";
import { describe, expect, it } from "vitest";
import type { MoltbotConfig } from "../../../config/config.js";
import type { OpenClawConfig } from "../../../config/config.js";
import type { RuntimeEnv } from "../../../runtime.js";
import { expectInboundContextContract } from "../../../../test/helpers/inbound-contract.js";
import type { ResolvedSlackAccount } from "../../accounts.js";
@@ -14,7 +14,7 @@ describe("slack prepareSlackMessage inbound contract", () => {
const slackCtx = createSlackMonitorContext({
cfg: {
channels: { slack: { enabled: true } },
} as MoltbotConfig,
} as OpenClawConfig,
accountId: "default",
botToken: "token",
app: { client: {} } as App,
@@ -40,7 +40,7 @@ describe("slack prepareSlackMessage inbound contract", () => {
threadInheritParent: false,
slashCommand: {
enabled: false,
name: "clawd",
name: "openclaw",
sessionPrefix: "slack:slash",
ephemeral: true,
},
@@ -82,7 +82,7 @@ describe("slack prepareSlackMessage inbound contract", () => {
const slackCtx = createSlackMonitorContext({
cfg: {
channels: { slack: { enabled: true, replyToMode: "all" } },
} as MoltbotConfig,
} as OpenClawConfig,
accountId: "default",
botToken: "token",
app: { client: {} } as App,
@@ -108,7 +108,7 @@ describe("slack prepareSlackMessage inbound contract", () => {
threadInheritParent: false,
slashCommand: {
enabled: false,
name: "clawd",
name: "openclaw",
sessionPrefix: "slack:slash",
ephemeral: true,
},

View File

@@ -7,7 +7,7 @@ describe("prepareSlackMessage sender prefix", () => {
it("prefixes channel bodies with sender label", async () => {
const ctx = {
cfg: {
agents: { defaults: { model: "anthropic/claude-opus-4-5", workspace: "/tmp/clawd" } },
agents: { defaults: { model: "anthropic/claude-opus-4-5", workspace: "/tmp/openclaw" } },
channels: { slack: {} },
},
accountId: "default",
@@ -40,7 +40,7 @@ describe("prepareSlackMessage sender prefix", () => {
replyToMode: "off",
threadHistoryScope: "channel",
threadInheritParent: false,
slashCommand: { command: "/clawd", enabled: true },
slashCommand: { command: "/openclaw", enabled: true },
textLimit: 2000,
ackReactionScope: "off",
mediaMaxBytes: 1000,

View File

@@ -68,7 +68,12 @@ function createHarness() {
groupPolicy: "open",
useAccessGroups: false,
channelsConfig: undefined,
slashCommand: { enabled: true, name: "clawd", ephemeral: true, sessionPrefix: "slack:slash" },
slashCommand: {
enabled: true,
name: "openclaw",
ephemeral: true,
sessionPrefix: "slack:slash",
},
textLimit: 4000,
app,
isChannelAllowed: () => true,
@@ -126,7 +131,7 @@ describe("Slack native command argument menus", () => {
const { actions, ctx, account } = createHarness();
registerSlackMonitorSlashCommands({ ctx: ctx as never, account: account as never });
const handler = actions.get("moltbot_cmdarg");
const handler = actions.get("openclaw_cmdarg");
if (!handler) throw new Error("Missing arg-menu action handler");
const respond = vi.fn().mockResolvedValue(undefined);
@@ -152,7 +157,7 @@ describe("Slack native command argument menus", () => {
const { actions, ctx, account } = createHarness();
registerSlackMonitorSlashCommands({ ctx: ctx as never, account: account as never });
const handler = actions.get("moltbot_cmdarg");
const handler = actions.get("openclaw_cmdarg");
if (!handler) throw new Error("Missing arg-menu action handler");
const respond = vi.fn().mockResolvedValue(undefined);
@@ -180,7 +185,7 @@ describe("Slack native command argument menus", () => {
const { actions, postEphemeral, ctx, account } = createHarness();
registerSlackMonitorSlashCommands({ ctx: ctx as never, account: account as never });
const handler = actions.get("moltbot_cmdarg");
const handler = actions.get("openclaw_cmdarg");
if (!handler) throw new Error("Missing arg-menu action handler");
await handler({
@@ -202,7 +207,7 @@ describe("Slack native command argument menus", () => {
const { actions, postEphemeral, ctx, account } = createHarness();
registerSlackMonitorSlashCommands({ ctx: ctx as never, account: account as never });
const handler = actions.get("moltbot_cmdarg");
const handler = actions.get("openclaw_cmdarg");
if (!handler) throw new Error("Missing arg-menu action handler");
await handler({

View File

@@ -61,7 +61,12 @@ function createHarness(overrides?: {
groupPolicy: overrides?.groupPolicy ?? "open",
useAccessGroups: true,
channelsConfig: overrides?.channelsConfig,
slashCommand: { enabled: true, name: "clawd", ephemeral: true, sessionPrefix: "slack:slash" },
slashCommand: {
enabled: true,
name: "openclaw",
ephemeral: true,
sessionPrefix: "slack:slash",
},
textLimit: 4000,
app,
isChannelAllowed: () => true,

View File

@@ -41,7 +41,7 @@ import { deliverSlackSlashReplies } from "./replies.js";
type SlackBlock = { type: string; [key: string]: unknown };
const SLACK_COMMAND_ARG_ACTION_ID = "moltbot_cmdarg";
const SLACK_COMMAND_ARG_ACTION_ID = "openclaw_cmdarg";
const SLACK_COMMAND_ARG_VALUE_PREFIX = "cmdarg";
function chunkItems<T>(items: T[], size: number): T[][] {
@@ -528,68 +528,73 @@ export function registerSlackMonitorSlashCommands(params: {
if (nativeCommands.length === 0 || !supportsInteractiveArgMenus) return;
(
ctx.app as unknown as { action: NonNullable<(typeof ctx.app & { action?: unknown })["action"]> }
).action(SLACK_COMMAND_ARG_ACTION_ID, async (args: SlackActionMiddlewareArgs) => {
const { ack, body, respond } = args;
const action = args.action as { value?: string };
await ack();
const respondFn =
respond ??
(async (payload: { text: string; blocks?: SlackBlock[]; response_type?: string }) => {
if (!body.channel?.id || !body.user?.id) return;
await ctx.app.client.chat.postEphemeral({
token: ctx.botToken,
channel: body.channel.id,
user: body.user.id,
text: payload.text,
blocks: payload.blocks,
const registerArgAction = (actionId: string) => {
(
ctx.app as unknown as {
action: NonNullable<(typeof ctx.app & { action?: unknown })["action"]>;
}
).action(actionId, async (args: SlackActionMiddlewareArgs) => {
const { ack, body, respond } = args;
const action = args.action as { value?: string };
await ack();
const respondFn =
respond ??
(async (payload: { text: string; blocks?: SlackBlock[]; response_type?: string }) => {
if (!body.channel?.id || !body.user?.id) return;
await ctx.app.client.chat.postEphemeral({
token: ctx.botToken,
channel: body.channel.id,
user: body.user.id,
text: payload.text,
blocks: payload.blocks,
});
});
const parsed = parseSlackCommandArgValue(action?.value);
if (!parsed) {
await respondFn({
text: "Sorry, that button is no longer valid.",
response_type: "ephemeral",
});
return;
}
if (body.user?.id && parsed.userId !== body.user.id) {
await respondFn({
text: "That menu is for another user.",
response_type: "ephemeral",
});
return;
}
const commandDefinition = findCommandByNativeName(parsed.command, "slack");
const commandArgs: CommandArgs = {
values: { [parsed.arg]: parsed.value },
};
const prompt = commandDefinition
? buildCommandTextFromArgs(commandDefinition, commandArgs)
: `/${parsed.command} ${parsed.value}`;
const user = body.user;
const userName =
user && "name" in user && user.name
? user.name
: user && "username" in user && user.username
? user.username
: (user?.id ?? "");
const triggerId = "trigger_id" in body ? body.trigger_id : undefined;
const commandPayload = {
user_id: user?.id ?? "",
user_name: userName,
channel_id: body.channel?.id ?? "",
channel_name: body.channel?.name ?? body.channel?.id ?? "",
trigger_id: triggerId ?? String(Date.now()),
} as SlackCommandMiddlewareArgs["command"];
await handleSlashCommand({
command: commandPayload,
ack: async () => {},
respond: respondFn as SlackCommandMiddlewareArgs["respond"],
prompt,
commandArgs,
commandDefinition: commandDefinition ?? undefined,
});
const parsed = parseSlackCommandArgValue(action?.value);
if (!parsed) {
await respondFn({
text: "Sorry, that button is no longer valid.",
response_type: "ephemeral",
});
return;
}
if (body.user?.id && parsed.userId !== body.user.id) {
await respondFn({
text: "That menu is for another user.",
response_type: "ephemeral",
});
return;
}
const commandDefinition = findCommandByNativeName(parsed.command, "slack");
const commandArgs: CommandArgs = {
values: { [parsed.arg]: parsed.value },
};
const prompt = commandDefinition
? buildCommandTextFromArgs(commandDefinition, commandArgs)
: `/${parsed.command} ${parsed.value}`;
const user = body.user;
const userName =
user && "name" in user && user.name
? user.name
: user && "username" in user && user.username
? user.username
: (user?.id ?? "");
const triggerId = "trigger_id" in body ? body.trigger_id : undefined;
const commandPayload = {
user_id: user?.id ?? "",
user_name: userName,
channel_id: body.channel?.id ?? "",
channel_name: body.channel?.name ?? body.channel?.id ?? "",
trigger_id: triggerId ?? String(Date.now()),
} as SlackCommandMiddlewareArgs["command"];
await handleSlashCommand({
command: commandPayload,
ack: async () => {},
respond: respondFn as SlackCommandMiddlewareArgs["respond"],
prompt,
commandArgs,
commandDefinition: commandDefinition ?? undefined,
});
});
};
registerArgAction(SLACK_COMMAND_ARG_ACTION_ID);
}

View File

@@ -1,4 +1,4 @@
import type { MoltbotConfig, SlackSlashCommandConfig } from "../../config/config.js";
import type { OpenClawConfig, SlackSlashCommandConfig } from "../../config/config.js";
import type { RuntimeEnv } from "../../runtime.js";
import type { SlackFile, SlackMessageEvent } from "../types.js";
@@ -7,7 +7,7 @@ export type MonitorSlackOpts = {
appToken?: string;
accountId?: string;
mode?: "socket" | "http";
config?: MoltbotConfig;
config?: OpenClawConfig;
runtime?: RuntimeEnv;
abortSignal?: AbortSignal;
mediaMaxMb?: number;