Coding tools · 02

Codex CLI

Use Codex CLI’s top-level notify setting to receive agent-turn-complete JSON. The example uses only thread, turn, and working-directory fields; it does not upload prompts or assistant responses.

Current official configuration

notify receives one JSON argument

On agent-turn-complete, Codex CLI runs the program specified by the notify array, passing JSON as a single command-line argument. The current payload includes thread-id, turn-id, cwd and other fields.

Step 1

Create a notify adapter script

codex-bluebell.py
#!/usr/bin/env python3
import json, os, subprocess, sys

CLI = "/Applications/bluebellMac.app/Contents/Helpers/bluebellctl"

try:
    payload = json.loads(sys.argv[1])
except Exception:
    sys.exit(0)

if payload.get("type") != "agent-turn-complete":
    sys.exit(0)

thread_id = str(payload.get("thread-id") or "")
turn_id = str(payload.get("turn-id") or "")
cwd = str(payload.get("cwd") or "")
if not thread_id or not turn_id:
    sys.exit(0)

subprocess.run([
    CLI, "emit",
    "--source", "Codex CLI",
    "--workspace-name", os.path.basename(cwd) or "Codex CLI",
    "--session-id", thread_id,
    "--turn-id", turn_id,
    "--dedupe-key", f"codex-cli:{thread_id}:{turn_id}",
    "--local",
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=3, check=False)

thread-id + turn-id form a stable deduplication ID. The example does not use last-assistant-message, preventing response text from accidentally entering notification metadata.

Step 2

Add it to the user-level config.toml

In ~/.codex/config.toml, add a top-level line and replace the script’s absolute path:

config.toml
notify = ["python3", "/absolute/path/codex-bluebell.py"]

This setting does not belong under a project section. Preserve other settings and avoid adding a second conflicting notify.

Step 3

Verify CLI turns first

  1. Keep bluebell Mac running and complete a short task with Codex CLI.
  2. Check that recent notifications contains just one local event from Codex CLI.
  3. Complete a second turn in the same thread and confirm that it produces a different turn-id.
  4. After verification, remove --local from the adapter. Then check Mac remote delivery, the iCloud queue, and a real Watch.

Sources

OpenAI official references