Skip to main content

Cross-platform notifications for long-running agentic CLI tools

Project description

agent-notifier

agent-notifier sends notifications when long-running CLI/agent tasks finish.

It supports two usage styles:

  1. Wrap a command (agent-notifier run -- ...)
  2. Receive task-level events from interactive agents (Codex, Claude Code, Gemini, Ollama pipelines)

Why People Use This

  • You can keep coding in one window and get notified when a background task completes.
  • Notifications include success/failure, duration, and exit code.
  • Works on macOS, Windows, and Linux (with console fallback when desktop notifications are unavailable).

Install

Recommended:

python3 -m pip install --user pipx
python3 -m pipx ensurepath
pipx install agent-notifier

Alternative:

pip install agent-notifier

If pipx install agent-notifier fails because the package is not yet on PyPI, install from this repo checkout:

cd /path/to/AgentPulse/packages/agent-notifier
pipx install .

From source:

python -m pip install -e .

Confirm install:

agent-notifier --help
agent-notifier test-notifier --channel console

Zero-To-Working Setup (macOS, Verified)

Validated on March 2, 2026 with:

  • macOS 26.2
  • iTerm2
  • codex-cli 0.107.0
  • Gemini CLI (AfterAgent hook)

Run the helper from the repo checkout:

cd /path/to/AgentPulse/packages/agent-notifier
./examples/setup_macos.sh --trust-dir "/absolute/path/to/your/project" --open-settings

What this script does:

  • Installs terminal-notifier with Homebrew when available.
  • Installs/updates agent-notifier from local source checkout.
  • Configures Codex hook in ~/.codex/config.toml using notify = [...].
  • Configures Gemini AfterAgent hook in ~/.gemini/settings.json.
  • Marks your project as trusted in ~/.gemini/trustedFolders.json.
  • Creates timestamped backups before editing existing Codex/Gemini config files.
  • Runs test-notifier and a Codex bridge smoke test.

Important limitation:

  • macOS notification permissions cannot be auto-granted by CLI tools.
  • You must manually allow notifications for your terminal app (Terminal/iTerm) in System Settings -> Notifications.

2-Minute Quickstart

Run any long command through the wrapper:

agent-notifier run -- python3 -c "import time; time.sleep(8)"

If the command fails, the notification title changes to Failed.

Behavior Model

agent-notifier is task-level first for interactive tools. It notifies when hook events fire (Codex/Claude/Gemini integrations), not when you exit your shell.

Interactive Tool Setup

Codex CLI

Codex provides a notification hook.

Preferred (works great with pipx/pip installs):

BRIDGE_PATH="$(command -v agent-notifier-codex-hook)"
echo "$BRIDGE_PATH"

If you're running from a source checkout, use the included script bridge:

chmod +x examples/codex_notifier_bridge.sh
BRIDGE_PATH="$(realpath examples/codex_notifier_bridge.sh)"
echo "$BRIDGE_PATH"

Add to ~/.codex/config.toml:

notify = [
  "/absolute/path/to/agent-notifier-codex-hook-or-script"
]

Codex key naming:

  • notify is the Codex config key (official in current Codex CLI builds).
  • It is unrelated to this package's internal naming (agent-notifier).

Legacy filename examples/codex_notify_bridge.sh is also supported.

Optional debug logs:

export AGENT_NOTIFIER_DEBUG=1

Log location: ~/.agentnotifier/logs/codex_notifier.log

Manual Verified Flow: macOS + iTerm + Codex

Use this exact flow if you do not use examples/setup_macos.sh:

  1. Set Codex config key to notify (not notifier) in ~/.codex/config.toml:
notify = [
  "/absolute/path/to/examples/codex_notifier_bridge.sh"
]
  1. Ensure the bridge is executable:
chmod +x examples/codex_notifier_bridge.sh
  1. Restart Codex fully (fresh process), then complete one prompt.

  2. If you still do not see a popup, enable debug and inspect hook calls:

export AGENT_NOTIFIER_DEBUG=1
tail -n 80 ~/.agentnotifier/logs/codex_notifier.log
  1. Manual bridge test (copy-paste safe):
./examples/codex_notifier_bridge.sh --channel both --verbose type=agent-turn-complete turn-id=manual-check

Expected behavior:

  • You should hear a chime and/or see a desktop notification.
  • The debug log should show type=agent-turn-complete payloads and exit=0.

Common causes when chime works but popup does not:

  • macOS notification permissions disabled for your terminal app.
  • Focus / Do Not Disturb enabled.
  • Banner style disabled in System Settings -> Notifications.

Claude Code

Preferred bridge command (installed via pipx/pip):

command -v agent-notifier-claude-hook

Configure hooks in .claude/settings.local.json (or user settings):

{
  "hooks": {
    "Stop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "agent-notifier-claude-hook --event Stop"
          }
        ]
      }
    ],
    "SubagentStop": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "agent-notifier-claude-hook --event SubagentStop"
          }
        ]
      }
    ]
  }
}

Gemini CLI

Config files:

  • ~/.gemini/settings.json (hooks)
  • ~/.gemini/trustedFolders.json (folder trust)

Preferred bridge command (installed via pipx/pip):

command -v agent-notifier-gemini-hook

Configure AfterAgent hook:

{
  "hooksConfig": {
    "enabled": true
  },
  "hooks": {
    "AfterAgent": [
      {
        "matcher": "*",
        "hooks": [
          {
            "type": "command",
            "command": "agent-notifier-gemini-hook",
            "timeout": 10000
          }
        ]
      }
    ]
  }
}

Gemini trust requirement:

  • Hooks may not run in untrusted project folders.
  • If AfterAgent does not fire, confirm the current project path is trusted in ~/.gemini/trustedFolders.json.

Quick check ($PROJECT_DIR is the folder where you run Gemini):

PROJECT_DIR="/absolute/path/to/your/project"
rg -n "\"$PROJECT_DIR\"|TRUST_FOLDER" ~/.gemini/trustedFolders.json

Example update:

PROJECT_DIR="/absolute/path/to/your/project"
jq --arg p "$PROJECT_DIR" '. + {($p):"TRUST_FOLDER"}' ~/.gemini/trustedFolders.json > /tmp/trustedFolders.json && mv /tmp/trustedFolders.json ~/.gemini/trustedFolders.json

Restart Gemini after changing trust settings.

Temporary hook-fire debug:

{
  "type": "command",
  "command": "agent-notifier-gemini-hook >> /tmp/gemini_afteragent.log 2>&1",
  "timeout": 10000
}

Then run:

tail -n 20 /tmp/gemini_afteragent.log

Ollama

  • Pure interactive ollama run currently has no native per-turn completion hook.
  • If you use ollama launch codex or ollama launch claude, configure Codex/Claude hooks above.
  • For non-interactive JSON output (--format json), pipe into agent-notifier ollama-hook.

Example:

ollama run llama3 --format json | agent-notifier ollama-hook --name ollama --channel both

Core Commands

agent-notifier run -- <cmd...>

  • Run and notify on completion.
  • Wrapper exits with the same exit code as the wrapped command.

agent-notifier watch --pid <pid>

  • Watch an existing process ID until exit.

agent-notifier test-notifier

  • Send a sample notification.

agent-notifier tail --file <path> --pattern <text>

  • Notify when a log pattern appears.

Hook bridge commands used by integrations:

  • agent-notifier-codex-hook
  • agent-notifier-gemini-hook
  • agent-notifier-claude-hook
  • agent-notifier codex-hook (direct mode)
  • agent-notifier gemini-hook (direct mode)
  • agent-notifier claude-hook (direct mode)
  • agent-notifier ollama-hook

Common Customizations

Suppress notifications while terminal is focused (macOS):

agent-notifier gemini-hook --quiet-when-focused

Note: --quiet-when-focused is optional. If you copied older hook examples that included it by default and notifications seem missing, remove that flag.

Add sound:

agent-notifier claude-hook --chime ping

Force console output:

agent-notifier run --channel console -- your-command

Configuration

Environment variables:

  • AGENT_NOTIFIER_TITLE_PREFIX="Agent"
  • AGENT_NOTIFIER_CHANNELS="desktop,console"
  • AGENT_NOTIFIER_TAIL_LINES=20
  • AGENT_NOTIFIER_POLL_INTERVAL=1.0

Optional TOML config at ~/.agentnotifier/config.toml:

title_prefix = "Agent"
channels = ["desktop"]
tail_lines = 20
poll_interval = 1.0

Environment variables override file values.

Troubleshooting

I only get notifications when I exit the CLI

Check your tool hooks configuration. This project intentionally focuses on task-level notifications. If notifications only appear on session exit, verify your CLI is calling codex-hook, claude-hook, or gemini-hook on task completion events.

Desktop notifications do not appear

  1. Test fallback path:
    • agent-notifier test-notifier --channel console
  2. Test desktop + diagnostics:
    • agent-notifier test-notifier --channel both --verbose
  3. Verify platform backend:
    • macOS uses terminal-notifier first, then osascript
    • Windows uses PowerShell/BurntToast (with win10toast fallback)
    • Linux uses notify-send (package libnotify-bin on Debian/Ubuntu)
  4. macOS permission gate:
    • Notifications must be allowed manually for your terminal app in System Settings -> Notifications.

Codex notifications not firing

  1. Confirm notify is configured in ~/.codex/config.toml.
  2. Confirm bridge command/path resolves:
    • command -v agent-notifier-codex-hook (preferred), or
    • chmod +x examples/codex_notifier_bridge.sh (source checkout)
  3. Restart Codex after config changes (required).
  4. Enable bridge debug logs with AGENT_NOTIFIER_DEBUG=1 and inspect ~/.agentnotifier/logs/codex_notifier.log.
  5. Do not use the notifier key in Codex config; use notify.

Scenario Matrix (Quick Diagnosis)

Use this section to map a symptom to a concrete next action.

Symptom What it usually means Verify Fix
No notifications from Codex and log file never updates Codex hook not wired tail -n 20 ~/.agentnotifier/logs/codex_notifier.log after a completed turn Use notify = [...] in ~/.codex/config.toml and restart Codex
Codex log updates with agent-turn-complete payloads but no popup Hook runs, desktop backend or OS UI is blocking agent-notifier test-notifier --channel both --verbose Enable notifications for your terminal app, disable Focus/Do Not Disturb, enable banners
Chime plays but no popup Sound path works, visual notifications blocked by OS settings Run agent-notifier test-notifier --channel both --verbose In System Settings -> Notifications, allow alerts for terminal/iTerm and terminal-notifier (if listed)
zsh: command not found: agent-notifier Installed in a different Python env or not on PATH command -v agent-notifier Use absolute binary path (for example ~/miniconda3/bin/agent-notifier-codex-hook) or update PATH
Manual bridge test prints [codex] Done but Codex turns show nothing Bridge itself is healthy; Codex config/session issue Run manual test and compare with Codex log updates Restart Codex fully; confirm the same bridge path is in notify = [...]
Manual bridge command returns no output but exit code is 0 Event did not match (often malformed payload text) Use key-value payload form Run: ./examples/codex_notifier_bridge.sh --channel both --verbose type=agent-turn-complete turn-id=manual-check
Gemini AfterAgent hook never runs Project path is untrusted in Gemini Set hook command to write /tmp/gemini_afteragent.log and verify file updates Add project path as TRUST_FOLDER in ~/.gemini/trustedFolders.json, restart Gemini
Desktop backend failure mentions terminal-notifier terminal-notifier present but failing/crashing agent-notifier test-notifier --channel both --verbose Reinstall/fix terminal-notifier or rely on osascript fallback
Linux desktop popup missing notify-send missing/unavailable command -v notify-send Install libnotify-bin (Debian/Ubuntu) or use --channel console
Windows desktop popup missing BurntToast/PowerShell path unavailable agent-notifier test-notifier --channel both --verbose Install optional extras: pip install "agent-notifier[windows]"

Platform Notes

macOS:

  • Desktop notifications via terminal-notifier (preferred, third-party) or Notification Center (osascript fallback).
  • terminal-notifier is not an Apple-official binary; it is a widely used open-source tool.
  • Install with Homebrew: brew install terminal-notifier
  • You can still work without it because osascript fallback is built in.

Windows:

  • Primary backend: PowerShell + BurntToast.
  • Optional fallback dependency: pip install "agent-notifier[windows]".

Linux:

  • Desktop notifications via notify-send.
  • Debian/Ubuntu install: sudo apt install libnotify-bin.

For Maintainers

Development checks:

python -m pip install -e ".[dev]"
ruff check .
pytest -q
python -m build
twine check dist/*

Release checklist:

  • docs/release_checklist.md

Project/process docs:

  • docs/project_charter.md
  • docs/scrum_working_agreement.md
  • docs/assumptions.md
  • docs/commit_plan.md
  • SECURITY.md

License

MIT (LICENSE)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agent_notifier-0.1.2.tar.gz (28.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agent_notifier-0.1.2-py3-none-any.whl (33.3 kB view details)

Uploaded Python 3

File details

Details for the file agent_notifier-0.1.2.tar.gz.

File metadata

  • Download URL: agent_notifier-0.1.2.tar.gz
  • Upload date:
  • Size: 28.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for agent_notifier-0.1.2.tar.gz
Algorithm Hash digest
SHA256 7980c536493c0724063a9749c4c46344c637d2c0580c3951e8d6e6fb4d77f645
MD5 be99028a37fa56c9c514fa2f2cf76b8c
BLAKE2b-256 a09ad4dbb6cfd8b89870b3ade0dfb44081b0f4ee5772b0609448d2f5a3d8192a

See more details on using hashes here.

File details

Details for the file agent_notifier-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: agent_notifier-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 33.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for agent_notifier-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 30786d5cfb8bd0db53e21774f05b3f89ef6c3eb45a723f32458af7bd73d32f9d
MD5 504512c070d28e7ab6bc5e27e6d454d4
BLAKE2b-256 381543d539d92089ff13dd89f1155272ef48e1790204c6e5d33bde5bb9519fe2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page