Blog · August 18, 2026 · 6 min read · by Vilva Athiban P B

Codex Sound When Done: Make Codex CLI Play a Sound When It Finishes

Sometimes you don't want banners, dashboards, or a notification center full of agent chatter. You want one thing: a sound when Codex is done. You kick off a task, you go read something else, and a ding tells you the terminal wants you back. This post is only about that — getting Codex CLI to make a sound when it finishes, on macOS, Linux, and Windows, from the simplest possible one-liner to a setup with different sounds for different events.

The one-liner: afplay in the notify hook

Codex CLI has no built-in "play sound on finish" toggle, but it has something better: a notify setting in ~/.codex/config.toml that runs any program you like when a turn completes. Point it at your operating system's audio player and you have your ding:

# ~/.codex/config.toml
notify = ["bash", "-c", "afplay /System/Library/Sounds/Glass.aiff"]

afplay is macOS's built-in audio player, and Glass.aiff is the classic soft ding. Save the file, start a new Codex session, and every completed turn now announces itself. Nothing to install, one line of config.

One gotcha catches nearly everyone: in TOML, root-level keys must appear before any table sections. If your config.toml already has sections like [tui] or [mcp_servers.something], the notify line must go above them — put it at the top of the file. If your sound never fires, this is the first thing to check.

Picking a better sound

Every macOS system sound lives in /System/Library/Sounds/ — run ls /System/Library/Sounds/ and audition them with afplay. Popular choices for "task done": Glass.aiff (gentle), Hero.aiff (triumphant), Ping.aiff (minimal), and Funk.aiff (impossible to miss). You can also point afplay at any audio file of your own — a two-second mp3 works fine — and control loudness with the volume flag: afplay -v 0.5 file.aiff plays at half volume, which your open-plan office neighbours will appreciate.

Linux and Windows equivalents

The pattern is identical; only the player changes.

  • Linux (PulseAudio/PipeWire): notify = ["bash", "-c", "paplay /usr/share/sounds/freedesktop/stereo/complete.oga"]
  • Linux (ALSA): use aplay with a wav file instead.
  • Windows (WSL or native PowerShell): notify = ["powershell.exe", "-c", "[console]::beep(880,300)"] gives a simple beep; for a real sound, use (New-Object Media.SoundPlayer 'C:\Windows\Media\notify.wav').PlaySync().

Only ding when the task is actually done

The bare one-liner plays for every notification event Codex emits. That is usually what you want, but if you'd rather filter, Codex appends a JSON payload as the final argument to whatever program notify runs. The payload's type field is agent-turn-complete when a turn ends, so a tiny script can play your done-sound only for that event:

# ~/.codex/config.toml
notify = ["bash", "/Users/you/.codex/ding.sh"]

# ~/.codex/ding.sh  (chmod +x it)
#!/bin/bash
payload="${@: -1}"
if echo "$payload" | grep -q '"type":"agent-turn-complete"'; then
  afplay /System/Library/Sounds/Glass.aiff
fi

Using grep keeps the script dependency-free; if you have jq installed, parsing properly is nicer. The payload also includes a summary of what Codex just did, which is how people build full desktop-banner setups on top of the same hook.

The sound you actually need: "it's waiting on you"

Here is the uncomfortable truth about done-sounds: the expensive silence isn't after a task finishes — it's when Codex stops mid-task to ask for approval and sits there while you read Slack. The notify hook fires when a turn completes, which covers many of these pauses, but terminal-level tricks can close the gap: iTerm2, WezTerm, and Kitty can all alert when a quiet tab produces output, and tmux's monitor-silence flags a window that has gone still. We dug into this specific problem in our post on getting a ding when Codex needs a response.

If you'd rather not maintain shell scripts

Config edits and ding scripts are genuinely fine for one machine and one tool. They get old when you also run Claude Code and Cursor, when a path change silently breaks the script, or when you want "done" and "waiting for input" to sound different without writing a JSON parser in bash.

Either way, the destination is the same: a terminal you can walk away from. Set up the sound once — one line of TOML or one app install — and Codex stops being something you watch and starts being something that calls you when it matters.

Keep reading

Desk Exercises for Programmers: 15 Moves to Do While Your AI Agent Codes

7 min read

Exercise While Coding: Turn Claude Code Wait Time Into Micro-Workouts

7 min read

Claude Code Notch Notifications on Mac: See When Claude Is Done Without Watching the Terminal

7 min read

Claude Code Tips and Tricks: 12 Ways to Use Claude Code Effectively

8 min read

Claude Code Multiple Sessions: How to Run Agents in Parallel Without Losing Track

6 min read

A Claude Code Workflow That Doesn't Involve Watching the Terminal

5 min read

Claude Code Hooks: A Practical Guide to Automating Your Agent Workflow

7 min read

Claude Code Auto Mode: Fewer Permission Prompts Without Living Dangerously

7 min read

Claude Code Subagents: How to Delegate Work to Specialized Agents

7 min read

Claude Code Context Management: Treat the Context Window Like a Budget

6 min read

Per-Subagent Model Selection: Route the Grunt Work Down, Keep the Judgment Up Top

7 min read

Skills and Plugins: How to Teach Claude Code Your Way of Working

7 min read

Claude Code Background Tasks: Run Long Commands Without Blocking Your Session

6 min read

Codex CLI Notifications: How to Get a Ding When Codex Is Done or Needs Input

7 min read

Cursor Notification When Done: Every Way to Get Notified When Cursor Finishes

6 min read

Claude Code Notifications: How to Get Notified When Claude Code Finishes or Needs Your Input

6 min read

Want to Be Notified When Claude Responds? How Claude Notifications Work on Web, Desktop, and Mobile

5 min read

Claude Code Notification Scripts: Copy-Paste Recipes for Every Platform

6 min read

Get a Ding the Moment Codex Needs Your Response

6 min read

Get Notified the Moment Claude Code Is Waiting for Your Input

6 min read

“Notifications Are Turned Off for Claude” — Here Is the Fix

6 min read

terminal-notifier + Claude Code: Native macOS Alerts When Your Agent Finishes

6 min read

Gemini CLI Notifications: How to Get a Sound or Alert When Gemini Finishes

6 min read

Get Claude Code Notifications on Your Phone

6 min read

Claude Code Remote Control, Explained

7 min read

preferredNotifChannel: Claude Code's Built-In Notification Setting

6 min read

Claude Code Notifications in tmux and Over SSH

7 min read

Claude Code Effort Levels: Why Your Setting Keeps Getting Ignored

8 min read

Codex vs Claude Code Notifications: How Each One Tells You It Is Done

8 min read

Claude Code Notifications Not Working: A Diagnostic Checklist

10 min read

Claude Code Notifications Inside Your Editor's Terminal

7 min read

CLAUDE_CODE_DISABLE_BACKGROUND_TASKS Explained

7 min read

CLAUDE_CODE_DISABLE_BG_SHELL_PRESSURE_REAP Explained

8 min read

Cursor Alerts Explained: Every Alert Cursor Raises, and How to Control Them

7 min read

Claude Code Environment Variables: The Groups That Actually Matter

10 min read

Claude Code Notifications on WSL and Windows

9 min read

Claude Code Checkpoints and /rewind

8 min read

Claude Remote Control: How It Works, Turning It Off, and Auto Mode

7 min read

Claude Code /loop: Poll a Deploy, Babysit a PR, and Get Told When It's Done

8 min read

Setting Up NotchFit With OpenAI Codex CLI: Hooks, $notchfit-plan, and the Daily Flow

7 min read

Claude Mods Explained: What the New Plugin Layer Can Do, and How to Turn On 'You Should Know'

9 min read

NotchFit vs Mac Break Reminder Apps: A Clock or a Signal From Your Coding Agent?

8 min read

Claude Code Headless Mode: Running claude -p in Scripts and CI, and the Three Signals That It Finished

10 min read

Building a Movement Habit at a Desk: Use the Agent Run as the Cue, One Set as the Unit, and Streaks Carefully

8 min read

Claude Code MCP Servers Explained: Adding Servers, Choosing a Scope, Handling Secrets, and Why Long Tool Calls Go to the Background

10 min read

/notchfit:plan Explained: How Claude Code or Codex Writes a Weekly Workout Plan the Notch Can Actually Run

8 min read

Claude Code Spinner Verbs Explained: What “Pondering” and “Brewing” Mean, How to Change Them, and Why You Should Stop Watching the Spinner

7 min read

Why NotchFit's Done and Permission Alerts Wait Until Your Set Ends, When That Costs You, and How to Turn the Workout Off

7 min read

How to Resume a Claude Code Session: --continue vs --resume, Naming Sessions, the Session Picker, Branching, and What Comes Back

9 min read

NotchFit on a Mac Without a Notch: How Pill Mode Works on Mac mini, iMac, Mac Studio and a MacBook With the Lid Closed

6 min read

How to Run a Claude Code Session in the Background: /background, claude --bg, Agent View, and Getting Back to It

9 min read

What a Notch App Can See: NotchFit's Local-First Design, What the Claude Code and Codex Hooks Send, and What Stays on Your Mac

7 min read

Why Codex CLI Asks for Permission Every Time, and How to Tune the Sandbox and Approval Policy Without Going Full Access

8 min read

What to Do While Claude Code or Codex Works: A Simple Protocol for the Two-to-Twenty-Minute Gap in Every Agent Run

7 min read

Is It Possible to Get a Notification When Claude Code or Codex Hits a Reset? Yes for Claude Code: the quota_auto_resume Hooks, Explained

8 min read

What a MacBook Notch App Can Actually Do: The Five Kinds of Notch Utility, Their Trade-offs, and Where NotchFit Fits

7 min read