add feature toggles
This commit is contained in:
parent
34ab774759
commit
f9ec72d808
60
CLAUDE.md
60
CLAUDE.md
@ -16,12 +16,14 @@ The tool integrates with Claude Code's hook system to send real-time notificatio
|
||||
|
||||
The entire implementation is a single Babashka script (`iamwaiting`) with these key functions:
|
||||
|
||||
- `load-config` - Loads webhook URL from config file or environment variable
|
||||
- `load-config` - Loads webhook URL and toggles from config file or environment variable
|
||||
- `send-discord-webhook` - Makes HTTP POST request to Discord webhook API
|
||||
- `format-waiting-message` - Formats the notification message with project context
|
||||
- `setup-config` - Interactive setup wizard for webhook configuration
|
||||
- `test-webhook` - Sends a test message to verify configuration
|
||||
- `send-waiting-notification` - Main function that sends the notification
|
||||
- `send-waiting-notification` - Main function that sends the notification (respects toggles)
|
||||
- `toggle-feature` - Toggle notification features on or off via CLI
|
||||
- `show-toggle-status` - Display current toggle status
|
||||
- `-main` - CLI argument parsing and entry point
|
||||
|
||||
### Configuration
|
||||
@ -30,13 +32,46 @@ Configuration is stored in `~/.iamwaiting/config.edn` with the following structu
|
||||
|
||||
```clojure
|
||||
{: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
|
||||
:permission-prompt true}} ; Enable permission prompt notifications
|
||||
```
|
||||
|
||||
Alternatively, configuration can be set via environment variables:
|
||||
- `IAMWAITING_WEBHOOK_URL` - Discord webhook URL (required)
|
||||
- `IAMWAITING_USER_ID` - Discord user ID for @mentions (optional)
|
||||
|
||||
### Notification Toggles
|
||||
|
||||
Control which types of notifications are sent using the `:toggles` configuration key. If toggles are not specified, both notification types are enabled by default (backwards compatible).
|
||||
|
||||
**Managing toggles via CLI:**
|
||||
```bash
|
||||
# Show current toggle status
|
||||
iamwaiting toggle status
|
||||
|
||||
# Disable idle prompt notifications
|
||||
iamwaiting toggle idle-prompt off
|
||||
|
||||
# Enable permission prompt notifications
|
||||
iamwaiting toggle permission-prompt on
|
||||
```
|
||||
|
||||
**Manually editing config file:**
|
||||
```clojure
|
||||
;; Only get notified for permission prompts
|
||||
{:webhook-url "https://discord.com/api/webhooks/..."
|
||||
:toggles {:idle-prompt false
|
||||
:permission-prompt true}}
|
||||
|
||||
;; Disable all notifications
|
||||
{:webhook-url "https://discord.com/api/webhooks/..."
|
||||
:toggles {:idle-prompt false
|
||||
:permission-prompt false}}
|
||||
```
|
||||
|
||||
**Default behavior:** If toggles are not specified in the config file, both notification types are enabled.
|
||||
|
||||
## Installation
|
||||
|
||||
Install via bbin (recommended):
|
||||
@ -71,6 +106,25 @@ iamwaiting
|
||||
iamwaiting '{"cwd": "/path/to/project"}'
|
||||
```
|
||||
|
||||
### Toggle Management
|
||||
|
||||
```bash
|
||||
# Show current toggle status
|
||||
iamwaiting toggle status
|
||||
|
||||
# Disable idle prompt notifications
|
||||
iamwaiting toggle idle-prompt off
|
||||
|
||||
# Enable permission prompt notifications
|
||||
iamwaiting toggle permission-prompt on
|
||||
|
||||
# Enable idle prompt notifications
|
||||
iamwaiting toggle idle-prompt on
|
||||
|
||||
# Disable permission prompt notifications
|
||||
iamwaiting toggle permission-prompt off
|
||||
```
|
||||
|
||||
### Running via Babashka Tasks
|
||||
|
||||
```bash
|
||||
|
||||
134
iamwaiting
134
iamwaiting
@ -15,9 +15,13 @@
|
||||
webhook-url (or (:webhook-url config)
|
||||
(System/getenv "IAMWAITING_WEBHOOK_URL"))
|
||||
user-id (or (:user-id config)
|
||||
(System/getenv "IAMWAITING_USER_ID"))]
|
||||
(System/getenv "IAMWAITING_USER_ID"))
|
||||
toggles (or (:toggles config)
|
||||
{:idle-prompt true
|
||||
:permission-prompt true})]
|
||||
{:webhook-url webhook-url
|
||||
:user-id user-id}))
|
||||
:user-id user-id
|
||||
:toggles toggles}))
|
||||
|
||||
(defn send-discord-webhook [webhook-url message]
|
||||
"Send a message to Discord via webhook"
|
||||
@ -81,20 +85,37 @@
|
||||
(print "> ")
|
||||
(flush)
|
||||
(let [user-id-input (str/trim (read-line))
|
||||
user-id (when-not (str/blank? user-id-input) user-id-input)
|
||||
config (if user-id
|
||||
{:webhook-url webhook-url :user-id user-id}
|
||||
{:webhook-url webhook-url})]
|
||||
user-id (when-not (str/blank? user-id-input) user-id-input)]
|
||||
|
||||
;; Create config directory
|
||||
(fs/create-dirs (fs/parent config-file))
|
||||
;; NEW: Toggle prompts
|
||||
(println "\n📬 Notification Preferences")
|
||||
(print "Enable notifications for idle prompts? (y/n, default: y): ")
|
||||
(flush)
|
||||
(let [idle-response (str/lower-case (str/trim (read-line)))
|
||||
idle-enabled? (not= idle-response "n")]
|
||||
|
||||
;; Write config
|
||||
(spit config-file (pr-str config))
|
||||
(println "\n✓ Configuration saved to" config-file)
|
||||
(when user-id
|
||||
(println "✓ User ID configured - you will be @mentioned on permission prompts"))
|
||||
(println "\nTest the webhook with: ./iamwaiting test"))))
|
||||
(print "Enable notifications for permission prompts? (y/n, default: y): ")
|
||||
(flush)
|
||||
(let [perm-response (str/lower-case (str/trim (read-line)))
|
||||
perm-enabled? (not= perm-response "n")
|
||||
|
||||
;; Build config with toggles
|
||||
config (cond-> {:webhook-url webhook-url
|
||||
:toggles {:idle-prompt idle-enabled?
|
||||
:permission-prompt perm-enabled?}}
|
||||
user-id (assoc :user-id user-id))]
|
||||
|
||||
;; Create config directory
|
||||
(fs/create-dirs (fs/parent config-file))
|
||||
|
||||
;; Write config
|
||||
(spit config-file (pr-str config))
|
||||
(println "\n✓ Configuration saved to" config-file)
|
||||
(when user-id
|
||||
(println "✓ User ID configured - you will be @mentioned on permission prompts"))
|
||||
(println (str "✓ Idle prompts: " (if idle-enabled? "enabled" "disabled")))
|
||||
(println (str "✓ Permission prompts: " (if perm-enabled? "enabled" "disabled")))
|
||||
(println "\nTest the webhook with: ./iamwaiting test"))))))
|
||||
|
||||
(defn test-webhook []
|
||||
"Test the webhook configuration"
|
||||
@ -141,21 +162,78 @@
|
||||
(json/parse-string (first event-data-args) true)
|
||||
(catch Exception _ {})))
|
||||
{})
|
||||
message (format-waiting-message event-data (:user-id config))
|
||||
result (send-discord-webhook (:webhook-url config) message)]
|
||||
(if (:success result)
|
||||
(println "✓ Notification sent")
|
||||
(do
|
||||
(println "✗ Failed to send notification:" (:error result))
|
||||
(System/exit 1)))))))
|
||||
;; Determine notification type
|
||||
notification-type (:notification_type event-data)
|
||||
permission-mode (:permission_mode event-data)
|
||||
is-permission-prompt? (or (= notification-type "permission_prompt")
|
||||
(some? permission-mode))
|
||||
;; Determine which toggle to check
|
||||
toggle-key (if is-permission-prompt? :permission-prompt :idle-prompt)
|
||||
enabled? (get-in config [:toggles toggle-key] true)]
|
||||
|
||||
;; Exit early if notification type is disabled
|
||||
(if-not enabled?
|
||||
(when (System/getenv "DEBUG")
|
||||
(println (str "Notification disabled for " toggle-key)))
|
||||
|
||||
;; Original notification logic
|
||||
(let [message (format-waiting-message event-data (:user-id config))
|
||||
result (send-discord-webhook (:webhook-url config) message)]
|
||||
(if (:success result)
|
||||
(println "✓ Notification sent")
|
||||
(do
|
||||
(println "✗ Failed to send notification:" (:error result))
|
||||
(System/exit 1)))))))))
|
||||
|
||||
(defn toggle-feature [feature action]
|
||||
"Toggle a notification feature on or off"
|
||||
(let [config (load-config)
|
||||
feature-key (case feature
|
||||
"idle-prompt" :idle-prompt
|
||||
"permission-prompt" :permission-prompt
|
||||
nil)
|
||||
action-bool (case action
|
||||
"on" true
|
||||
"off" false
|
||||
nil)]
|
||||
|
||||
(cond
|
||||
(nil? feature-key)
|
||||
(do
|
||||
(println "❌ Invalid feature. Use: idle-prompt | permission-prompt")
|
||||
(System/exit 1))
|
||||
|
||||
(nil? action-bool)
|
||||
(do
|
||||
(println "❌ Invalid action. Use: on | off")
|
||||
(System/exit 1))
|
||||
|
||||
:else
|
||||
(let [updated-config (assoc-in config [:toggles feature-key] action-bool)]
|
||||
(fs/create-dirs (fs/parent config-file))
|
||||
(spit config-file (pr-str updated-config))
|
||||
(println (str "✅ " feature " notifications: " action))))))
|
||||
|
||||
(defn show-toggle-status []
|
||||
"Display current toggle status"
|
||||
(let [config (load-config)
|
||||
toggles (or (:toggles config)
|
||||
{:idle-prompt true
|
||||
:permission-prompt true})]
|
||||
(println "📊 Current Toggle Status\n")
|
||||
(println (str "Idle prompts: " (if (:idle-prompt toggles) "✅ enabled" "❌ disabled")))
|
||||
(println (str "Permission prompts: " (if (:permission-prompt toggles) "✅ enabled" "❌ disabled")))))
|
||||
|
||||
(defn show-help []
|
||||
(println "iamwaiting - Send Discord notifications when Claude is waiting")
|
||||
(println "")
|
||||
(println "Usage:")
|
||||
(println " iamwaiting setup Set up Discord webhook configuration")
|
||||
(println " iamwaiting test Test webhook configuration")
|
||||
(println " iamwaiting [event-data-json] Send waiting notification")
|
||||
(println " iamwaiting setup Set up Discord webhook configuration")
|
||||
(println " iamwaiting test Test webhook configuration")
|
||||
(println " iamwaiting toggle status Show current toggle status")
|
||||
(println " iamwaiting toggle idle-prompt <on|off> Toggle idle prompt notifications")
|
||||
(println " iamwaiting toggle permission-prompt <on|off> Toggle permission prompt notifications")
|
||||
(println " iamwaiting [event-data-json] Send waiting notification")
|
||||
(println "")
|
||||
(println "Configuration:")
|
||||
(println " Config file: ~/.iamwaiting/config.edn")
|
||||
@ -175,6 +253,14 @@
|
||||
(case command
|
||||
"setup" (setup-config)
|
||||
"test" (test-webhook)
|
||||
"toggle" (let [subcommand (second args)]
|
||||
(case subcommand
|
||||
"status" (show-toggle-status)
|
||||
"idle-prompt" (toggle-feature "idle-prompt" (nth args 2 nil))
|
||||
"permission-prompt" (toggle-feature "permission-prompt" (nth args 2 nil))
|
||||
(do
|
||||
(println "Usage: iamwaiting toggle <status|idle-prompt|permission-prompt> [on|off]")
|
||||
(System/exit 1))))
|
||||
"help" (show-help)
|
||||
"--help" (show-help)
|
||||
"-h" (show-help)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user