All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Per-channel mute: Mute individual notification channels with optional duration instead of muting everything at once.
shelldone mute slack 2h— mute Slack for 2 hours while desktop notifications continueshelldone mute desktop— mute desktop notifications indefinitelyshelldone unmute slack— unmute a specific channelshelldone unmute— clear all mutes (global + per-channel)- State stored as
mute_<channel>_untilkeys in the state file, with auto-expiry cleanup
- Interactive mute menu: Running
shelldone mutewith no arguments in a TTY now opens an interactive menu to select channels and duration. Non-TTY falls back to global indefinite mute for backward compatibility. - Rich status dashboard:
shelldone statusnow shows a channel-by-channel breakdown with visual indicators for muted (with countdown), toggled off, configured, and not configured states. - Shell completions: Tab completion for
muteandunmutenow suggests channel names (desktop, sound, voice, slack, discord, telegram, email, whatsapp, webhook) in both bash and zsh. - 18 new tests: Comprehensive test coverage for per-channel mute,
_shelldone_channel_active,_shelldone_unmute_all, and CLI mute/unmute commands.
- AI CLI hook latency: Reduced hook blocking time from ~1s to <50ms, eliminating "7u" garbage characters that appeared when typing quickly after a Claude Code session ended. The race condition was caused by the hook's synchronous operations widening the window between terminal mode restoration and user input.
- Hook notifications now run in a double-forked detached process (
setsidon Linux,disownon macOS) so the hook script exits immediately - JSON field extraction uses pure-bash regex first, falling back to python3 only for complex payloads (saves 25–275ms python3 startup)
- Focus detection (
osascript) is skipped in hook context where it is unreliable and adds ~200ms of unnecessary latency
- Hook notifications now run in a double-forked detached process (
1.4.0 - 2026-03-21
SHELLDONE_NESTED_SHELL=suppressconfig - disables auto-notify in nested shells (SHLVL > 1), preventing duplicate alerts from subshells spawned by AI coding tools, IDEs, and other wrappers. Top-level shells, tmux panes, and new terminal tabs are unaffected (they resetSHLVLto 1).
- Zsh compatibility: Fixed 22 failing tests and their underlying library bugs when running under zsh:
_shelldone_warn_once- replaced bash-only${!var}indirect expansion with cross-shelleval_shelldone_json_escape- fixed${str:i:1}substring syntax (${str:$i:1})_shelldone_redact_url- addedmatch[]fallback for zsh regex captures_shelldone_parse_duration- addedmatch[]/MATCHfallback for zsh regex captures_shelldone_is_quiet_hours- addedmatch[]fallback for zsh regex capturesauto-notify.zshglob exclusion - fixed pattern matching with$~excludedfor proper glob support_tui_select/_tui_multiselect- replaced bash-only${!array[@]}and 0-indexedoptions[$i]with cross-shell array access
- Test harness now sets
SHELLDONE_CONFIG=/dev/nullto prevent real config (e.g., Slack webhook) from leaking into test runs
1.3.1 - 2026-03-18
- Background job notifications no longer leak
[N] PID/donemessages in zsh (addedNO_MONITOR/NO_NOTIFYsetopt in_shelldone_bg_timeoutand_shelldone_notify_external)
1.3.0 - 2026-03-18
- Interactive TUI for channel setup (
shelldone setuplaunches menu-driven interface) lib/tui.sh- reusable TUI library for building interactive shell menus
- Hook scripts resolve library paths correctly in installed layout (
PREFIX/share/shelldone/hooks/→PREFIX/lib/shelldone/) - Prompt stdout leak during interactive setup
1.1.0 - 2026-03-17
- Enriched Discord embeds with structured fields (Command, Duration, Exit Code, Project), footer, and ISO 8601 timestamp
- Status emoji prefix (
✅/❌) in Discord embed titles for color-blind accessibility - Enriched Telegram messages with HTML formatting, structured fields, and context footer
- Enriched email body with key=value metadata (Command, Duration, Exit Code, Project, Host, Directory, Branch, Time)
- WhatsApp context line with project, hostname, and git branch
- Generic webhook payload now includes
hostname,command,duration,project,directory,git_branch,source,timestamp,successfields - AI hook exit code mapping: error stop reasons (
error,max_turns_reached,context_window_full,timeout) now produce exit code 1 instead of always 0 alert-bgnow sets_SHELLDONE_META_*variables for enriched channel messages
- Auto-notify captures full command with arguments (truncated to 50 chars) instead of just the basename - notification body now shows
✓ make deploy-production (2m 5s, exit 0)instead of✓ make (2m 5s, exit 0) alert-bgtitle now includes job name:Background: PID 1234 Completeinstead ofBackground Job Completealert-bgunknown exit code path now passes exit code 2 with⚠icon instead of false-green exit code 0- Duration formatting shows
<1sinstead of0sfor sub-second commands - Word-boundary-aware command truncation in
alert(breaks at last space before limit) - Timestamp format changed to locale-independent 24-hour format (
%Y-%m-%d %H:%M) - Telegram parse mode changed from Markdown to HTML for better formatting support
- Copilot hook message standardized from "Session complete" to "Task complete"
- AI hook error stop reasons no longer show false-green success indicators
alert-bgno longer reports success for unknown exit codes
1.0.0 - 2026-03-17
- BREAKING: Rebranded from
cli-alerttoshelldone - Command name changed:
cli-alert→shelldone - All environment variables renamed:
CLI_ALERT_*→SHELLDONE_* - Config directory moved:
~/.config/cli-alert/→~/.config/shelldone/ - State directory moved:
~/.local/state/cli-alert/→~/.local/state/shelldone/ - History directory moved:
~/.local/share/cli-alert/→~/.local/share/shelldone/ - Shell function prefix changed:
_cli_alert_*→_shelldone_*
- Backward compatibility shim: auto-migrates
CLI_ALERT_*env vars toSHELLDONE_*with warnings shelldone setupdetects and replaces old# >>> cli-alert >>>blocks in shell rc filesshelldone uninstallalso cleans up old# >>> cli-alert >>>blocks- Config directory migration from
~/.config/cli-alert/to~/.config/shelldone/
0.2.0 - 2026-03-16
- Multi-AI CLI hook support: Codex CLI, Gemini CLI, GitHub Copilot CLI, Cursor
- Per-AI toggle system (
shelldone toggle claude off,shelldone toggle codex off, etc.) - Auto-detect and install all AI hooks (
shelldone setup ai-hooks) - Shared hook library (
lib/ai-hook-common.sh) with JSON extraction and toggle-aware notification - Individual setup commands:
shelldone setup codex-hook,gemini-hook,copilot-hook,cursor-hook - AI CLI hooks section in
shelldone statusandshelldone toggleoutput - Aider detection with wrapper guidance in status output
- Uninstall now removes all AI CLI hooks (Claude, Codex, Gemini, Copilot, Cursor)
- ~40 new tests covering AI hook library, hook scripts, setup CLI, toggle, and status
shelldone setup(andshelldone setup all) now installs hooks for all detected AI CLIs, not just Claude- Shell completions expanded with new setup and toggle options
- Homebrew formula installs all hook scripts and shared library
- Makefile installs new hook scripts and
ai-hook-common.sh
0.1.0 - 2026-03-15
- Cross-platform desktop notifications (macOS, Linux, WSL, Windows via Git Bash/MSYS2/Cygwin)
alert <command>wrapper with exit code preservation- Auto-notify via shell hooks (zsh preexec/precmd, bash DEBUG trap) for commands exceeding configurable threshold
- Sound alerts with per-platform defaults and custom file path support
- Text-to-speech announcements (macOS
say, Linuxespeak/spd-say, Windowspowershell.exe) - Smart focus detection to suppress notifications when the terminal is in the foreground
- Glob-based command exclusion patterns
- External notification channels: Slack, Discord, Telegram, Email, WhatsApp, generic webhook
- Per-channel rate limiting with configurable interval
- HTTP transport auto-detection (
curl>wget>/dev/tcpfallback for plain HTTP) - Claude Code Stop hook integration (
hooks/claude-done.sh) - Mute / unmute with optional duration (e.g.,
30m,2h) - Per-layer toggle (desktop, sound, voice, individual channels,
externalgroup) - Daily quiet-hours schedule with cross-midnight support
- Notification history logging
shelldone statusdiagnostic commandshelldone webhook statusandshelldone webhook test <channel>commands- Shell completions for bash and zsh
install.shinteractive installer with platform detectionuninstall.shand marker-based RC file cleanupMakefilewith install/uninstall/test targets- Homebrew formula (
Formula/shelldone.rb) - Debian packaging (
debian/) - Scoop manifest (
packaging/scoop.json) - Chocolatey manifest (
packaging/chocolatey.nuspec) - GitHub Actions CI: ShellCheck, macOS (bash + zsh), Linux, install round-trip
- Comprehensive test suite (374 tests)