From 933ffd7fa42402ec4033dd04a80aa168acf7372d Mon Sep 17 00:00:00 2001 From: Amolith Date: Tue, 10 Feb 2026 19:35:29 -0700 Subject: [PATCH] feat: add notifying-through-ntfy skill Sends push notifications via ntfy.sh when the user explicitly asks to be notified. Includes curl examples in SKILL.md and alternative HTTP client references (ht, httpie, wget, python, nodejs) for environments where curl is unavailable. --- skills/notifying-through-ntfy/SKILL.md | 80 ++++++++++++++++ .../notifying-through-ntfy/references/ht.md | 42 +++++++++ .../references/httpie.md | 38 ++++++++ .../references/nodejs.md | 92 +++++++++++++++++++ .../references/python.md | 68 ++++++++++++++ .../notifying-through-ntfy/references/wget.md | 42 +++++++++ 6 files changed, 362 insertions(+) create mode 100644 skills/notifying-through-ntfy/SKILL.md create mode 100644 skills/notifying-through-ntfy/references/ht.md create mode 100644 skills/notifying-through-ntfy/references/httpie.md create mode 100644 skills/notifying-through-ntfy/references/nodejs.md create mode 100644 skills/notifying-through-ntfy/references/python.md create mode 100644 skills/notifying-through-ntfy/references/wget.md diff --git a/skills/notifying-through-ntfy/SKILL.md b/skills/notifying-through-ntfy/SKILL.md new file mode 100644 index 0000000000000000000000000000000000000000..640945e7e2d575270e0a24751a1ef0d806aeb8aa --- /dev/null +++ b/skills/notifying-through-ntfy/SKILL.md @@ -0,0 +1,80 @@ +--- +name: notifying-through-ntfy +description: Sends push notifications via ntfy.sh. Use when the user asks to be notified, says "ntfy me", or requests a notification when a task is done. +license: GPL-3.0-or-later +metadata: + author: Amolith +--- + +Send a notification only when the user explicitly asks for one. + +## Environment + +Two environment variables are required: + +- `$NTFY_TOPIC_LLM` — the ntfy topic to publish to +- `$NTFY_ACCESS_TOKEN` — bearer token for authentication + +If either is unset or empty, ask the user to set them before proceeding. + +## Headers + +Set headers on every notification: + +- **Title** (`-H "Title: ..."`) — brief, informative, sentence-case summary of what happened (e.g. "Refactored authentication middleware in rumilo") +- **Tags** (`-H "Tags: ..."`) — comma-separated emoji shortcodes (prefer one). Must be a valid shortcode or ntfy treats it as a text tag instead of an emoji prefix. +- **Priority** (`-H "Priority: ..."`) — integer 1–5. Only set when something went wrong; 3 is default and omitted. + - 1 (min) / 2 (low): quiet, no vibration + - 3 (default): normal notification + - 4 (high): long vibration burst + - 5 (max/urgent): very long vibration burst, may bypass Do Not Disturb +- **Click** (`-H "Click: ..."`) — optional URL opened when the notification is tapped. If your environment provides a way to generate a link back to the current conversation or session, include it. If not, only set this header when linking to something directly relevant (a PR, a deploy, a docs page, etc.). Never fabricate a conversation URL. + +## Body + +The body is a slightly longer, friendly paragraph saying who finished what in which project. Keep it conversational and informative — a sentence or two is plenty. + +## Examples + +```bash +# normal success +curl -H "Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + -H "Title: Refactored authentication middleware in rumilo" \ + -H "Tags: hammer_and_wrench" \ + -d "Finished refactoring the auth middleware in rumilo. Session validation is cleaner now and all tests pass." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" + +# success with a relevant click URL +curl -H "Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + -H "Title: Updated AUR package for kagi-ken" \ + -H "Tags: package" \ + -H "Click: https://aur.archlinux.org/packages/kagi-ken" \ + -d "Bumped the kagi-ken AUR package to v0.4.2 and updated the checksums." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" + +# something went wrong +curl -H "Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + -H "Title: Build failed in pi-mono — disk full" \ + -H "Tags: rotating_light" \ + -H "Priority: 4" \ + -d "Ran into a full disk on the build server while compiling pi-mono. /var/log looks like it needs rotation. The build is blocked until there's space." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" + +# urgent failure +curl -H "Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + -H "Title: Production database unreachable" \ + -H "Tags: sos" \ + -H "Priority: 5" \ + -d "The primary Postgres instance stopped responding during a migration. Rolled back what we could, but the app is down." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" +``` + +## Alternative HTTP clients + +If `curl` is unavailable or blocked, use one of these instead: + +- **ht** (httpie-go): see [ht.md](references/ht.md) +- **HTTPie**: see [httpie.md](references/httpie.md) +- **wget**: see [wget.md](references/wget.md) +- **Python**: see [python.md](references/python.md) +- **Node.js**: see [nodejs.md](references/nodejs.md) diff --git a/skills/notifying-through-ntfy/references/ht.md b/skills/notifying-through-ntfy/references/ht.md new file mode 100644 index 0000000000000000000000000000000000000000..ef46b0e012ccb2bfbbec9f62dd219fa3aa0a9eb5 --- /dev/null +++ b/skills/notifying-through-ntfy/references/ht.md @@ -0,0 +1,42 @@ +# ht (httpie-go) + +`ht` uses httpie-style `Header:Value` syntax. The request body is passed via stdin. + +## Examples + +```bash +# normal success +ht POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Refactored authentication middleware in rumilo" \ + "Tags:hammer_and_wrench" <<'EOF' +Finished refactoring the auth middleware in rumilo. Session validation is cleaner now and all tests pass. +EOF + +# success with a relevant click URL +ht POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Updated AUR package for kagi-ken" \ + "Tags:package" \ + "Click:https://aur.archlinux.org/packages/kagi-ken" <<'EOF' +Bumped the kagi-ken AUR package to v0.4.2 and updated the checksums. +EOF + +# something went wrong +ht POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Build failed in pi-mono — disk full" \ + "Tags:rotating_light" \ + "Priority:4" <<'EOF' +Ran into a full disk on the build server while compiling pi-mono. /var/log looks like it needs rotation. The build is blocked until there's space. +EOF + +# urgent failure +ht POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Production database unreachable" \ + "Tags:sos" \ + "Priority:5" <<'EOF' +The primary Postgres instance stopped responding during a migration. Rolled back what we could, but the app is down. +EOF +``` diff --git a/skills/notifying-through-ntfy/references/httpie.md b/skills/notifying-through-ntfy/references/httpie.md new file mode 100644 index 0000000000000000000000000000000000000000..6333fb63a80b48d992dca29210187f6fb0f305f8 --- /dev/null +++ b/skills/notifying-through-ntfy/references/httpie.md @@ -0,0 +1,38 @@ +# HTTPie + +HTTPie (`http` command) uses `Header:Value` syntax for headers and reads the body from stdin with `<` or via echo/pipe. + +## Examples + +```bash +# normal success +echo 'Finished refactoring the auth middleware in rumilo. Session validation is cleaner now and all tests pass.' | \ + http POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Refactored authentication middleware in rumilo" \ + "Tags:hammer_and_wrench" + +# success with a relevant click URL +echo 'Bumped the kagi-ken AUR package to v0.4.2 and updated the checksums.' | \ + http POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Updated AUR package for kagi-ken" \ + "Tags:package" \ + "Click:https://aur.archlinux.org/packages/kagi-ken" + +# something went wrong +echo 'Ran into a full disk on the build server while compiling pi-mono. /var/log looks like it needs rotation. The build is blocked until there is space.' | \ + http POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Build failed in pi-mono — disk full" \ + "Tags:rotating_light" \ + "Priority:4" + +# urgent failure +echo 'The primary Postgres instance stopped responding during a migration. Rolled back what we could, but the app is down.' | \ + http POST "https://ntfy.sh/$NTFY_TOPIC_LLM" \ + "Authorization:Bearer $NTFY_ACCESS_TOKEN" \ + "Title:Production database unreachable" \ + "Tags:sos" \ + "Priority:5" +``` diff --git a/skills/notifying-through-ntfy/references/nodejs.md b/skills/notifying-through-ntfy/references/nodejs.md new file mode 100644 index 0000000000000000000000000000000000000000..e1be0fed9d2a14ec6204273a6173081ad7f97e95 --- /dev/null +++ b/skills/notifying-through-ntfy/references/nodejs.md @@ -0,0 +1,92 @@ +# Node.js + +Uses the built-in `https` module — no third-party dependencies required. Run each example as a standalone script. + +## Examples + +### Normal success + +```javascript +const https = require("https"); +const req = https.request( + `https://ntfy.sh/${process.env.NTFY_TOPIC_LLM}`, + { + method: "POST", + headers: { + Authorization: `Bearer ${process.env.NTFY_ACCESS_TOKEN}`, + Title: "Refactored authentication middleware in rumilo", + Tags: "hammer_and_wrench", + }, + }, + (res) => res.resume() +); +req.end( + "Finished refactoring the auth middleware in rumilo. Session validation is cleaner now and all tests pass." +); +``` + +### Success with a relevant click URL + +```javascript +const https = require("https"); +const req = https.request( + `https://ntfy.sh/${process.env.NTFY_TOPIC_LLM}`, + { + method: "POST", + headers: { + Authorization: `Bearer ${process.env.NTFY_ACCESS_TOKEN}`, + Title: "Updated AUR package for kagi-ken", + Tags: "package", + Click: "https://aur.archlinux.org/packages/kagi-ken", + }, + }, + (res) => res.resume() +); +req.end( + "Bumped the kagi-ken AUR package to v0.4.2 and updated the checksums." +); +``` + +### Something went wrong + +```javascript +const https = require("https"); +const req = https.request( + `https://ntfy.sh/${process.env.NTFY_TOPIC_LLM}`, + { + method: "POST", + headers: { + Authorization: `Bearer ${process.env.NTFY_ACCESS_TOKEN}`, + Title: "Build failed in pi-mono — disk full", + Tags: "rotating_light", + Priority: "4", + }, + }, + (res) => res.resume() +); +req.end( + "Ran into a full disk on the build server while compiling pi-mono. /var/log looks like it needs rotation. The build is blocked until there's space." +); +``` + +### Urgent failure + +```javascript +const https = require("https"); +const req = https.request( + `https://ntfy.sh/${process.env.NTFY_TOPIC_LLM}`, + { + method: "POST", + headers: { + Authorization: `Bearer ${process.env.NTFY_ACCESS_TOKEN}`, + Title: "Production database unreachable", + Tags: "sos", + Priority: "5", + }, + }, + (res) => res.resume() +); +req.end( + "The primary Postgres instance stopped responding during a migration. Rolled back what we could, but the app is down." +); +``` diff --git a/skills/notifying-through-ntfy/references/python.md b/skills/notifying-through-ntfy/references/python.md new file mode 100644 index 0000000000000000000000000000000000000000..8728a19a29e71ea29887756690f1f3bdabb9960e --- /dev/null +++ b/skills/notifying-through-ntfy/references/python.md @@ -0,0 +1,68 @@ +# Python + +Uses the standard library `urllib.request` — no third-party dependencies required. Run each example as a standalone script. + +## Examples + +### Normal success + +```python +import os, urllib.request + +req = urllib.request.Request( + f"https://ntfy.sh/{os.environ['NTFY_TOPIC_LLM']}", + data=b"Finished refactoring the auth middleware in rumilo. Session validation is cleaner now and all tests pass.", +) +req.add_header("Authorization", f"Bearer {os.environ['NTFY_ACCESS_TOKEN']}") +req.add_header("Title", "Refactored authentication middleware in rumilo") +req.add_header("Tags", "hammer_and_wrench") +urllib.request.urlopen(req) +``` + +### Success with a relevant click URL + +```python +import os, urllib.request + +req = urllib.request.Request( + f"https://ntfy.sh/{os.environ['NTFY_TOPIC_LLM']}", + data=b"Bumped the kagi-ken AUR package to v0.4.2 and updated the checksums.", +) +req.add_header("Authorization", f"Bearer {os.environ['NTFY_ACCESS_TOKEN']}") +req.add_header("Title", "Updated AUR package for kagi-ken") +req.add_header("Tags", "package") +req.add_header("Click", "https://aur.archlinux.org/packages/kagi-ken") +urllib.request.urlopen(req) +``` + +### Something went wrong + +```python +import os, urllib.request + +req = urllib.request.Request( + f"https://ntfy.sh/{os.environ['NTFY_TOPIC_LLM']}", + data=b"Ran into a full disk on the build server while compiling pi-mono. /var/log looks like it needs rotation. The build is blocked until there's space.", +) +req.add_header("Authorization", f"Bearer {os.environ['NTFY_ACCESS_TOKEN']}") +req.add_header("Title", "Build failed in pi-mono — disk full") +req.add_header("Tags", "rotating_light") +req.add_header("Priority", "4") +urllib.request.urlopen(req) +``` + +### Urgent failure + +```python +import os, urllib.request + +req = urllib.request.Request( + f"https://ntfy.sh/{os.environ['NTFY_TOPIC_LLM']}", + data=b"The primary Postgres instance stopped responding during a migration. Rolled back what we could, but the app is down.", +) +req.add_header("Authorization", f"Bearer {os.environ['NTFY_ACCESS_TOKEN']}") +req.add_header("Title", "Production database unreachable") +req.add_header("Tags", "sos") +req.add_header("Priority", "5") +urllib.request.urlopen(req) +``` diff --git a/skills/notifying-through-ntfy/references/wget.md b/skills/notifying-through-ntfy/references/wget.md new file mode 100644 index 0000000000000000000000000000000000000000..f6dbfcd93cdab51697d2ddf98caa4dbf6940800b --- /dev/null +++ b/skills/notifying-through-ntfy/references/wget.md @@ -0,0 +1,42 @@ +# wget + +`wget` can POST with `--post-data`. Headers are added with `--header`. + +## Examples + +```bash +# normal success +wget --quiet --output-document=- \ + --header="Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + --header="Title: Refactored authentication middleware in rumilo" \ + --header="Tags: hammer_and_wrench" \ + --post-data="Finished refactoring the auth middleware in rumilo. Session validation is cleaner now and all tests pass." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" + +# success with a relevant click URL +wget --quiet --output-document=- \ + --header="Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + --header="Title: Updated AUR package for kagi-ken" \ + --header="Tags: package" \ + --header="Click: https://aur.archlinux.org/packages/kagi-ken" \ + --post-data="Bumped the kagi-ken AUR package to v0.4.2 and updated the checksums." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" + +# something went wrong +wget --quiet --output-document=- \ + --header="Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + --header="Title: Build failed in pi-mono — disk full" \ + --header="Tags: rotating_light" \ + --header="Priority: 4" \ + --post-data="Ran into a full disk on the build server while compiling pi-mono. /var/log looks like it needs rotation. The build is blocked until there's space." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" + +# urgent failure +wget --quiet --output-document=- \ + --header="Authorization: Bearer $NTFY_ACCESS_TOKEN" \ + --header="Title: Production database unreachable" \ + --header="Tags: sos" \ + --header="Priority: 5" \ + --post-data="The primary Postgres instance stopped responding during a migration. Rolled back what we could, but the app is down." \ + "https://ntfy.sh/$NTFY_TOPIC_LLM" +```