diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d82e2c00..fd4368499 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - UI: add optional `ui.seamColor` accent to tint the Talk Mode side bubble (macOS/iOS/Android). - Nix mode: opt-in declarative config + read-only settings UI when `CLAWDIS_NIX_MODE=1` (thanks @joshp123 for the persistence — earned my trust; I'll merge these going forward). - Agent runtime: accept legacy `Z_AI_API_KEY` for Z.AI provider auth (maps to `ZAI_API_KEY`). +- Discord: add user-installed slash command handling with per-user sessions and auto-registration (#94) — thanks @thewilloftheshadow. - Discord: add DM enable/allowlist plus guild channel/user/guild allowlists with id/name matching. - Signal: add `signal-cli` JSON-RPC support for send/receive via the Signal provider. - iMessage: add imsg JSON-RPC integration (stdio), chat_id routing, and group chat support. diff --git a/README.md b/README.md index 78c372992..9f0dfd62d 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ Minimal `~/.clawdis/clawdis.json`: ### Discord - Set `DISCORD_BOT_TOKEN` or `discord.token` (env wins). -- Optional: set `discord.requireMention`, `discord.slashCommand`, `discord.allowFrom`, or `discord.mediaMaxMb` as needed. +- Optional: set `discord.slashCommand`, `discord.dm.allowFrom`, `discord.guilds`, or `discord.mediaMaxMb` as needed. ```json5 { diff --git a/src/discord/monitor.ts b/src/discord/monitor.ts index 1b3b95101..5a542c7b2 100644 --- a/src/discord/monitor.ts +++ b/src/discord/monitor.ts @@ -844,58 +844,6 @@ function resolveSlashPrompt( return undefined; } -async function ensureSlashCommand( - client: Client, - slashCommand: Required, - runtime: RuntimeEnv, -) { - try { - const appCommands = client.application?.commands; - if (!appCommands) { - runtime.error?.(danger("discord slash commands unavailable")); - return; - } - const existing = await appCommands.fetch(); - let hasCommand = false; - for (const entry of existing.values()) { - if (entry.name === slashCommand.name) { - hasCommand = true; - continue; - } - await entry.delete(); - } - if (hasCommand) return; - await appCommands.create({ - name: slashCommand.name, - description: "Ask Clawdis a question", - options: [ - { - name: "prompt", - description: "What should Clawdis help with?", - type: ApplicationCommandOptionType.String, - required: true, - }, - ], - }); - runtime.log?.(`registered discord slash command /${slashCommand.name}`); - } catch (err) { - const status = (err as { status?: number | string })?.status; - const code = (err as { code?: number | string })?.code; - const message = String(err); - const isRateLimit = - status === 429 || - code === 429 || - /rate ?limit/i.test(message); - const text = `discord slash command setup failed: ${message}`; - if (isRateLimit) { - logVerbose(text); - runtime.error?.(warn(text)); - } else { - runtime.error?.(danger(text)); - } - } -} - function findFirstStringOption( options: readonly CommandInteractionOption[], ): string | undefined {