Skip to content

Play a sound when Codex finishes a prompt / task #3962

Open

Description

@khryniewiecki

Sound when Codex finishes

Summary
Please add an optional, clearly audible completion sound that plays when Codex finishes executing a prompt/task (useful when prompts run longer and the user switches focus).

Why
Helps when Codex works in background and I’m in another window/tab.
Terminal bell \a is too short/quiet and easy to miss.

Use case / Motivation
Most of my prompts take Codex quite a long time to execute — often more than a minute. It’s frustrating that I have to sit and stare at the screen just to know when it’s done. Since I work remotely, I could easily use that waiting time to do something else, as long as Codex informs me when it finishes.

Yes, I can (and already did) hack together my own workaround, but it would be much nicer if this were a built-in feature of the extension. For example, after finishing a prompt Codex could simply play a clear sound notification.

Environment
VSC

Extras
I would be cool if it plays: https://youtu.be/CduA0TULnow?list=RDCduA0TULnow&t=58

Are you interested in implementing this feature?

No response

Additional information

No response

Activity

  1. robin-liquidium commented on Sep 20, 2025

    @robin-liquidium

    you can already do that by setting up a notification hook for it in your .codex config.toml.

    just add this to your config.toml
    notify = ["python3", "~/.codex/notify.py"]

    and setup a notify.py file

    #!/usr/bin/env python3
    """
    Minimal notifier for Codex "notify" hook.
    Plays a short sound when an agent turn completes.
    
    Usage: Codex runs this script with a single JSON argument.
    """
    
    import json
    import os
    import subprocess
    import sys
    
    
    def main() -> int:
        if len(sys.argv) != 2:
            return 0
    
        try:
            event = json.loads(sys.argv[1])
        except Exception:
            event = {}
    
        if event.get("type") != "agent-turn-complete":
            return 0
    
        # Prefer a built-in macOS sound if available; fall back to TTS.
        sound_path = "/System/Library/Sounds/Glass.aiff"
        try:
            if os.path.exists(sound_path):
                subprocess.Popen(["afplay", sound_path])
            else:
                subprocess.Popen(["say", "Codex turn complete"])  # best-effort fallback
        except Exception:
            pass
    
        return 0
    
    
    if __name__ == "__main__":
        raise SystemExit(main())
    
  2. markgrover commented on Sep 25, 2025

    @markgrover

    I had to a make a few tweaks (iterm2 on macOS):

    • Relative path didn't work for me in my ~/.codex/config.toml, I had to use absolute path to my home dir

    notify = ["python3", "/Users/YOUR_USER_NAME/.codex/notify.py"]

    • Minor change to notify.py to use the terminal bell instead:
    #!/usr/bin/env python3
    """
    Minimal notifier for Codex "notify" hook.
    Plays a short sound when an agent turn completes.
    
    Usage: Codex runs this script with a single JSON argument.
    """
    
    import sys
    import json
    
    def main():
        if len(sys.argv) != 2:
            return 0
    
        try:
            event = json.loads(sys.argv[1])
        except Exception:
            return 0
    
        if event.get("type") != "agent-turn-complete":
            return 0
    
        # Print BEL character -> terminal bell
        sys.stdout.write("\a")
        sys.stdout.flush()
        return 0
    
    if __name__ == "__main__":
        raise SystemExit(main())
    
    • To test once it's all set up run:
      python3 ~/.codex/notify.py '{"type":"agent-turn-complete"}'
  3. samlouiscohen commented on Sep 27, 2025

    @samlouiscohen

    Love this ask. I implemented a cross-platform MVP that’s opt-in and uses system sounds (no bundled assets).

    Proposal

    • notifications.sound = true|false (default false)
    • notifications.only_on_long_runs_ms = 0
    • notifications.success_tone = "default" / notifications.error_tone = "default"
      • Maps to OS-appropriate system sounds:
        • macOS → Hero (success), Basso (error)
        • Windows → SystemSounds.Asterisk (success), SystemSounds.Hand (error)
        • Linux → canberra id complete (success), dialog-error (error)
    • Fallback: terminal bell (\a) if no backend available
    • Fires only on final agent-turn-complete

    Why

    • Improves the UX for long-running tasks without requiring custom notify hook scripts
    • Only system sounds → zero new binary assets
    • Safe defaults, fully optional, and configurable via ~/.codex/config.toml
    • Increasingly relevant as model time horizons grow longer — Codex runs already take tens of minutes in some cases. An audible success/failure cue makes it possible to safely multitask while waiting.

    Example Config

    [notifications]
    sound = true
    only_on_long_runs_ms = 10000
    success_tone = "default"
    error_tone = "default"

    Opened a PR to implement this: #4329

    It adds:

    • notifications.sound (default off)
    • notifications.only_on_long_runs_ms
    • success_tone / error_tone with sensible per-OS defaults
    • Fallback to terminal bell

    Cross-platform mappings:

    • macOS → Hero (success), Basso (error)
    • Windows → SystemSounds.Asterisk / Hand
    • Linux → canberra complete / dialog-error
  4. atreeon commented on Oct 1, 2025

    @atreeon

    Would this proposal result in the cli playing a sound if the task pauses asking for approval?

  5. jsh9 commented on Oct 5, 2025

    @jsh9

    Hi @samlouiscohen , does your code change work for the VS Code extension as well? Or only the CLI version of Codex?

  6. budingkak12 commented on Oct 18, 2025

    @budingkak12

    我尝试了很多次,都通知失败,最后,我把notify = ["python3", "/Users/wang/.codex/notify.py"]
    放到disable_response_storage = true的后面一行 成功了,(我之前一直放在
    trust_level = "trusted"
    后面,导致一直失败,很神奇)

  7. budingkak12 commented on Oct 18, 2025

    @budingkak12

    "I tried many times, but the notification failed every time. Finally, I moved the line notify = ["python3", "/Users/wang/.codex/notify.py"] right after disable_response_storage = true, and it worked! (It's strange because it kept failing when I had it after trust_level = "trusted".)"

  8. rijieli commented on Oct 19, 2025

    @rijieli

    For macOS users, I found a simple way to play sounds or notifications using the Shortcuts app, which has higher permissions. I configured the TOML file accordingly.

    notify = ["zsh", "/Users/roger/.codex/notify.sh"]
    
    [tui]
    notifications = true
    
    #!/bin/zsh
    /usr/bin/shortcuts run "Codex Done"
    
    Image
  9. jsh9 commented on Oct 21, 2025

    @jsh9

    The following worked for me on macOS, simple and easy to maintain, without the hassle of creating a Python script (notify.py) or a Shortcut.

    In ~/.codex/config.toml, add this line:

    model = "gpt-5-codex"
    model_reasoning_effort = "low"
    + notify = ["bash", "-lc", "afplay /System/Library/Sounds/Bottle.aiff"]

    /System/Library/Sounds has many different ringtones for you to choose. You don't have to use my choice.

    /System/Library/Sounds
    ├── Basso.aiff
    ├── Blow.aiff
    ├── Bottle.aiff
    ├── Frog.aiff
    ├── Funk.aiff
    ├── Glass.aiff
    ├── Hero.aiff
    ├── Morse.aiff
    ├── Ping.aiff
    ├── Pop.aiff
    ├── Purr.aiff
    ├── Sosumi.aiff
    ├── Submarine.aiff
    └── Tink.aiff
    

    (Inspired by #4998 (comment))

  10. changed the title [-]Play a long sound when Codex finishes a prompt/task[/-] [+]Play a sound when Codex finishes a prompt / task[/+] on Nov 12, 2025
  11. 40 remaining items

  12. apws commented on May 4, 2026

    @apws
  13. constansino commented on May 6, 2026

    @constansino

    I published a small hook-based workaround for macOS users who want a clearer "Codex needs attention" signal, not just turn-complete notifications:

    https://github.com/constansino/codex-attention-notifier

    It sends a native macOS notification for PermissionRequest hook events. It does not approve/deny anything; it only notifies and logs locally.

    I also wrote a short discussion post with usage details here:

    #21354

  14. PhilChen-6765 commented on May 14, 2026

    @PhilChen-6765
  15. etraut-openai commented on May 14, 2026

    @etraut-openai
  16. PhilChen-6765 commented on May 14, 2026

    @PhilChen-6765
  17. etraut-openai commented on May 14, 2026

    @etraut-openai
  18. AminDhouib commented on May 15, 2026

    @AminDhouib

    For anyone here using custom notify.py scripts or one-off afplay commands, we built a small cross-platform notifier for Codex and other AI coding agents: https://github.com/DevinoSolutions/ai-agent-notifier

    Just run npx ai-agent-notifier setup, reset your current sessions, and you are good to go!


    Desktop.Notifications.for.Claude.Codex.Cursor.and.Gemini.-.AI.Agent.Notifier.Demo.mp4

    Watch on YouTube

  19. apws commented on May 23, 2026

    @apws

    hi, glad to see there 2 nice "hooks"-related solutions for (also) sound notifications; I was totally new to codex 3 weeks ago, so only now understanding the architecture (btw, is codex-CLI used under the hood of codex-APP ?), but as I understood reading related issues here, "hooks" are still in development to be in parity to claude code, but this is probably something I didn't knew - sure; so I as a one of first codex test projects implemented "out of the box sound notifier" based on visual screen watching of PET badge parked into left-bottom screen corner (tested on win/mac, hidpi aware etc); sure IT IS hack, but is reliable and is fast/immediate - system notifications on windows are always quite weird and not instant - thanks for the new workarounds/hooks here too;
    (this was hidden originally as off-topic, but it isn't, excuse me, I am writing here mostly because "system notifications" at least on windows is something which didn't worked for me well, so i was immediately forced to TRY something simple the "other way"...)
    https://github.com/apws/260504-codex-pet-screen-sounds

  20. alsotang commented on Jun 10, 2026

    @alsotang

    any update here? i dont need the sound. i need visual notification.

  21. pal03377 commented on Jun 22, 2026

    @pal03377

    Someone built an additional plugin that can do this (but it does not work via the Remote SSH extension :()
    https://marketplace.visualstudio.com/items?itemName=zis3c.codex-notifier

  22. finebyme99 commented on Jul 11, 2026

    @finebyme99

    Please also support custom notification sounds in the Codex desktop app.

    Suggested settings:

    • Choose from built-in sounds
    • Import a local WAV/MP3 file
    • Preview the selected sound
    • Configure separate sounds for task completion, user input required, approval required, and failure
    • Restore the default sound easily

    Currently, the macOS app bundles a fixed notification sound. Replacing that file manually invalidates the app code signature and may prevent the app from launching, so this needs an officially supported setting.

    This would be especially useful for long-running tasks and for users who work with several agent applications simultaneously.

  23. bellowsai commented on Oct 13, 2026

    @bellowsai

    Disclosure: I'm Rob, and I built this.

    For anyone who wants this outside the editor: Bellows, a desktop app for Windows, macOS and Linux, runs Codex (alongside Claude, Gemini CLI and any ACP agent) and tells you the moment a turn finishes or the agent stops to ask permission. It's a proper system notification with sound, not a terminal bell, and clicking it takes you straight to the session that raised it. While a session is waiting on you, its taskbar button flashes until you answer.

    It works across every session at once, so you can leave three Codex tasks running in different worktrees and get on with something else. If you're away from the desk entirely, you can answer the permission prompts from your phone.

    Download: https://bellowsai.app/downloads?utm_source=github&utm_medium=reply

    Give it a try, and tell me what would make it better for your workflow. We act fast on feedback.

  24. lttxzmj commented on Oct 15, 2026

    @lttxzmj

    For the extension-side gap specifically, here is what works today with zero dependencies — plus the four things that silently break it. I re-checked every detail below against the current hooks reference today (2026-10-15), because a few of the recipes earlier in this thread have gone stale.

    Two distinct sounds, one for "waiting on you" and one for "done", in ~/.codex/hooks.json:

    {
      "hooks": {
        "PermissionRequest": [
          {
            "hooks": [
              {
                "type": "command",
                "command": "afplay /System/Library/Sounds/Sosumi.aiff >/dev/null 2>&1 & osascript -e 'display notification \"Codex is waiting for you\" with title \"Codex\"' >/dev/null 2>&1",
                "timeout": 5
              }
            ]
          }
        ],
        "Stop": [
          {
            "hooks": [
              {
                "type": "command",
                "command": "afplay /System/Library/Sounds/Glass.aiff >/dev/null 2>&1 & osascript -e 'display notification \"Turn complete\" with title \"Codex\"' >/dev/null 2>&1",
                "timeout": 5
              }
            ]
          }
        ]
      }
    }

    PermissionRequest runs when Codex is about to ask for approval (it does not run for commands that need no approval); Stop runs at the turn boundary. Both hooks here return no output, so the normal approval prompt is untouched — this only notifies, it never auto-approves or denies anything. afplay and osascript are both built into macOS, so there is nothing to install.

    The four traps

    1. Hooks must be trusted before they run. Codex records trust against the hook's hash, so a new or edited hook is flagged for review and skipped until trusted. Run /hooks to review and trust it. This is the most likely reason a perfectly correct config does nothing — and it bites again every time you tweak the command.
    2. Stop rejects plain stdout. For Stop, output must be empty or JSON; plain text is invalid for that event. That is what the >/dev/null 2>&1 is doing — without it, any command that prints a line gets the hook run marked as failed.
    3. The older notify key cannot do this. It only ever receives type: agent-turn-complete, so there is no way to get a separate "needs you" sound out of it — which is exactly why tput bel never fires on permission requests (@nialse's observation). Also worth knowing: notify is ignored in project-local .codex/config.toml and must live in your user-level ~/.codex/config.toml.
    4. codex_hooks = true is stale. Hooks are enabled by default now; the feature key is [features].hooks, with codex_hooks kept only as a deprecated alias. If you copied an older snippet from this thread, you do not need that flag at all.

    If you would rather keep one file, the inline config.toml form needs a TOML triple-quoted literal, because a single-quoted literal cannot contain the quotes osascript needs (a silent parse error otherwise):

    [[hooks.Stop]]
    [[hooks.Stop.hooks]]
    type = "command"
    command = '''afplay /System/Library/Sounds/Glass.aiff >/dev/null 2>&1 & osascript -e 'display notification "Turn complete" with title "Codex"' >/dev/null 2>&1'''
    timeout = 5

    To confirm hooks actually fire on your extension build, don't take my word for it — the docs describe hook discovery from the ~/.codex config layer but do not spell out IDE-extension coverage. Probe it: temporarily set the Stop command to printf '%s stop\n' "$(date +%T)" >> ~/codex-hook-probe.log, trust it via /hooks, run one turn from the extension, then cat ~/codex-hook-probe.log. Lines appearing means the sound hooks will work there too; nothing appearing means it is engine-side and no config will fix it.

    (CLI readers: this is already built in — tui.notifications can filter by event type including approval-requested, and tui.notification_condition can restrict it to when the terminal is unfocused. See config-advanced. Per @etraut-openai, CLI behaviour is tracked separately from this thread.)

    Disclosure: I build Sleepwing (free, macOS), so season that part to taste. It is a watcher rather than a notifier: it connects to 7 coding agents (Codex is one of the three I have verified end to end), shows distinct waiting-on-you / done / failed states instead of one undifferentiated ping, and clicking a session jumps back to it — exact tab routing on Terminal.app and iTerm2, other terminals just get the app activated. It also nudges you to take the break while the agent works, which was the OP's actual goal. Zero outbound network, everything stays local. It uses the same hook events shown above, so if the probe above comes back empty, it would not help you either.

  25. Silverstar187 commented on Oct 18, 2026

    @Silverstar187

    Disclosure: I built this.

    If a sound isn't enough and you want to actually hear what finished: voicehook is a remote MCP server (https://voicehook.ai/mcp) that works with Codex. The agent opens a voice call in your browser, tells you out loud when a long task is done or when it needs a decision, and you can answer by voice from another window or the couch. A status board shows what it's doing in between.

    Free minutes, no signup: https://voicehook.ai/?utm_source=github&utm_medium=comment&utm_campaign=codex-3962

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestextensionIssues related to the VS Code extension

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions