HookStack
Back to catalogue
NotificationStop

Voice task-completion announcement

Get told out loud the moment work is done

Announces out loud via TTS that the agent has finished its task, with a random completion message.

What does the Voice task-completion announcement hook do?

Voice task-completion announcement is a Claude Code Stop hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Get told out loud the moment work is done.

As a Stop hook it runs after the action, reacting to what just happened rather than blocking it. Because it is a deterministic Node.js script, it executes on every matching event without relying on the model to remember — the guarantee that makes agentic workflows safe to automate.

Use cases

  • Get notified without watching the screen when the task is done
  • Audio feedback at the end of a long session

Tags

#tts#stop#voice#completion#audio

settings.json fragment

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/stop-tts.mjs",
            "type": "command"
          }
        ],
        "matcher": ""
      }
    ]
  }
}

Script · .claude/hooks/stop-tts.mjs

#!/usr/bin/env node
// @hookstack stop-tts-completion
// Annonce la fin de session Claude par TTS (Stop)
import { execSync } from "node:child_process";
import { fileURLToPath } from "node:url";

function defaultExec(cmd) {
	execSync(cmd, { timeout: 10_000, stdio: "ignore", shell: true });
}

export function run({
	exec = defaultExec,
	platform = process.platform,
	projectDir = process.env.CLAUDE_PROJECT_DIR,
} = {}) {
	const project = projectDir?.split("/").pop() ?? "Claude";
	const text = `Tâche terminée sur ${project}`;

	try {
		if (platform === "darwin") exec(`say "${text}"`);
		else exec(`espeak "${text}" 2>/dev/null || spd-say "${text}"`);
	} catch {
		// TTS absent — non bloquant
	}
	return text;
}

/* v8 ignore next 3 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
	run();
}

Learn more

Related hooks