feat(channels): add Discord adapter (#625)
Implements DiscordAdapter conforming to the ChannelAdapter interface,
using Discord Incoming Webhooks for outbound messages and the Interactions
endpoint for inbound slash commands.
Changes:
- platform/internal/channels/discord.go: DiscordAdapter + splitMessage
helper (Discord enforces 2000-char limit; long messages are split at
newline/space boundaries). ParseWebhook handles type-1 PING (returns
nil so the router layer can respond), type-2 APPLICATION_COMMAND, and
type-3 MESSAGE_COMPONENT payloads. ValidateConfig rejects non-discord
webhook URLs (SSRF guard matches Slack pattern).
- platform/internal/channels/discord_test.go: 20 unit tests covering
Type/DisplayName, ValidateConfig (valid + 5 invalid cases), SendMessage
error paths, ParseWebhook (PING / slash command / DM user / unknown type /
invalid JSON), StartPolling, GetAdapter registry lookup, ListAdapters
inclusion, and splitMessage edge cases.
- platform/internal/channels/registry.go: register "discord" adapter.
- .env.example: document DISCORD_WEBHOOK_URL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>