Cross-platform terminal notification system for long-running commands. Get desktop notifications, sounds, and external alerts (Slack, Discord, Telegram, and more) when your builds, deploys, and tests finish.
Works with bash and zsh on macOS, Linux, WSL, and Windows. Notify via desktop popup, sound, voice, Slack, Discord, Telegram, Email, WhatsApp, or webhook. Integrates with AI CLIs: Claude Code, Codex, Gemini, Copilot, Cursor, and Aider.
"I'm not needy. I simply believe every completed process deserves recognition." - shelldone
- Features
- Quick Start
- Installation
- Usage
- Configuration
- External Notifications
- Commands Reference
- Platform Support
- Alternatives
- Contributing
- License
| Document | Description |
|---|---|
| Commands Reference | Every CLI command with detailed ASCII flowcharts |
| Architecture | System design, notification flow, module loading, state management |
| External Channels | Setup guides for Slack, Discord, Telegram, Email, WhatsApp, webhooks |
| Configuration | Full environment variable reference and config file format |
| Troubleshooting | Debug mode, common issues, and fixes |
"Running without me is like running without set -e. Technically possible. Spiritually wrong." - shelldone
- Desktop notifications on macOS, Linux, WSL, and Windows (Git Bash/MSYS2/Cygwin)
- Auto-notify for any command that runs longer than a configurable threshold (default: 10s)
- Sound alerts with customizable success/failure sounds (system sounds or custom file paths)
- Text-to-speech announcements (optional)
- External notifications via Slack, Discord, Telegram, Email, WhatsApp, or generic webhooks
- AI CLI integration - Claude Code, Codex CLI, Gemini CLI, Copilot CLI, Cursor (hook-based), plus Aider (wrapper)
- Smart focus detection - suppresses notifications when you're already looking at the terminal
- Glob-based exclusions - skip commands like
npm*,ssh,vim, etc. - Notification control - per-channel mute, toggle layers (sound/desktop/voice/channels), schedule quiet hours
- Shell completions for bash and zsh
- Zero dependencies - uses only built-in system tools (
curl/wgetoptional for external channels) - Fast - adds less than 50ms to shell startup time
"You left your terminal. I waited. I notified. You're welcome." - shelldone
# Clone and install
git clone https://github.com/nareshnavinash/shelldone.git
cd shelldone
./install.sh
# Verify your setup
shelldone status
# Send a test notification
shelldone test-notify
# Wrap any command
alert make buildAfter installation, commands running longer than 10 seconds automatically trigger notifications - no wrapper needed.
git clone https://github.com/nareshnavinash/shelldone.git
cd shelldone
./install.shThe install script detects your platform, makes scripts executable, adds shell integration to your rc files, and sets up hooks for all detected AI CLIs.
make install # installs to /usr/local
make install PREFIX=~/.local # installs to ~/.localbrew tap nareshnavinash/tap
brew install shelldone# Add the GPG key and repository
curl -fsSL https://nareshnavinash.github.io/shelldone/KEY.gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/shelldone-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/shelldone-archive-keyring.gpg] https://nareshnavinash.github.io/shelldone stable main" \
| sudo tee /etc/apt/sources.list.d/shelldone.list
sudo apt update && sudo apt install shelldonescoop bucket add shelldone https://github.com/nareshnavinash/scoop-bucket
scoop install shelldoneComing soon - submitted for review.
choco install shelldoneAdd to your .zshrc or .bashrc:
eval "$(shelldone init zsh)" # for zsh
eval "$(shelldone init bash)" # for bashOr auto-configure everything (rc files + AI CLI hooks):
shelldone setup"If you wanted a quiet terminal, you shouldn't have installed something this thorough." - shelldone
Run the interactive setup wizard to configure everything at once:
shelldone setup # interactive wizard (auto-detects shell, configures RC files, installs AI hooks)
shelldone setup --full # advanced mode (also configures notification preferences and external channels)
shelldone setup --quick # non-interactive (shell init + AI hooks, sensible defaults)The wizard walks through:
- Shell integration - detects
.zshrc/.bashrcand adds theevalblock - Notification preferences (advanced) - threshold, filter, voice, focus detection
- External channels (advanced) - add/test Slack, Discord, Telegram, etc.
- AI CLI hooks - detects installed AI CLIs and installs hooks
- Health check - verifies everything is working
You can also set up individual components:
shelldone setup ai-hooks # install hooks for all detected AI CLIs
shelldone setup claude-hook # Claude Code only
shelldone setup codex-hook # Codex CLI only
shelldone setup gemini-hook # Gemini CLI only
shelldone setup copilot-hook # Copilot CLI only
shelldone setup cursor-hook # Cursor only"I didn't notify you because I wanted to. I notified you because exit code 0 demands acknowledgment." - shelldone
Wrap any command to get notified when it completes:
alert make build
alert npm test
alert ./deploy.sh productionThe notification shows the command name, exit status icon, elapsed time, and exit code. The original exit code is preserved.
"My notification was not late. Your attention to the terminal was early to leave." - shelldone
After shell integration, any command running longer than the threshold (default: 10 seconds) triggers a notification automatically. No alert wrapper needed.
make build-all # takes 5 minutes -> notification fires
ls # instant -> no notification
vim file.txt # excluded by default -> no notification"I monitor six channels simultaneously. What do you monitor? Your phone? Pathetic." - shelldone
shelldone can notify you when AI coding assistants finish their turn via native hook systems:
shelldone setup ai-hooks # install hooks for all detected AI CLIs
shelldone setup claude-hook # or install individually
shelldone toggle claude off # toggle per AI CLISupports Claude Code, Codex CLI, Gemini CLI, Copilot CLI, and Cursor. Aider uses the alert wrapper: alert aider "fix the bug".
"I could let your build finish in silence. But that would be chaos, and I don't do chaos." - shelldone
shelldone mute 30m # mute all channels for 30 minutes
shelldone mute slack 2h # mute only Slack for 2 hours
shelldone mute desktop # mute desktop notifications indefinitely
shelldone unmute slack # unmute just Slack
shelldone unmute # resume all notifications
shelldone toggle sound off # disable sound, keep desktop popups
shelldone toggle external off # disable all external channels
shelldone schedule 22:00-08:00 # set quiet hoursSupported layers: desktop, sound, voice, slack, discord, telegram, email, whatsapp, webhook, external (group), claude, codex, gemini, copilot, cursor.
"I don't have trust issues. I have exit code verification standards." - shelldone
All settings are environment variables. Set them before the eval line in your shell config:
export SHELLDONE_THRESHOLD=60
export SHELLDONE_SOUND_SUCCESS=Ping
export SHELLDONE_VOICE=true
eval "$(shelldone init zsh)"| Variable | Default | Description |
|---|---|---|
SHELLDONE_ENABLED |
true |
Master on/off switch |
SHELLDONE_AUTO |
true |
Auto-notify on/off |
SHELLDONE_THRESHOLD |
10 |
Seconds before auto-notify triggers |
SHELLDONE_SOUND_SUCCESS |
Glass / complete / Asterisk |
Success sound (macOS / Linux / Windows) |
SHELLDONE_SOUND_FAILURE |
Sosumi / dialog-error / Hand |
Failure sound (macOS / Linux / Windows) |
SHELLDONE_VOICE |
(off) | Set to true for TTS |
SHELLDONE_FOCUS_DETECT |
true |
Suppress when terminal is focused |
SHELLDONE_EXCLUDE |
vim nvim vi nano less ... |
Space-separated commands/globs to skip |
SHELLDONE_QUIET_HOURS |
(off) | Daily quiet hours (e.g., 22:00-08:00) |
Full reference with all variables: docs/configuration.md
"Your deploy finished 4 minutes ago. I told Slack. I told Discord. I told you. You ignored all three." - shelldone
Send alerts to Slack, Discord, Telegram, Email, WhatsApp, or any webhook. External notifications fire even when the terminal is focused.
export SHELLDONE_SLACK_WEBHOOK="https://hooks.slack.com/services/T.../B.../xxx"
shelldone webhook test slack # verify it worksSetup guides for all 6 channels: docs/external-channels.md
| Command | Description |
|---|---|
shelldone init [bash|zsh] |
Output shell init code (use with eval) |
shelldone setup [all|ai-hooks|<ai>-hook] |
Auto-configure rc files and/or AI CLI hooks |
shelldone uninstall |
Remove all shell integration and AI CLI hooks |
shelldone status |
Show diagnostic info: platform, tools, config, integration |
shelldone test-notify |
Send a test notification to all configured channels |
shelldone sounds |
List available system sounds for your platform |
shelldone exclude [list|add|remove] |
Manage auto-notify exclusion list |
shelldone webhook [status|test <channel>] |
Manage and test external notification channels |
shelldone mute [channel] [duration] |
Mute notifications globally or per channel (e.g., slack 2h) |
shelldone unmute [channel] |
Resume notifications (all or specific channel) |
shelldone toggle [layer [on|off]] |
Toggle notification layers (sound, desktop, voice, channels) |
shelldone schedule [HH:MM-HH:MM|off] |
Set or clear daily quiet hours |
shelldone test |
Run the full verification test suite (452 tests) |
shelldone version [--verbose] |
Show version (add --verbose for platform details) |
shelldone help |
Show usage help |
Detailed flowcharts for every command: docs/commands.md
| Feature | macOS | Linux | WSL | Windows (Git Bash) |
|---|---|---|---|---|
| Desktop notifications | osascript | notify-send | BurntToast / WinRT | BurntToast / WinRT |
| Sound | afplay | paplay / aplay / mpv | powershell.exe | powershell.exe |
| TTS | say | espeak / spd-say | powershell.exe | powershell.exe |
| Focus detection | AppleScript | xdotool | -- | -- |
| Auto-notify | zsh + bash | zsh + bash | zsh + bash | bash |
| External notifications | All channels | All channels | All channels | All channels |
macOS: No additional dependencies (osascript, afplay, say are built-in).
Linux: libnotify-bin for desktop, pulseaudio-utils/alsa-utils for sound, espeak for TTS, xdotool for focus.
WSL/Windows: BurntToast PowerShell module (recommended) or wsl-notify-send.
External channels: curl or wget for HTTPS channels.
Tested on macOS with bash and zsh, extensively validated with Claude Code, Gemini CLI, and Codex CLI. Slack is the only external channel tested end-to-end; other channels (Discord, Telegram, Email, WhatsApp, webhook) follow the same HTTP dispatch pattern and should work correctly. Since bash and zsh behave consistently across operating systems, shelldone should work identically on Linux, WSL, and Windows. It's MIT licensed - fork it, fix it, and send a PR.
shelldone uninstall # interactive confirmation
./uninstall.sh # or run the uninstall script
make uninstall # or via makeRun shelldone status for quick diagnosis. For debug output: SHELLDONE_DEBUG=true alert echo hello.
Full troubleshooting guide: docs/troubleshooting.md
"0 is the only exit code I respect." - shelldone
shelldone includes 452 tests covering unit, integration, and end-to-end scenarios.
bash test.sh # from project root
shelldone test # via the CLI"Knock knock knock... your build is done. Knock knock knock... your build is done." - shelldone
| Feature | shelldone | undistract-me | noti | done (fish) |
|---|---|---|---|---|
| Auto-notify | Yes | Yes | Partial | Yes |
| macOS + Linux + WSL + Windows | Yes | No | Yes | No |
| External channels (6) | Yes | No | Partial | No |
| Zero dependencies | Yes | Yes | No (Go) | Yes |
| AI CLI integration (5 tools) | Yes | No | No | No |
| Sound + TTS | Yes | No | Partial | No |
| Mute / schedule / toggle | Yes | No | No | No |
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes
- Run the test suite:
bash test.sh(all 452 tests must pass) - Run ShellCheck:
shellcheck bin/shelldone lib/*.sh hooks/*.sh - Commit and push
- Open a pull request
See CONTRIBUTING.md for detailed guidelines.
MIT License. Copyright (c) 2026 Naresh Sekar. See LICENSE for details.
