Skip to main content
DevAI

I built voice notifications for my terminal and it changed how I work

Every developer knows this moment: you kick off a build, a test suite, or a deploy, switch to something else, and forget to check back. Five minutes later you realize the build finished ages ago — or worse, it failed immediately and you’ve been waiting for nothing.

The longer the task, the worse it gets. You Alt-Tab back to check, nothing yet. You check your email. You check again. Still running. You open a YouTube video. Three minutes later you remember — oh right, the build. It finished two minutes ago.

I got tired of this loop, so I built a small CLI tool called notify that makes my terminal talk to me. A sound, a spoken message, a toast popup, even a Discord ping — whenever a command finishes or needs my attention.

It changed the way I work.

The problem with silent terminals

Terminals are visual. If you’re not looking at them, you don’t know what happened. This becomes a real problem when you’re running things across multiple virtual desktops, or when a task takes long enough that you context-switch away.

Builds, test suites, deploys, database migrations, AI coding agents — they all finish silently. And the moment your attention moves elsewhere, you lose track of them.

Voice notifications fix this

The solution is simple — make the terminal talk to you. When a build finishes, my computer says “Backend done”. When a test suite fails, I hear “Something went wrong with project coolgame”. I immediately know which project needs me and why, without looking at a single screen.

This is what notify does. It’s a single binary that chains sounds, text-to-speech, toast popups, and Discord messages into configurable pipelines. You can chain it onto any command, wrap it around long-running tasks, or wire it into tool-specific hooks.

How it works

The simplest usage is chaining notify onto existing commands:

# Notify on success or failure
go test ./... && notify ready || notify error

# Wrap a command — auto-notifies and tracks duration
notify run -- make build

# After a deploy
kubectl rollout status deploy/api; notify done

The notify run wrapper measures how long the command took, so you hear things like “Backend ready; took 2 minutes and 15 seconds.”

You can also name your projects. The first argument is the profile name — it gets spoken in the notification, so you know which project is talking:

notify backend done      # "Backend done"
notify coolgame error    # "Something went wrong with project coolgame"

Integrating with Claude Code

My primary use case is Claude Code, Anthropic’s AI coding agent. It has a hooks system — shell commands that run automatically on lifecycle events. Two events matter here:

  • Stop — Claude finished responding
  • Notification — Claude needs your attention (permission prompts, idle alerts)

For each project, I add a .claude/settings.json with hooks that call notify:

{
	"hooks": {
		"Stop": [
			{
				"matcher": "",
				"hooks": [
					{
						"type": "command",
						"command": "notify coolgame done",
						"timeout": 10
					}
				]
			}
		],
		"Notification": [
			{
				"matcher": "",
				"hooks": [
					{
						"type": "command",
						"command": "notify coolgame attention",
						"timeout": 10
					}
				]
			}
		]
	}
}

When Claude finishes work on my game project, I hear: “Coolgame done.” When it needs permission to run something, I hear: “Coolgame needs your attention.”

No screen-checking required. This works the same way with any tool that supports hooks or post-run commands — CI pipelines, file watchers, task runners.

The notification config

All notification behavior is defined in a single JSON file (notify-config.json). Here’s a simplified version of what I use:

{
	"config": {
		"afk_threshold_seconds": 60,
		"default_volume": 10,
		"credentials": {
			"discord_webhook": "https://discord.com/api/webhooks/YOUR_ID/YOUR_TOKEN"
		}
	},
	"profiles": {
		"default": {
			"done": {
				"steps": [
					{ "type": "sound", "sound": "blip" },
					{ "type": "say", "text": "{Profile} done" },
					{ "type": "toast", "title": "{Profile}", "message": "Project {profile} is done!" },
					{ "type": "discord", "text": "{Profile} is done", "when": "afk" }
				]
			},
			"attention": {
				"steps": [
					{ "type": "sound", "sound": "blip" },
					{ "type": "say", "text": "{Profile} needs your attention" },
					{
						"type": "toast",
						"title": "{Profile}",
						"message": "Project {profile} needs your help!"
					},
					{ "type": "discord", "text": "{Profile} needs your attention", "when": "afk" }
				]
			}
		}
	}
}

When notify coolgame done fires, here’s what happens: it plays a short blip sound, then speaks “Coolgame done” through text-to-speech, and shows a desktop toast notification saying “Project coolgame is done!” If I’ve been away from my keyboard for more than 60 seconds, it also sends a Discord message — “Coolgame is done” — so I get a ping on my phone.

When notify coolgame attention fires, it’s similar but more urgent: a blip, then “Coolgame needs your attention” through speech, plus a toast. If I’m AFK, it also pings Discord with the same message so I know to come back.

A few things to note:

Template variables{profile} gets replaced with whatever profile name you pass on the CLI. So one config handles all projects. When I call notify coolgame done, the speech says “Coolgame done”. When I call notify backend done, it says “Backend done”. No per-project configuration needed.

AFK detectionnotify checks whether I’ve touched the keyboard or mouse recently. If I’ve been idle for more than 60 seconds, it considers me away. The "when": "afk" condition on the Discord step means I only get a Discord ping when I’ve actually left my desk — not when I’m sitting right there hearing the audio.

Low volume — I keep the default at 10 because I’m usually wearing headphones. A quiet spoken notification is enough to get my attention without being jarring.

What my typical workflow looks like

  1. I open three virtual desktops — one for a game project, one for a backend service, one for a CLI tool.
  2. Each has tasks running — Claude Code sessions, builds, test suites. Each one’s hooked up to notify with that project’s name.
  3. I start a build in the game project, then switch to the backend and kick off a test suite there.
  4. A minute later, I hear “Backend done” through my headphones. I switch to that desktop, check the results, and start the next task.
  5. While working, I hear “Coolgame needs your attention”. The game build needs me. I switch over, fix the issue, and go back to the backend.

It’s like having a team of junior devs in the room, each one tapping you on the shoulder when they need you — except instead of a tap, it’s a voice telling you exactly who and why.

Discord pings when you’re away from your desk

Voice notifications are great when you’re at your computer. But sometimes you’re not — you’re in the kitchen making coffee, grabbing lunch, or just stretching your legs. That’s where the Discord integration comes in.

When notify detects that I’ve been idle (no keyboard or mouse input for 60 seconds), it automatically sends a Discord message instead. So if a build finishes while I’m picking up a coffee, I get a ping on my phone: “Backend is done.” I know before I even sit back down that there’s work ready for review.

The nice part is that it’s automatic. I don’t have to enable or disable anything when I leave my desk. The AFK detection handles it — voice when I’m here, Discord when I’m not.

It pulls you back from distractions

Here’s something I didn’t expect when I built this: the voice notifications don’t just help when you’re working on other code. They help when you’ve drifted away from code entirely.

You kick off a task, and while it runs, you check your email. Then you see a news article. Then a YouTube video catches your eye. Before you know it, ten minutes have passed and the task finished ages ago.

With notify, that drift gets interrupted. You’re two minutes into a YouTube video and suddenly hear “Coolgame done” through your headphones. It’s a gentle but immediate pull back to the task. You pause the video, switch to the desktop, review the code, and move on.

It works the same way when you’re reading documentation, browsing Stack Overflow, or answering Slack messages. The spoken notification cuts through whatever you’re doing because it’s a different sensory channel — you don’t need to see it, you hear it.

Reducing dead time

This is the real productivity gain, and it’s bigger than I initially thought.

Without notifications, there’s always a gap between “the task is done” and “I notice the task is done.” Sometimes it’s thirty seconds, sometimes it’s five minutes, sometimes it’s longer. That’s dead time — the result is ready, the next step is waiting, but your attention is elsewhere.

Those gaps add up fast. If you’re running three parallel tasks and each one has even a two-minute gap, that’s six minutes of wasted time per cycle. Over a full day of work, you can easily lose an hour.

With voice notifications, that gap shrinks to nearly zero. The task finishes, I hear it, I switch. The turnaround between “done” and “next step” is seconds instead of minutes. It keeps things moving.

It’s a small thing — just a voice saying a few words — but it fundamentally changes the rhythm of working with long-running tasks. Instead of polling (“is it done yet?”), you’re event-driven (“it told me it’s done”). That shift makes parallel workflows actually practical.

It works with everything

I’ve shown the Claude Code integration because that’s my primary use case, but notify is completely tool-agnostic. Anything that runs in a terminal can trigger it — builds, deploys, test suites, database migrations, container orchestration, you name it. If it has an exit code, notify can wrap it.

Try it

notify is open source and available on GitHub. It’s a single Go binary with no runtime dependencies — just drop it on your PATH and create a config file. It runs on Windows, macOS, and Linux.

If you’re juggling long-running terminal tasks — builds, deploys, test suites, AI coding agents — and find yourself constantly checking back on them, give it a try. The voice notifications are a small thing, but they completely changed how I work.

Check out the wiki for setup instructions and a full config reference.

Published on February 20, 2026 · 8 min read



Older Post Coding With a Colleague That Isn’t Human

Scroll NavigateR Reader