anotifier / codex
Codex CLI logo

anotifier for Codex CLI.

Codex works quietly in your terminal until it's done — or until it's stuck waiting for you to approve a command. anotifier turns both moments into notifications on your desktop, phone, or team chat.

$ npx anotifier@latest setup
[ HOW IT HOOKS IN ]

Wired into Codex CLI itself.

Setup registers three hooks with Codex CLI's own hook system in ~/.codex/hooks.json, and records them as trusted so Codex runs them without a review step.

StopCodex finished its turnTitled backend · Codex, with the body backend: Task complete. anotifier doesn't read Codex's reply, so the text is the same every time; the project name tells you which run finished.
PermissionRequestCodex is waiting for your approvalbackend: Needs your input, sent urgent with its own sound. The command isn't in the alert; you see it in the terminal. anotifier never answers the request, so Codex's own approval prompt decides.
SessionStartA Codex session startedQuiet by default: toast, phone push and bell are off for this event. A webhook, if you set one up, still receives Session started.
[ WHAT SETUP WRITES ]

Hooks in hooks.json, trust in config.toml.

Setup wires Codex when a ~/.codex folder exists. It backs up hooks.json to ~/.anotifier/backups/, then adds one entry per event to ~/.codex/hooks.json. This is the Stop one:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node \"/path/to/anotifier/src/notify.mjs\" --source codex --event Stop",
            "timeout": 10,
            "statusMessage": "Sending notification"
          }
        ]
      }
    ]
  }
}

PermissionRequest and SessionStart get the same entry with their own --event. In ~/.codex/config.toml, setup turns hooks on (renaming an older codex_hooks = true) and records a trust hash for each entry:

[features]
hooks = true

[hooks.state.'/home/you/.codex/hooks.json:stop:0:0']
trusted_hash = "sha256:…"

Codex skips a new or edited hook until it is trusted, which is why setup writes the hashes. Edit an anotifier entry by hand and Codex skips it until you trust it again in /hooks, or rerun setup.

[ GOOD TO KNOW ]

What it does, and what it doesn't.

  • Interactive sessions only. Codex runs hooks in its TUI, not in codex exec, so scripted runs finish without an alert.
  • Codex waits for the hook. Hooks run synchronously: Codex shows “Sending notification” until anotifier exits, at most 10 seconds. Every channel sends in parallel with a shorter timeout of its own.
  • Codex's built-in alerts still work. Its [tui] notifications setting can ding or post a desktop notification too; the Codex sound guide shows how to tune them so you don't hear two dings.
  • The ding is a bell anotifier writes to the terminal Codex runs in, or to its tmux pane; on Windows, to the console Codex runs in.
  • Click-to-focus is Windows-only. Clicking the toast brings forward the window whose title contains the project folder. macOS, Linux and WSL toasts have no click action.
  • Uninstall removes the three entries and their trust hashes, and leaves [features] hooks = true as it is.
  • Tested with Codex CLI 0.144.0 and later.
[ CHANNELS ]

Every channel you'd actually use.

[+] Desktop toasts macOS, Windows, Linux + WSL routing.
[+] Phone push Android & iOS via ntfy — no account.
[+] Webhooks Slack, Discord, Telegram, any HTTP endpoint.
[+] Terminal bell A ding in the terminal the agent runs in.
[+] Click-to-focus On Windows, a click on the toast brings the project's window forward.
[+] Zero npm dependencies Plain Node.js 18+, one shared config.
[ CHECK IT, UNDO IT ]

Test it, then keep it or remove it.

npx anotifier@latest test       # fire a test alert on every channel
npx anotifier@latest status     # show which agents and channels are set up
npx anotifier@latest doctor     # diagnose a channel that stays quiet
npx anotifier@latest uninstall  # remove the hooks setup added

test sends straight to your channels without going through Codex CLI, so it proves the channels work. uninstall removes only the entries anotifier added and restores your statusline (1.5.0 and later), and setup keeps a copy of every file it changes in ~/.anotifier/backups/.

[ FAQ ]

Codex CLI questions, answered.

How does anotifier know when Codex CLI is done?

Codex CLI has its own hook system. anotifier setup writes Stop, PermissionRequest and SessionStart hooks into ~/.codex/hooks.json, turns hooks on in ~/.codex/config.toml, and records a trust hash for each, so Codex runs them straight away.

Does the approval alert show the command?

No. It says my-app: Needs your input, sent urgent with its own sound. The command itself is in the Codex terminal, where you approve it.

Can I approve a Codex request from the notification?

No. anotifier only tells you that Codex is waiting. It never answers the PermissionRequest, so Codex's normal approval prompt decides.

Does it slow Codex down?

Codex waits for each hook to finish, showing “Sending notification”, for at most 10 seconds. anotifier sends to every channel in parallel with shorter timeouts of its own and always exits cleanly, so a dead channel can't stall a run.

Why is there no alert when I use codex exec?

Codex runs hooks in the interactive TUI only, so codex exec runs finish without one.

[ GUIDES ]

Every option, explained.

[ ALSO WORKS WITH ]

One config, every agent.

Every command and config key is in the docs.

Full feature tour, demo video, and install options on the anotifier home page.