add ping toggle

This commit is contained in:
Adam Jeniski 2026-01-08 03:01:26 -05:00
parent f9ec72d808
commit bec42359e0
3 changed files with 129 additions and 28 deletions

View File

@ -33,8 +33,9 @@ Configuration is stored in `~/.iamwaiting/config.edn` with the following structu
```clojure ```clojure
{:webhook-url "https://discord.com/api/webhooks/..." {:webhook-url "https://discord.com/api/webhooks/..."
:user-id "123456789012345678" ; Optional: Discord user ID for @mentions :user-id "123456789012345678" ; Optional: Discord user ID for @mentions
:toggles {:idle-prompt true ; Enable idle prompt notifications :toggles {:idle-prompt true ; Enable idle prompt notifications
:permission-prompt true}} ; Enable permission prompt notifications :permission-prompt true ; Enable permission prompt notifications
:permission-prompt-ping true}} ; Enable @mentions on permission prompts
``` ```
Alternatively, configuration can be set via environment variables: Alternatively, configuration can be set via environment variables:
@ -55,6 +56,9 @@ iamwaiting toggle idle-prompt off
# Enable permission prompt notifications # Enable permission prompt notifications
iamwaiting toggle permission-prompt on iamwaiting toggle permission-prompt on
# Disable @mentions on permission prompts
iamwaiting toggle permission-prompt-ping off
``` ```
**Manually editing config file:** **Manually editing config file:**
@ -62,15 +66,33 @@ iamwaiting toggle permission-prompt on
;; Only get notified for permission prompts ;; Only get notified for permission prompts
{:webhook-url "https://discord.com/api/webhooks/..." {:webhook-url "https://discord.com/api/webhooks/..."
:toggles {:idle-prompt false :toggles {:idle-prompt false
:permission-prompt true}} :permission-prompt true
:permission-prompt-ping true}}
;; Get permission prompt notifications but don't @mention
{:webhook-url "https://discord.com/api/webhooks/..."
:user-id "123456789012345678"
:toggles {:idle-prompt true
:permission-prompt true
:permission-prompt-ping false}}
;; Disable all notifications ;; Disable all notifications
{:webhook-url "https://discord.com/api/webhooks/..." {:webhook-url "https://discord.com/api/webhooks/..."
:toggles {:idle-prompt false :toggles {:idle-prompt false
:permission-prompt false}} :permission-prompt false
:permission-prompt-ping false}}
``` ```
**Default behavior:** If toggles are not specified in the config file, both notification types are enabled. **Default behavior:** If toggles are not specified in the config file, all notification features are enabled.
### Permission Prompt Pings
The `:permission-prompt-ping` toggle controls whether you get @mentioned (pinged) on permission prompts. This is useful when:
- You want to disable pings during focus time
- You want notifications but not intrusive @mentions
- You want to keep your user ID configured without getting pinged
**Note:** This toggle only has effect if you have a user ID configured. The ping toggle defaults to `true` for backwards compatibility.
## Installation ## Installation
@ -123,6 +145,12 @@ iamwaiting toggle idle-prompt on
# Disable permission prompt notifications # Disable permission prompt notifications
iamwaiting toggle permission-prompt off iamwaiting toggle permission-prompt off
# Disable @mentions on permission prompts
iamwaiting toggle permission-prompt-ping off
# Enable @mentions on permission prompts
iamwaiting toggle permission-prompt-ping on
``` ```
### Running via Babashka Tasks ### Running via Babashka Tasks
@ -171,16 +199,16 @@ Notifications include:
- ⏳ Waiting indicator - ⏳ Waiting indicator
- 📁 Current working directory / project name - 📁 Current working directory / project name
- 🕐 Timestamp (HH:mm:ss format) - 🕐 Timestamp (HH:mm:ss format)
- @mention (if user ID is configured and it's a permission prompt) - @mention (if user ID is configured, it's a permission prompt, and ping toggle is enabled)
Example message (normal prompt): Example message (idle prompt):
``` ```
**Claude is waiting** in `ajet-industries` **Claude is waiting** in `ajet-industries`
📁 Path: `/home/user/repos/ajet-industries` 📁 Path: `/home/user/repos/ajet-industries`
🕐 Time: 14:23:45 🕐 Time: 14:23:45
``` ```
Example message (permission prompt with user ID configured): Example message (permission prompt with ping enabled):
``` ```
<@123456789012345678> ⏳ **Claude is waiting** in `ajet-industries` <@123456789012345678> ⏳ **Claude is waiting** in `ajet-industries`
📁 Path: `/home/user/repos/ajet-industries` 📁 Path: `/home/user/repos/ajet-industries`
@ -188,6 +216,14 @@ Example message (permission prompt with user ID configured):
📢 Type: `permission_prompt` 📢 Type: `permission_prompt`
``` ```
Example message (permission prompt with ping disabled):
```
**Claude is waiting** in `ajet-industries`
📁 Path: `/home/user/repos/ajet-industries`
🕐 Time: 14:23:45
📢 Type: `permission_prompt`
```
### Error Handling ### Error Handling
- Missing configuration prompts user to run `./iamwaiting setup` - Missing configuration prompts user to run `./iamwaiting setup`

View File

@ -126,15 +126,41 @@ bb run # Send waiting notification
Configuration is stored in `~/.iamwaiting/config.edn`: Configuration is stored in `~/.iamwaiting/config.edn`:
```clojure ```clojure
{:webhook-url "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"} {:webhook-url "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
:user-id "123456789012345678" ; Optional: for @mentions
:toggles {:idle-prompt true
:permission-prompt true
:permission-prompt-ping true}}
``` ```
You can also set the webhook URL via environment variable: You can also set the webhook URL via environment variable:
```bash ```bash
export IAMWAITING_WEBHOOK_URL="https://discord.com/api/webhooks/..." export IAMWAITING_WEBHOOK_URL="https://discord.com/api/webhooks/..."
export IAMWAITING_USER_ID="123456789012345678" # Optional
``` ```
### Advanced Configuration
Control which notifications you receive using toggles:
```bash
# Show current toggle status
iamwaiting toggle status
# Toggle notification types on/off
iamwaiting toggle idle-prompt on|off
iamwaiting toggle permission-prompt on|off
# Control @mentions on permission prompts
iamwaiting toggle permission-prompt-ping on|off
```
**Use cases:**
- **Focus time:** Disable pings but keep notifications (`permission-prompt-ping off`)
- **Critical only:** Only notify on permission prompts (`idle-prompt off`)
- **Silent mode:** Disable all notifications (both toggles `off`)
## How It Works ## How It Works
When Claude Code is waiting for user input, the `agent-waiting-for-user` hook is triggered, which: When Claude Code is waiting for user input, the `agent-waiting-for-user` hook is triggered, which:
@ -149,15 +175,33 @@ The notification appears in your Discord channel with:
- ⏳ Waiting indicator - ⏳ Waiting indicator
- 📁 Project name and path - 📁 Project name and path
- 🕐 Timestamp - 🕐 Timestamp
- @mention (if configured and enabled for permission prompts)
## Example Notification ## Example Notifications
**Idle prompt (standard notification):**
``` ```
**Claude is waiting** in `my-project` **Claude is waiting** in `my-project`
📁 Path: `/home/user/repos/my-project` 📁 Path: `/home/user/repos/my-project`
🕐 Time: 14:23:45 🕐 Time: 14:23:45
``` ```
**Permission prompt with ping enabled:**
```
<@123456789012345678> ⏳ **Claude is waiting** in `my-project`
📁 Path: `/home/user/repos/my-project`
🕐 Time: 14:23:45
📢 Type: `permission_prompt`
```
**Permission prompt with ping disabled:**
```
**Claude is waiting** in `my-project`
📁 Path: `/home/user/repos/my-project`
🕐 Time: 14:23:45
📢 Type: `permission_prompt`
```
## Troubleshooting ## Troubleshooting
**"No webhook URL configured"** **"No webhook URL configured"**

View File

@ -18,7 +18,8 @@
(System/getenv "IAMWAITING_USER_ID")) (System/getenv "IAMWAITING_USER_ID"))
toggles (or (:toggles config) toggles (or (:toggles config)
{:idle-prompt true {:idle-prompt true
:permission-prompt true})] :permission-prompt true
:permission-prompt-ping true})]
{:webhook-url webhook-url {:webhook-url webhook-url
:user-id user-id :user-id user-id
:toggles toggles})) :toggles toggles}))
@ -38,7 +39,7 @@
(catch Exception e (catch Exception e
{:success false :error (.getMessage e)}))) {:success false :error (.getMessage e)})))
(defn format-waiting-message [event-data user-id] (defn format-waiting-message [event-data user-id toggles]
"Format a message for Claude waiting event" "Format a message for Claude waiting event"
(let [cwd (or (:cwd event-data) (System/getProperty "user.dir")) (let [cwd (or (:cwd event-data) (System/getProperty "user.dir"))
project-name (fs/file-name cwd) project-name (fs/file-name cwd)
@ -54,8 +55,9 @@
;; Check if this is a permission prompt ;; Check if this is a permission prompt
is-permission-prompt? (or (= notification-type "permission_prompt") is-permission-prompt? (or (= notification-type "permission_prompt")
(some? permission-mode)) (some? permission-mode))
;; Ping user if configured and it's a permission prompt ;; Ping user if configured, it's a permission prompt, and ping toggle is enabled
user-ping (when (and user-id is-permission-prompt?) ping-enabled? (get toggles :permission-prompt-ping true)
user-ping (when (and user-id is-permission-prompt? ping-enabled?)
(str "<@" user-id "> "))] (str "<@" user-id "> "))]
(str user-ping (str user-ping
"⏳ **Claude is waiting** in `" project-name "`\n" "⏳ **Claude is waiting** in `" project-name "`\n"
@ -99,10 +101,20 @@
(let [perm-response (str/lower-case (str/trim (read-line))) (let [perm-response (str/lower-case (str/trim (read-line)))
perm-enabled? (not= perm-response "n") perm-enabled? (not= perm-response "n")
;; Ask about ping preference if user ID provided
ping-enabled? (if user-id
(do
(print "@mention you on permission prompts? (y/n, default: y): ")
(flush)
(let [ping-response (str/lower-case (str/trim (read-line)))]
(not= ping-response "n")))
true)
;; Build config with toggles ;; Build config with toggles
config (cond-> {:webhook-url webhook-url config (cond-> {:webhook-url webhook-url
:toggles {:idle-prompt idle-enabled? :toggles {:idle-prompt idle-enabled?
:permission-prompt perm-enabled?}} :permission-prompt perm-enabled?
:permission-prompt-ping ping-enabled?}}
user-id (assoc :user-id user-id))] user-id (assoc :user-id user-id))]
;; Create config directory ;; Create config directory
@ -112,7 +124,8 @@
(spit config-file (pr-str config)) (spit config-file (pr-str config))
(println "\n✓ Configuration saved to" config-file) (println "\n✓ Configuration saved to" config-file)
(when user-id (when user-id
(println "✓ User ID configured - you will be @mentioned on permission prompts")) (println (str "✓ User ID configured - you will be @mentioned on permission prompts: "
(if ping-enabled? "enabled" "disabled"))))
(println (str "✓ Idle prompts: " (if idle-enabled? "enabled" "disabled"))) (println (str "✓ Idle prompts: " (if idle-enabled? "enabled" "disabled")))
(println (str "✓ Permission prompts: " (if perm-enabled? "enabled" "disabled"))) (println (str "✓ Permission prompts: " (if perm-enabled? "enabled" "disabled")))
(println "\nTest the webhook with: ./iamwaiting test")))))) (println "\nTest the webhook with: ./iamwaiting test"))))))
@ -177,7 +190,7 @@
(println (str "Notification disabled for " toggle-key))) (println (str "Notification disabled for " toggle-key)))
;; Original notification logic ;; Original notification logic
(let [message (format-waiting-message event-data (:user-id config)) (let [message (format-waiting-message event-data (:user-id config) (:toggles config))
result (send-discord-webhook (:webhook-url config) message)] result (send-discord-webhook (:webhook-url config) message)]
(if (:success result) (if (:success result)
(println "✓ Notification sent") (println "✓ Notification sent")
@ -191,6 +204,7 @@
feature-key (case feature feature-key (case feature
"idle-prompt" :idle-prompt "idle-prompt" :idle-prompt
"permission-prompt" :permission-prompt "permission-prompt" :permission-prompt
"permission-prompt-ping" :permission-prompt-ping
nil) nil)
action-bool (case action action-bool (case action
"on" true "on" true
@ -200,7 +214,7 @@
(cond (cond
(nil? feature-key) (nil? feature-key)
(do (do
(println "❌ Invalid feature. Use: idle-prompt | permission-prompt") (println "❌ Invalid feature. Use: idle-prompt | permission-prompt | permission-prompt-ping")
(System/exit 1)) (System/exit 1))
(nil? action-bool) (nil? action-bool)
@ -219,21 +233,27 @@
(let [config (load-config) (let [config (load-config)
toggles (or (:toggles config) toggles (or (:toggles config)
{:idle-prompt true {:idle-prompt true
:permission-prompt true})] :permission-prompt true
:permission-prompt-ping true})
user-id (:user-id config)]
(println "📊 Current Toggle Status\n") (println "📊 Current Toggle Status\n")
(println (str "Idle prompts: " (if (:idle-prompt toggles) "✅ enabled" "❌ disabled"))) (println (str "Idle prompts: " (if (:idle-prompt toggles) "✅ enabled" "❌ disabled")))
(println (str "Permission prompts: " (if (:permission-prompt toggles) "✅ enabled" "❌ disabled"))))) (println (str "Permission prompts: " (if (:permission-prompt toggles) "✅ enabled" "❌ disabled")))
(println (str "Permission ping: " (if (:permission-prompt-ping toggles) "✅ enabled" "❌ disabled")))
(when user-id
(println (str "\n👤 User ID configured: " user-id)))))
(defn show-help [] (defn show-help []
(println "iamwaiting - Send Discord notifications when Claude is waiting") (println "iamwaiting - Send Discord notifications when Claude is waiting")
(println "") (println "")
(println "Usage:") (println "Usage:")
(println " iamwaiting setup Set up Discord webhook configuration") (println " iamwaiting setup Set up Discord webhook configuration")
(println " iamwaiting test Test webhook configuration") (println " iamwaiting test Test webhook configuration")
(println " iamwaiting toggle status Show current toggle status") (println " iamwaiting toggle status Show current toggle status")
(println " iamwaiting toggle idle-prompt <on|off> Toggle idle prompt notifications") (println " iamwaiting toggle idle-prompt <on|off> Toggle idle prompt notifications")
(println " iamwaiting toggle permission-prompt <on|off> Toggle permission prompt notifications") (println " iamwaiting toggle permission-prompt <on|off> Toggle permission prompt notifications")
(println " iamwaiting [event-data-json] Send waiting notification") (println " iamwaiting toggle permission-prompt-ping <on|off> Toggle @mentions on permission prompts")
(println " iamwaiting [event-data-json] Send waiting notification")
(println "") (println "")
(println "Configuration:") (println "Configuration:")
(println " Config file: ~/.iamwaiting/config.edn") (println " Config file: ~/.iamwaiting/config.edn")
@ -258,8 +278,9 @@
"status" (show-toggle-status) "status" (show-toggle-status)
"idle-prompt" (toggle-feature "idle-prompt" (nth args 2 nil)) "idle-prompt" (toggle-feature "idle-prompt" (nth args 2 nil))
"permission-prompt" (toggle-feature "permission-prompt" (nth args 2 nil)) "permission-prompt" (toggle-feature "permission-prompt" (nth args 2 nil))
"permission-prompt-ping" (toggle-feature "permission-prompt-ping" (nth args 2 nil))
(do (do
(println "Usage: iamwaiting toggle <status|idle-prompt|permission-prompt> [on|off]") (println "Usage: iamwaiting toggle <status|idle-prompt|permission-prompt|permission-prompt-ping> [on|off]")
(System/exit 1)))) (System/exit 1))))
"help" (show-help) "help" (show-help)
"--help" (show-help) "--help" (show-help)