Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chime

Chime

Run this:

chime

That’s the sound of a command being done. Drop it at the end of anything you were about to stare at — a build, a backup, a brew upgrade, a twenty-minute encode — and walk away.

On macOS it plays a short completion chime. Add --notify (or --message) and it also pops a Notification Center banner, so you see it even if the terminal is buried.

chime --message "Hello, world!"

Notification Center banner: Chime — Hello, world!

Pick the right glue

Chime is just a command. The shell decides whether it runs. That one choice is the whole product.

You write When it rings What it means
cmd && chime Only if cmd succeeded “You’re clear.”
cmd; chime Always, after cmd “Come look.”
cmd | chime As output arrives, then at the end “I’m listening.”

&& — only if it worked

Success is the news. Silence means something still needs you.

make -j && chime
pytest && chime --message "Tests passed"
ffmpeg -i talk.mov talk.mp4 && chime --message "Export ready"
brew upgrade && chime --notify
ssh build-box './deploy.sh' && chime --message "Deployed"

false && chime stays quiet. That’s the point.

; — whenever it’s over

You left. You want the doorbell, not a verdict. Look at the terminal to see how it went.

rsync -a ~/Projects /Volumes/Backup ; chime --message "Backup finished"
make -j ; chime --notify
long-job ; chime --message "Done — check the exit"

false; chime still rings.

| — listen while it runs

A pipe puts Chime inside the command. Stdout still prints exactly as before. Each new line gets a short tick; when the stream ends you get the longer complete sound.

./slow-job | chime
make -j 2>&1 | chime
docker pull ghcr.io/org/huge-image | chime
for i in 5 4 3 2 1; do echo "$i"; sleep 1; done | chime --message "GO"

A tick is progress. Completion means the pipe closed — not that the producer succeeded. cmd | chime always runs Chime.

Progress bars that rewrite the same line with \r do not tick. Empty input still plays the complete sound.

Hear it and see it

Sounds are enough at your desk. For banners, run this once, then --notify or --message:

chime --setup-notifications
sleep 25m && chime --message "Tea is ready"
echo "TIME TO GOOOO" | chime --notify

--message sets the text and turns notifications on, so you never write a message nobody will see. On a pipe without --message, the banner is the last nonempty line of output — that’s why the example above shows TIME TO GOOOO instead of a generic “Complete.”

{ echo "compiling…"; sleep 2; echo "Build succeeded"; } | chime --notify
{ echo "compiling…"; sleep 2; echo "Build succeeded"; } | chime --message "Ship it"

Install

User-local — no administrator privileges. You need macOS 13+, Xcode command-line tools, CMake 3.20+, and Apple Clang.

cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build -j
cmake --install build --prefix ~/.local
mkdir -p ~/Applications
cp -R ~/.local/libexec/Chime.app ~/Applications/   # or: cp -R build/Chime.app ~/Applications/
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
chime --setup-notifications                        # only needed for banners

Allow the macOS prompt and confirm Chime in System Settings → Notifications. Sound-only use works without the helper app.

Keep Chime.app at ~/Applications. Notification permission follows that bundle; moving or re-signing it can look like a new app. The build ad-hoc signs it — a stable Apple Development identity avoids the prompt returning after every rebuild.

Universal binary: -DCHIME_UNIVERSAL=ON.

# uninstall
rm -f ~/.local/bin/chime
rm -rf ~/.local/libexec/Chime.app ~/.local/share/chime
rm -rf ~/Applications/Chime.app
rm -rf ~/Library/Application\ Support/Chime
rm -f ~/.chime.json                                # optional

You can also remove Chime from System Settings → Notifications.

Other arguments

chime --help is the full list. These are the ones worth knowing:

chime --volume 0.3                              # quieter; never touches system volume
chime --no-sound --message "Meeting in 5"       # banner only
printf 'secret\n' | chime --no-passthrough      # eat the pipe, print nothing
yes | head -n 200 | chime --sound-cooldown-ms 250   # don’t machine-gun ticks
make -j 2>&1 | chime --line-sound ~/Sounds/tick.wav
chime --title Kitchen --message "Tea is ready"
chime --notify-on all                           # banners on every line (usually too much)

--title changes the banner heading. Custom --line-sound and --completion-sound take a built-in name (tick, complete) or a path to a .wav / .aiff.

Configuration

Optional ~/.chime.json. Missing is normal — the defaults are enough.

chime --init-config      # write ~/.chime.json (refuses to overwrite)
chime --print-config     # show what will actually run
chime --no-config        # ignore the file for this invocation

CLI flags always win. A quiet, notify-on-by-default setup looks like examples/chime.json:

{
  "version": 1,
  "sound": {
    "volume": 0.4,
    "cooldown_ms": 250
  },
  "notifications": {
    "enabled": true,
    "events": "completion"
  }
}

Omitted keys keep their defaults. Nested objects merge.

Implementation

A small macOS 13+ CLI in C++17 with a little Objective-C++. NSSound plays the bundled tick and complete tones (or your own files). Banners go through Notification Center via a tiny accessory app, Chime.app, that the CLI talks to over a local socket. There is no background daemon.

Piped bytes are forwarded unchanged. Chime works in any macOS terminal.

License

MIT. Copyright 2026 Daxliar.

No third-party runtime libraries. Sounds (tick.wav, complete.wav) and the helper icon are generated at build time (tools/gen_sounds.c, tools/gen_icon.mm). docs/icon.png is a snapshot of that icon. Audio and banners use Apple’s Foundation, AppKit, and UserNotifications.

About

A macOS CLI that plays a sound (and optional Notification Center banner) when a command finishes.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages