281 lines
9.1 KiB
Markdown
281 lines
9.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Overview
|
|
|
|
`iamwaiting` is a Babashka CLI tool that sends Discord webhook notifications when Claude Code is waiting for user input. It's designed to be used as a hook in Claude Code to notify users on Discord when their attention is needed.
|
|
|
|
## Architecture
|
|
|
|
### Core Concept
|
|
|
|
The tool integrates with Claude Code's hook system to send real-time notifications to Discord when Claude is waiting for user input. This allows users to be notified on Discord when they need to return to their terminal/editor.
|
|
|
|
### Code Structure
|
|
|
|
The entire implementation is a single Babashka script (`iamwaiting`) with these key functions:
|
|
|
|
- `load-config` - Loads webhook URL, toggles, and Spiceflow URL from config file or environment variables
|
|
- `send-discord-webhook` - Makes HTTP POST request to Discord webhook API
|
|
- `get-tmux-session` - Detects current tmux session name (if running inside tmux)
|
|
- `format-waiting-message` - Formats the notification message with project context, tmux session, and Spiceflow link
|
|
- `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 (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
|
|
|
|
Configuration is stored in `~/.iamwaiting/config.edn` with the following structure:
|
|
|
|
```clojure
|
|
{:webhook-url "https://discord.com/api/webhooks/..."
|
|
:user-id "123456789012345678" ; Optional: Discord user ID for @mentions
|
|
:spiceflow-url "https://hostname:5173" ; Optional: Spiceflow URL for session links
|
|
:toggles {:idle-prompt true ; Enable idle 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:
|
|
- `IAMWAITING_WEBHOOK_URL` - Discord webhook URL (required)
|
|
- `IAMWAITING_USER_ID` - Discord user ID for @mentions (optional)
|
|
- `IAMWAITING_SPICEFLOW_URL` - Spiceflow base URL for session links (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
|
|
|
|
# Disable @mentions on permission prompts
|
|
iamwaiting toggle permission-prompt-ping off
|
|
```
|
|
|
|
**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
|
|
: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
|
|
{:webhook-url "https://discord.com/api/webhooks/..."
|
|
:toggles {:idle-prompt false
|
|
:permission-prompt false
|
|
:permission-prompt-ping false}}
|
|
```
|
|
|
|
**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
|
|
|
|
Install via symlink (recommended):
|
|
|
|
```bash
|
|
ln -s /path/to/repos/iamwaiting/iamwaiting ~/.local/bin/iamwaiting
|
|
```
|
|
|
|
This creates a symlink at `~/.local/bin/iamwaiting` pointing to the script (ensure `~/.local/bin` is in your PATH). Using a symlink means changes to the script are immediately available without reinstalling.
|
|
|
|
## Common Commands
|
|
|
|
**Note:** These examples assume `iamwaiting` is in your PATH.
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
# Initial setup - configure Discord webhook
|
|
iamwaiting setup
|
|
|
|
# Test the webhook configuration
|
|
iamwaiting test
|
|
|
|
# Show current configuration
|
|
iamwaiting status
|
|
```
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
# Send a basic waiting notification
|
|
iamwaiting
|
|
|
|
# Send notification with event data (used by hooks)
|
|
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
|
|
|
|
# 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
|
|
|
|
```bash
|
|
bb setup # Run setup wizard
|
|
bb test # Test webhook
|
|
bb run # Send notification
|
|
```
|
|
|
|
## Hook Integration
|
|
|
|
To use with Claude Code hooks, add to `~/.claude/settings.json`:
|
|
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"Notification": [
|
|
{
|
|
"matcher": "idle_prompt",
|
|
"hooks": [{"type": "command", "command": "iamwaiting"}]
|
|
},
|
|
{
|
|
"matcher": "permission_prompt",
|
|
"hooks": [{"type": "command", "command": "iamwaiting"}]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
This configuration triggers notifications for both idle prompts and permission requests.
|
|
|
|
## Important Implementation Details
|
|
|
|
### Discord Webhook API
|
|
|
|
The tool uses Discord's webhook API which requires:
|
|
- Webhook URL from Discord (Server Settings > Integrations > Webhooks)
|
|
- POST request with JSON payload containing `content`, `username`, and `avatar_url`
|
|
- No authentication required (webhook URL acts as the credential)
|
|
|
|
### Message Format
|
|
|
|
Notifications include:
|
|
- ⏳ Waiting indicator
|
|
- 📁 Current working directory / project name
|
|
- 🖥️ Tmux session name (if running inside tmux)
|
|
- 🔗 Spiceflow session link (if Spiceflow URL configured and running in tmux)
|
|
- 🕐 Timestamp (HH:mm:ss format)
|
|
- @mention (if user ID is configured, it's a permission prompt, and ping toggle is enabled)
|
|
|
|
Example message (with Spiceflow link):
|
|
```
|
|
⏳ **Claude is waiting** in `ajet-industries`
|
|
📁 Path: `/home/user/repos/ajet-industries`
|
|
🖥️ Tmux: `spiceflow-bold-sun-9841`
|
|
🔗 **[Open in Spiceflow](https://hostname:5173/session/spiceflow-bold-sun-9841)**
|
|
🕐 Time: 14:23:45
|
|
```
|
|
|
|
Example message (permission prompt with ping enabled):
|
|
```
|
|
<@123456789012345678> ⏳ **Claude is waiting** in `ajet-industries`
|
|
📁 Path: `/home/user/repos/ajet-industries`
|
|
🖥️ Tmux: `spiceflow-bold-sun-9841`
|
|
🔗 **[Open in Spiceflow](https://hostname:5173/session/spiceflow-bold-sun-9841)**
|
|
🕐 Time: 14:23:45
|
|
📢 Type: `permission_prompt`
|
|
```
|
|
|
|
Example message (without tmux/Spiceflow):
|
|
```
|
|
⏳ **Claude is waiting** in `ajet-industries`
|
|
📁 Path: `/home/user/repos/ajet-industries`
|
|
🕐 Time: 14:23:45
|
|
```
|
|
|
|
### Error Handling
|
|
|
|
- Missing configuration prompts user to run `./iamwaiting setup`
|
|
- Failed webhook requests exit with code 1 and display error message
|
|
- Invalid webhook URLs are caught and reported
|
|
- Network errors are caught and reported gracefully
|
|
|
|
### Dependencies
|
|
|
|
Uses Babashka standard libraries:
|
|
- `babashka.http-client` - HTTP requests to Discord API
|
|
- `babashka.fs` - File system operations for config management
|
|
- `babashka.process` - Shell command execution (for tmux session detection)
|
|
- `cheshire.core` - JSON encoding/decoding
|
|
- `clojure.string` - String manipulation
|
|
|
|
## Development
|
|
|
|
The script is self-contained with minimal dependencies. To modify:
|
|
|
|
1. Edit the `iamwaiting` script directly
|
|
2. Test changes using `iamwaiting test` (or `./iamwaiting test` if running from the repo directory)
|
|
3. The script is executable via shebang `#!/usr/bin/env bb`
|
|
|
|
## Security Considerations
|
|
|
|
- Webhook URL should be kept secret (it allows posting to your Discord channel)
|
|
- Config file at `~/.iamwaiting/config.edn` has standard file permissions
|
|
- No sensitive data is sent in notifications beyond directory paths
|
|
- Webhook URLs are never logged or displayed (except during setup)
|
|
|
|
## Context: Standalone Usage
|
|
|
|
This tool is a standalone repository and can be used with any project. It's particularly useful when working on long-running tasks where Claude may need user input while the user is away from their terminal.
|
|
|
|
## Future Enhancements
|
|
|
|
Possible improvements:
|
|
- Support for multiple notification channels
|
|
- Customizable message templates
|
|
- Integration with other notification services (Slack, Telegram, etc.)
|
|
- Retry logic for failed webhook requests
|
|
- Rate limiting to avoid spam
|