Codex CLI
OpenAI Codex sessions - phone shows what tool it's running.

Codex CLI's hooks fire on lifecycle events with stdin-delivered JSON payloads, much like Claude Code's. The Chirp hook script reads each event, normalizes it into the @codex Live Activity state, and POSTs an update.
Two notable Codex-specific differences from Claude Code: (1) Codex uses `PermissionRequest` instead of `Notification` for permission prompts - same waiting-state UX, different hook name. (2) Codex's `Stop` event carries `last_assistant_message`, which we surface as the final action line ("Wrote auth helper" etc.) instead of the generic "Response complete".
Prerequisites
- Codex CLI installed (`developers.openai.com/codex/install`).
- Chirp installed on your phone, signed in.
- Python 3.9+ on your machine.
Setup
- 1
Install + authenticate Chirp
Same
chirp loginpairing as the Python SDK. The token at~/.chirprcis shared across every Chirp integration on this machine - one auth covers everything.shellpip install chirp-sdk chirp login - 2
Drop the hook script into ~/.codex/hooks/
Single-file Python script - pure stdlib, no external deps beyond the Chirp SDK. Codex looks here for hook commands referenced in config.toml.
shellmkdir -p ~/.codex/hooks curl -fsSL https://chirpapp.dev/hooks/codex.py \ -o ~/.codex/hooks/chirp-hook.py chmod +x ~/.codex/hooks/chirp-hook.py - 3
Wire the hooks in ~/.codex/config.toml
Codex uses TOML rather than JSON. Append the three
[[hooks.<EventName>]]blocks below. Restart any running Codex sessions for changes to take effect. The script's first arg distinguishes which event called it - same hook script handles all three.~/.codex/config.toml[[hooks.PreToolUse]] command = "python3 ~/.codex/hooks/chirp-hook.py PreToolUse" [[hooks.PermissionRequest]] command = "python3 ~/.codex/hooks/chirp-hook.py PermissionRequest" [[hooks.Stop]] command = "python3 ~/.codex/hooks/chirp-hook.py Stop" - 4
(Optional) SessionStart for explicit start
PreToolUse implicitly starts the activity on first tool call. If you want the card to appear the moment Codex launches (before any tool runs), add a SessionStart hook too. Useful for long-thinking sessions where the agent reads/plans before acting.
shell[[hooks.SessionStart]] command = "python3 ~/.codex/hooks/chirp-hook.py SessionStart"
What you’ll see
When Codex starts a session, the card shows "Codex · WORKING" in OpenAI mint-green with the cwd as subtitle. Each tool call updates the action line - `apply_patch · src/auth.ts`, `Bash · pytest`, `Read · server/index.ts`. PermissionRequest events flip the card amber with the prompt text (e.g. "Allow Bash to run `npm install`?"). Session end (Stop) closes green with the agent's last_assistant_message as the summary line.
Troubleshooting
- Hooks aren't firing - Codex runs but the card never appears.
- Codex only loads hooks from a *trusted* config layer. Run
codex trustin the directory where config.toml lives. Then restart your Codex session. If still nothing, verify the script runs manually:echo '{"hook_event_name":"SessionStart"}' | python3 ~/.codex/hooks/chirp-hook.py SessionStart. - Card flips waiting forever after a permission was denied.
- Codex doesn't fire a follow-up event when you deny a permission. The hook script clears the waiting state after 5 minutes by default; you can pull-to-dismiss in the Chirp app to clear it sooner.
- I want to use a project-local config instead of ~/.codex/config.toml.
- Codex supports
<project>/.codex/config.toml- same syntax, same hook block. The hook script can live in<project>/.codex/hooks/so the whole setup is self-contained per repo. - Apple-style apply_patch gets logged as `apply_patch · undefined` in the action line.
- Codex's apply_patch payload has the file path under
tool_input.path(notfile_pathlike Claude). The hook script handles both names; if you seeundefined, you're on an older script -curlthe latest version.