From fd33290266620ee7379a236e1cde0d5eddf6e9ff Mon Sep 17 00:00:00 2001 From: orion Date: Sun, 5 Apr 2026 19:24:06 +0000 Subject: [PATCH] feat: add /add-guild slash command --- plugin/commands/add-guild-command.ts | 59 ++++++++++++++++++++++++++++ plugin/index.ts | 4 ++ 2 files changed, 63 insertions(+) create mode 100644 plugin/commands/add-guild-command.ts diff --git a/plugin/commands/add-guild-command.ts b/plugin/commands/add-guild-command.ts new file mode 100644 index 0000000..a500468 --- /dev/null +++ b/plugin/commands/add-guild-command.ts @@ -0,0 +1,59 @@ +import type { OpenClawPluginApi } from "openclaw/plugin-sdk"; +import { execFileSync } from "node:child_process"; +import path from "node:path"; +import os from "node:os"; + +export function registerAddGuildCommand(api: OpenClawPluginApi): void { + api.registerCommand({ + name: "add-guild", + description: "Add a Discord guild to the discord-guilds skill", + acceptsArgs: true, + handler: async (cmdCtx) => { + const args = (cmdCtx.args || "").trim(); + if (!args) { + return { + text: "Usage: /add-guild \nExample: /add-guild 123456789012345678 \"Production server\"", + isError: true, + }; + } + + const parts = args.split(/\s+/); + if (parts.length < 2) { + return { + text: "Error: Both guild-id and description are required.\nUsage: /add-guild ", + isError: true, + }; + } + + const guildId = parts[0]; + const description = parts.slice(1).join(" "); + + // Validate guild ID + if (!/^\d+$/.test(guildId)) { + return { + text: "Error: guild-id must be a numeric Discord snowflake (e.g., 123456789012345678)", + isError: true, + }; + } + + // Resolve the skill script path + const openClawDir = (api.config as Record)?.["dirigentStateDir"] as string || path.join(os.homedir(), ".openclaw"); + const scriptPath = path.join(openClawDir, "skills", "discord-guilds", "scripts", "add-guild"); + + try { + const result = execFileSync(process.execPath, [scriptPath, guildId, description], { + encoding: "utf8", + timeout: 5000, + }); + return { text: result.trim() }; + } catch (e: any) { + const stderr = e?.stderr?.toString?.() || ""; + const stdout = e?.stdout?.toString?.() || ""; + return { + text: `Failed to add guild: ${stderr || stdout || String(e)}`, + isError: true, + }; + } + }, + }); +} diff --git a/plugin/index.ts b/plugin/index.ts index 03bac0b..0146e9a 100644 --- a/plugin/index.ts +++ b/plugin/index.ts @@ -9,6 +9,7 @@ import { registerBeforePromptBuildHook } from "./hooks/before-prompt-build.js"; import { registerBeforeMessageWriteHook } from "./hooks/before-message-write.js"; import { registerMessageSentHook } from "./hooks/message-sent.js"; import { registerDirigentCommand } from "./commands/dirigent-command.js"; +import { registerAddGuildCommand } from "./commands/add-guild-command.js"; import { registerDirigentTools } from "./tools/register-tools.js"; import { ensurePolicyStateLoaded, persistPolicies, policyState } from "./policy/store.js"; import { buildAgentIdentity, buildUserIdToAccountIdMap, resolveAccountId } from "./core/identity.js"; @@ -201,6 +202,9 @@ export default { ensurePolicyStateLoaded, }); + // Register add-guild command + registerAddGuildCommand(api); + // Handle NO_REPLY detection before message write registerBeforeMessageWriteHook({ api,