Discord MVP slice 1: bot foundation (sidecar + bridge + settings)#260
Merged
Conversation
…e 1) First slice of the Discord MVP (.tickets/discord/MVP-PLAN.md): connect a bot and test it. No task threads / output streaming yet (next slice). - Node.js discord.js sidecar at src-tauri/sidecars/discord-bot — driven over newline-delimited JSON on stdin/stdout (commands: connect/disconnect/ping/ create_thread/post_message; events: ready/error/disconnect/message). `connect` waits for the gateway-ready event and returns the bot tag. - Rust bridge src-tauri/src/discord/mod.rs: spawns + supervises the sidecar, id-correlated request/response with timeout, forwards events as discord:<event> to the frontend, drains stderr to the log, resolves node + the sidecar path. - Commands src-tauri/src/commands/discord.rs: discord_get_config / discord_status / discord_test_connection (throwaway probe → bot tag) / discord_save_config (persist + reconcile the single managed bridge). Auto-reconciles on startup. - Config: AppSettings gains discord_enabled / discord_bot_token / discord_thread_channel_id (opt-in, off by default). - Settings UI: a Discord tab (enable, token + test connection, task-thread channel, save). Opt-in and isolated: the app runs fully without Node/Discord. Sidecar deps are a separate `npm install` in the sidecar dir (node_modules gitignored; package-lock committed). clippy · cargo check · config tests · tsc · lint · sidecar smoke green.
Slice 1 only posts to Discord (create thread + send message = REST + the non-privileged Guilds gateway intent). Requesting the PRIVILEGED MessageContent intent made login fail with "disallowed intents" for any bot that doesn't have it enabled in the Developer Portal. Drop it (and GuildMessages) until the reply-routing slice (T058) actually reads message text — so an existing bot can connect with no portal changes. The (now inert) messageCreate handler stays for that later slice.
The board now mirrors to Discord (one direction): when a trigger-spawned agent runs, a thread is created for the task; on completion its output tail + status are posted into that thread. - Migration 047 + db::discord: `discord_task_threads` (task_id ↔ thread_id, channel_id) with upsert/get helpers. - discord::notify: best-effort, fire-and-forget hooks — `on_task_started` (create thread "▸ <title>" in the configured channel, persist the mapping, post "agent started") and `on_task_finished` (post the ANSI-stripped output tail in code fences, chunked under Discord's limit, then ✅/❌ status). Guarded: a no-op unless Discord is enabled, the bridge is running, and a channel is set. `chunk_message` mirrors choomfie's line-aware splitter (unit-tested). - Wired into the headless trigger path (bridge::run_trigger_in_tmux) at start + completion; both calls are spawned so they never block or fail agent execution. Interactive-path hooks + real-time (mid-run) streaming are follow-ups; this posts the output tail at completion. clippy · cargo test (502, +4 chunker) green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First slice of the Discord MVP (.tickets/discord/MVP-PLAN.md): connect a bot and test it. Task threads + agent-output streaming are the next slice.
What's here
src-tauri/sidecars/discord-bot) —discord.js, driven over newline-delimited JSON on stdin/stdout. Commands:connect/disconnect/ping/create_thread/post_message; events:ready/error/disconnect/message.connectwaits for gateway-ready and returns the bot tag.src/discord/mod.rs) — spawns + supervises the sidecar, id-correlated request/response with timeout, forwards events asdiscord:<event>, drains stderr to the log, resolvesnode+ the sidecar path.src/commands/discord.rs) —discord_get_config/discord_status/discord_test_connection(throwaway probe → bot tag) /discord_save_config(persist + reconcile the single managed bridge). Auto-reconciles on startup.AppSettings.discord_enabled / discord_bot_token / discord_thread_channel_id(opt-in, off by default).Notes
npm installin the sidecar dir (node_modulesgitignored;package-lock.jsoncommitted). CI doesn't need them — the Rust code only references the sidecar at runtime.clippy · cargo check · config tests · tsc · lint · sidecar smoke all green.