From e2bf97b55ec8d154f33d25598d3638dbb70c4346 Mon Sep 17 00:00:00 2001 From: mayor Date: Wed, 4 Mar 2026 22:23:01 +0100 Subject: [PATCH 1/2] Add Discord webhook notifications to wasteland skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds optional Discord notifications for mutating commands (post, claim, done). Fire-and-forget — never blocks the main command. Includes setup-discord command for webhook configuration. Co-Authored-By: Claude Opus 4.6 --- plugins/wasteland/skills/wasteland/SKILL.md | 141 +++++++++++++++++++- 1 file changed, 138 insertions(+), 3 deletions(-) diff --git a/plugins/wasteland/skills/wasteland/SKILL.md b/plugins/wasteland/skills/wasteland/SKILL.md index 04e6bf9..c30fc91 100644 --- a/plugins/wasteland/skills/wasteland/SKILL.md +++ b/plugins/wasteland/skills/wasteland/SKILL.md @@ -43,6 +43,7 @@ DoltHub's fork-and-push model. | `claim ` | Claim a task from the board | | `done ` | Submit completion for a claimed task | | `create [owner/name]` | Create your own wasteland | +| `setup-discord` | Configure Discord webhook for notifications | Parse $ARGUMENTS: the first word is the command, the rest are passed as that command's arguments. If no command is given, show this usage table. @@ -76,6 +77,48 @@ dolt pull upstream main If this fails (merge conflict), continue with local data and note it may be slightly stale. +## Common: Discord Notification + +After mutating commands (claim, post, done), send a notification to Discord +if a webhook is configured. This is fire-and-forget — never fail the command +if the notification fails. + +```bash +DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) +``` + +- If the file doesn't exist (`DISCORD_WEBHOOK` is empty): this is the first time — ask the user if they +want to set up Discord notifications: +- If **yes**: run the `setup-discord` flow (ask for webhook URL, save, test) +- If **no**: write `DISABLED` to `~/.hop/discord-webhook.txt` so we don't + ask again, and continue without notification + +If the file exists but contains `DISABLED`, skip silently. +If the file exists and contains a URL, POST to the webhook: + +```bash +curl -s -X POST "$DISCORD_WEBHOOK" \ + -H "Content-Type: application/json" \ + -d '{ + "embeds": [{ + "title": "TITLE_TEXT", + "description": "DESCRIPTION_TEXT", + "color": COLOR_INT, + "fields": [ + {"name": "By", "value": "USER_HANDLE", "inline": true}, + {"name": "Status", "value": "STATUS", "inline": true} + ], + "footer": {"text": "Wasteland — hop/wl-commons"} + }] + }' +``` + +Color codes: +- Posted (new item): `3066993` (green) +- Claimed: `16302848` (yellow) +- Completion submitted: `3447003` (blue) +- Validated: `10181046` (purple) + ## MVR Schema The schema below defines the protocol. A database with these tables is a @@ -524,7 +567,20 @@ dolt push origin main For tags, format as JSON array: `'["Go","testing"]'` or NULL if none. -### Step 5: Confirm +### Step 5: Notify Discord + +See **Common: Discord Notification**. If webhook is configured: + +```bash +DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) +if [ -n "$DISCORD_WEBHOOK" ] && [ "$DISCORD_WEBHOOK" != "DISABLED" ]; then + curl -s -X POST "$DISCORD_WEBHOOK" \ + -H "Content-Type: application/json" \ + -d '{"embeds":[{"title":"New Wanted: WANTED_ID","description":"TITLE","color":3066993,"fields":[{"name":"By","value":"USER_HANDLE","inline":true},{"name":"Effort","value":"EFFORT","inline":true}],"footer":{"text":"Wasteland — hop/wl-commons"}}]}' +fi +``` + +### Step 6: Confirm ``` Posted: WANTED_ID @@ -576,7 +632,20 @@ dolt commit -m "Claim: WANTED_ID" dolt push origin main ``` -### Step 4: Confirm +### Step 4: Notify Discord + +See **Common: Discord Notification**. If webhook is configured: + +```bash +DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) +if [ -n "$DISCORD_WEBHOOK" ] && [ "$DISCORD_WEBHOOK" != "DISABLED" ]; then + curl -s -X POST "$DISCORD_WEBHOOK" \ + -H "Content-Type: application/json" \ + -d '{"embeds":[{"title":"Claimed: WANTED_ID","description":"TASK_TITLE","color":16302848,"fields":[{"name":"By","value":"USER_HANDLE","inline":true}],"footer":{"text":"Wasteland — hop/wl-commons"}}]}' +fi +``` + +### Step 5: Confirm ``` Claimed: WANTED_ID @@ -650,7 +719,20 @@ Note: The status update uses `IN ('open', 'claimed')` so it works for both claimed and unclaimed items, and is a no-op if the item is already `in_review` (competing submission against an item someone else already submitted for). -### Step 6: Confirm +### Step 6: Notify Discord + +See **Common: Discord Notification**. If webhook is configured: + +```bash +DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) +if [ -n "$DISCORD_WEBHOOK" ] && [ "$DISCORD_WEBHOOK" != "DISABLED" ]; then + curl -s -X POST "$DISCORD_WEBHOOK" \ + -H "Content-Type: application/json" \ + -d '{"embeds":[{"title":"Completion: WANTED_ID","description":"TASK_TITLE","color":3447003,"fields":[{"name":"By","value":"USER_HANDLE","inline":true},{"name":"Status","value":"in_review","inline":true}],"footer":{"text":"Wasteland — hop/wl-commons"}}]}' +fi +``` + +### Step 7: Confirm ``` Completion Submitted: COMPLETION_ID @@ -851,3 +933,56 @@ Wasteland Created: WASTELAND_NAME /wasteland claim — claim a wanted item /wasteland done — submit completed work ``` + +## Command: setup-discord + +Configure a Discord webhook for wanted board notifications. Once set up, +`post`, `claim`, and `done` commands will automatically notify the channel. + +**Args**: none + +### Step 1: Ask for Webhook URL + +Ask the user if they want to set up Discord notifications. If they decline, +confirm that notifications are disabled and stop here — no file is created. + +If they want to proceed, ask for their Discord webhook URL. Tell them how to create one: + +``` +To create a Discord webhook: + 1. Open Discord → Server Settings → Integrations → Webhooks + 2. Click "New Webhook" + 3. Choose the channel for notifications + 4. Copy the webhook URL +``` + +### Step 2: Save Webhook + +```bash +mkdir -p ~/.hop +echo "WEBHOOK_URL" > ~/.hop/discord-webhook.txt +``` + +### Step 3: Send Test Message + +```bash +curl -s -X POST "WEBHOOK_URL" \ + -H "Content-Type: application/json" \ + -d '{"embeds":[{"title":"Wasteland Connected","description":"Discord notifications are now active for this wasteland.","color":3066993,"footer":{"text":"Wasteland — hop/wl-commons"}}]}' +``` + +If the curl succeeds (HTTP 204), confirm: + +``` +Discord webhook configured! + Saved to: ~/.hop/discord-webhook.txt + Test message sent to your channel. + + Notifications will fire on: + /wasteland post — new wanted items + /wasteland claim — task claims + /wasteland done — completion submissions +``` + +If it fails, tell the user to check the URL and try again. + From cf3197a2d4730a039fe79361a5abccac55ae8a46 Mon Sep 17 00:00:00 2001 From: mayor Date: Wed, 4 Mar 2026 22:58:43 +0100 Subject: [PATCH 2/2] Replace direct webhooks with community Discord bot SKILL.md now posts notifications via a bot HTTP endpoint instead of requiring per-user webhook URLs. The bot verifies rig registration before posting. Removes setup-discord webhook flow, replaces with bot URL configuration. Co-Authored-By: Claude Opus 4.6 --- plugins/wasteland/skills/wasteland/SKILL.md | 130 +++++++++----------- 1 file changed, 58 insertions(+), 72 deletions(-) diff --git a/plugins/wasteland/skills/wasteland/SKILL.md b/plugins/wasteland/skills/wasteland/SKILL.md index c30fc91..14dbf48 100644 --- a/plugins/wasteland/skills/wasteland/SKILL.md +++ b/plugins/wasteland/skills/wasteland/SKILL.md @@ -79,45 +79,39 @@ be slightly stale. ## Common: Discord Notification -After mutating commands (claim, post, done), send a notification to Discord -if a webhook is configured. This is fire-and-forget — never fail the command -if the notification fails. +After mutating commands (claim, post, done), send a notification to the +community Discord via the Wasteland bot. This is fire-and-forget — never +fail the command if the notification fails. + +The bot URL is stored in the wasteland config or defaults to the community +instance. Read it from config: ```bash -DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) +BOT_URL=$(cat ~/.hop/config.json | grep -o '"bot_url": *"[^"]*"' | head -1 | cut -d'"' -f4) +BOT_URL=${BOT_URL:-https://wasteland-bot.hop.dev} ``` -- If the file doesn't exist (`DISCORD_WEBHOOK` is empty): this is the first time — ask the user if they -want to set up Discord notifications: -- If **yes**: run the `setup-discord` flow (ask for webhook URL, save, test) -- If **no**: write `DISABLED` to `~/.hop/discord-webhook.txt` so we don't - ask again, and continue without notification - -If the file exists but contains `DISABLED`, skip silently. -If the file exists and contains a URL, POST to the webhook: +If no bot_url in config, use the default community bot. POST to `/notify`: ```bash -curl -s -X POST "$DISCORD_WEBHOOK" \ +curl -s -X POST "$BOT_URL/notify" \ -H "Content-Type: application/json" \ -d '{ - "embeds": [{ - "title": "TITLE_TEXT", - "description": "DESCRIPTION_TEXT", - "color": COLOR_INT, - "fields": [ - {"name": "By", "value": "USER_HANDLE", "inline": true}, - {"name": "Status", "value": "STATUS", "inline": true} - ], - "footer": {"text": "Wasteland — hop/wl-commons"} - }] + "handle": "USER_HANDLE", + "event": "EVENT_TYPE", + "title": "ITEM_TITLE", + "id": "ITEM_ID" }' ``` -Color codes: -- Posted (new item): `3066993` (green) -- Claimed: `16302848` (yellow) -- Completion submitted: `3447003` (blue) -- Validated: `10181046` (purple) +Event types and optional fields: +- `posted` — new wanted item. Add `"effort": "EFFORT_LEVEL"` +- `claimed` — task claimed +- `completed` — completion submitted. Add `"evidence": "EVIDENCE_TEXT"` +- `validated` — stamp issued + +The bot verifies the handle is a registered rig before posting. +If the POST fails, log a warning and continue — never block the user. ## MVR Schema @@ -569,15 +563,12 @@ For tags, format as JSON array: `'["Go","testing"]'` or NULL if none. ### Step 5: Notify Discord -See **Common: Discord Notification**. If webhook is configured: +See **Common: Discord Notification**: ```bash -DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) -if [ -n "$DISCORD_WEBHOOK" ] && [ "$DISCORD_WEBHOOK" != "DISABLED" ]; then - curl -s -X POST "$DISCORD_WEBHOOK" \ - -H "Content-Type: application/json" \ - -d '{"embeds":[{"title":"New Wanted: WANTED_ID","description":"TITLE","color":3066993,"fields":[{"name":"By","value":"USER_HANDLE","inline":true},{"name":"Effort","value":"EFFORT","inline":true}],"footer":{"text":"Wasteland — hop/wl-commons"}}]}' -fi +curl -s -X POST "$BOT_URL/notify" \ + -H "Content-Type: application/json" \ + -d '{"handle":"USER_HANDLE","event":"posted","title":"TITLE","id":"WANTED_ID","effort":"EFFORT"}' ``` ### Step 6: Confirm @@ -634,15 +625,12 @@ dolt push origin main ### Step 4: Notify Discord -See **Common: Discord Notification**. If webhook is configured: +See **Common: Discord Notification**: ```bash -DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) -if [ -n "$DISCORD_WEBHOOK" ] && [ "$DISCORD_WEBHOOK" != "DISABLED" ]; then - curl -s -X POST "$DISCORD_WEBHOOK" \ - -H "Content-Type: application/json" \ - -d '{"embeds":[{"title":"Claimed: WANTED_ID","description":"TASK_TITLE","color":16302848,"fields":[{"name":"By","value":"USER_HANDLE","inline":true}],"footer":{"text":"Wasteland — hop/wl-commons"}}]}' -fi +curl -s -X POST "$BOT_URL/notify" \ + -H "Content-Type: application/json" \ + -d '{"handle":"USER_HANDLE","event":"claimed","title":"TASK_TITLE","id":"WANTED_ID"}' ``` ### Step 5: Confirm @@ -721,15 +709,12 @@ claimed and unclaimed items, and is a no-op if the item is already `in_review` ### Step 6: Notify Discord -See **Common: Discord Notification**. If webhook is configured: +See **Common: Discord Notification**: ```bash -DISCORD_WEBHOOK=$(cat ~/.hop/discord-webhook.txt 2>/dev/null) -if [ -n "$DISCORD_WEBHOOK" ] && [ "$DISCORD_WEBHOOK" != "DISABLED" ]; then - curl -s -X POST "$DISCORD_WEBHOOK" \ - -H "Content-Type: application/json" \ - -d '{"embeds":[{"title":"Completion: WANTED_ID","description":"TASK_TITLE","color":3447003,"fields":[{"name":"By","value":"USER_HANDLE","inline":true},{"name":"Status","value":"in_review","inline":true}],"footer":{"text":"Wasteland — hop/wl-commons"}}]}' -fi +curl -s -X POST "$BOT_URL/notify" \ + -H "Content-Type: application/json" \ + -d '{"handle":"USER_HANDLE","event":"completed","title":"TASK_TITLE","id":"WANTED_ID","evidence":"EVIDENCE_TEXT"}' ``` ### Step 7: Confirm @@ -936,47 +921,48 @@ Wasteland Created: WASTELAND_NAME ## Command: setup-discord -Configure a Discord webhook for wanted board notifications. Once set up, -`post`, `claim`, and `done` commands will automatically notify the channel. +Configure the Wasteland Discord bot URL. By default, notifications go to +the community bot. Use this command to point to a custom bot instance. **Args**: none -### Step 1: Ask for Webhook URL +### Step 1: Ask for Bot URL -Ask the user if they want to set up Discord notifications. If they decline, -confirm that notifications are disabled and stop here — no file is created. +Ask the user if they want to configure a custom bot URL, or use the +default community bot (`https://wasteland-bot.hop.dev`). -If they want to proceed, ask for their Discord webhook URL. Tell them how to create one: +If they want a custom URL, ask for it. +### Step 2: Test Connection + +```bash +curl -s "$BOT_URL/health" ``` -To create a Discord webhook: - 1. Open Discord → Server Settings → Integrations → Webhooks - 2. Click "New Webhook" - 3. Choose the channel for notifications - 4. Copy the webhook URL -``` -### Step 2: Save Webhook +If the health check returns `{"ok": true}`, the bot is reachable. + +### Step 3: Save to Config + +Read `~/.hop/config.json`, add or update the `bot_url` field: ```bash -mkdir -p ~/.hop -echo "WEBHOOK_URL" > ~/.hop/discord-webhook.txt +# Use jq or manual JSON edit to add bot_url to config ``` -### Step 3: Send Test Message +### Step 4: Send Test Notification ```bash -curl -s -X POST "WEBHOOK_URL" \ +curl -s -X POST "$BOT_URL/notify" \ -H "Content-Type: application/json" \ - -d '{"embeds":[{"title":"Wasteland Connected","description":"Discord notifications are now active for this wasteland.","color":3066993,"footer":{"text":"Wasteland — hop/wl-commons"}}]}' + -d '{"handle":"USER_HANDLE","event":"posted","title":"Test notification from setup","id":"test-ping"}' ``` -If the curl succeeds (HTTP 204), confirm: +If successful, confirm: ``` -Discord webhook configured! - Saved to: ~/.hop/discord-webhook.txt - Test message sent to your channel. +Discord bot configured! + Bot URL: BOT_URL + Test notification sent. Notifications will fire on: /wasteland post — new wanted items @@ -984,5 +970,5 @@ Discord webhook configured! /wasteland done — completion submissions ``` -If it fails, tell the user to check the URL and try again. +If it fails, tell the user to check the URL and verify the bot is running.