Sandbox
@777genius/agent-notifications

Notifications plugin for Claude Code and Codex

Agent Notifications plugs into Claude Code and Codex so your agent work can trigger desktop alerts, sounds, focus changes, and webhooks. It uses plugin manifests and hooks to detect events like task completion, questions, review completion, session limits, and permission requests.

807 stars108 forksGoUpdated 7d ago
Who it's for

Builders who want their Claude Code or Codex sessions to notify them instead of forcing them to watch the terminal.

What it delivers

You can keep working away from the terminal and still know when your agent needs attention.

What it does

Cross-platform desktop notifications

Sends alerts on macOS, Linux, and Windows with native support for each platform.

Sound playback

Plays built-in or custom audio files and lets you choose volume and audio device.

Click to focus

On macOS and Linux, clicking a notification can bring the right terminal, tab, or pane to the front.

Webhook delivery

Posts notification events to Slack, Discord, Telegram, Teams, ntfy.sh, PagerDuty, Zapier, n8n, Make, or a custom endpoint.

Claude and Codex hook support

Listens for events like task complete, review complete, question, plan ready, session limit reached, API error, and permission request.

Installer and setup commands

Includes one-command bootstrap, Claude slash commands, and a Codex setup flow for registration and updates.

How to get it

  1. 1One command to install or update the notifications plugin for Claude Code, Codex, or…
    curl -fsSL https://raw.githubusercontent.com/777genius/agent-notifications/main/bin/bootstrap.sh | bash
  2. 2For automation or terminals without a controlling TTY, choose explicitly
    curl -fsSL https://raw.githubusercontent.com/777genius/agent-notifications/main/bin/bootstrap.sh | bash -s -- --product codex
  3. 3Run the same command and choose the product(s) you want to update
    curl -fsSL https://raw.githubusercontent.com/777genius/agent-notifications/main/bin/bootstrap.sh | bash

README

Agent Notifications

Ubuntu CI macOS CI Windows CI Go Report Card codecov

imageimageimage

Notifications for Claude Code and Codex CLI (beta), with sounds, git branch display, and webhook integrations. See Codex support and limitations for differences between products.

Boost your productivity — check out the advanced task manager for Claude with a convenient UI, from the creator of this plugin.

Table of Contents

Features

  • Cross-platform: macOS (Intel & Apple Silicon), Linux (x64 & ARM64), Windows 10+ (x64)
  • Claude notification types: Task Complete, Review Complete, Question, Plan Ready, Session Limit, API Error
  • Click-to-focus (macOS, Linux): click notification to focus the exact project window and tab — Ghostty, VS Code, iTerm2, Warp, kitty, WezTerm, Alacritty, Hyper, Apple Terminal, GNOME Terminal, Konsole, Tilix, Terminator, XFCE4 Terminal, MATE Terminal
  • Multiplexers: tmux (including iTerm2 -CC integration mode), zellij, WezTerm, kitty — click switches to the correct session/pane/tab
  • Git branch in title: ✅ Completed main [cat]
  • Sounds: MP3/WAV/FLAC/OGG/AIFF, volume control, audio device selection
  • Webhooks: Slack, Discord, Telegram, Lark/Feishu, Microsoft Teams, ntfy.sh, PagerDuty, Zapier, n8n, Make, custom — with retry, circuit breaker, rate limiting (docs)
  • Plugin compatibility: works with double-shot-latte and other plugins that spawn background Claude instances

Installation

Prerequisites

  • Claude Code and/or Codex CLI for the products you select
  • Python 3.6 or newer, available as the python3 command on PATH, is required for installer metadata and checksum validation. Check with python3 --version.
  • Windows users: Git Bash (included with Git for Windows) and native Windows Python available as python3 from Git Bash. A python or py command alone is insufficient; use native Python, not WSL Python.
  • macOS/Linux users: Ensure python3 is installed and available in the shell running the installer.

Quick Install (Recommended)

Prefer a guided setup? Open the installation guide to choose your agent, OS and task.

One command to install or update the notifications plugin for Claude Code, Codex, or both. The interactive menu asks you to choose:

curl -fsSL https://raw.githubusercontent.com/777genius/agent-notifications/main/bin/bootstrap.sh | bash

Windows users: open Git Bash from the Start menu and run this command there. Do not run the curl ... | bash command from PowerShell or Windows Terminal if bash opens WSL, because that targets Linux paths and binaries instead of Windows.

For automation or terminals without a controlling TTY, choose explicitly:

curl -fsSL https://raw.githubusercontent.com/777genius/agent-notifications/main/bin/bootstrap.sh | bash -s -- --product codex

Use claude, codex, or both. This installs the notifications plugin; the selected Claude Code / Codex CLI must already be on PATH.

After installation:

  • Claude: restart Claude Code. Optionally run /claude-notifications-go:settings to configure sounds.
  • Codex: start Codex, run /hooks, then review and trust the installed hooks. The installer registers them automatically; no JSON editing or manual registration command is needed. Trust approval remains yours.
  • Both: complete both steps above.

Codex requires a published stable plugin release v1.42.0 or newer. The installer downloads matching source and binaries, respects CODEX_HOME, and keeps a permanent runtime copy there. It reports an error if no supported release is published yet.

If installation fails, use manual Claude installation or manual Codex registration, depending on the product.

Manual Install

Step-by-step installation inside Claude Code (if bootstrap doesn't work)

Run these slash commands in the Claude Code chat, not in your system terminal:

# 1) Add marketplace
/plugin marketplace add 777genius/agent-notifications
# 2) Install plugin
/plugin install claude-notifications-go@claude-notifications-go
# 3) Restart Claude Code
# 4) Download binary
/claude-notifications-go:init
# 5) (Optional) Configure sounds and settings
/claude-notifications-go:settings

Having issues with installation? See Troubleshooting.

Updating

Run the same command and choose the product(s) you want to update:

curl -fsSL https://raw.githubusercontent.com/777genius/agent-notifications/main/bin/bootstrap.sh | bash

For Claude, restart Claude Code. For Codex, restart Codex and inspect /hooks; changed hook definitions may need trust approval again. The installer refreshes the Codex runtime and registration automatically. Existing foreign hooks and shared settings in the file selected by config path are preserved.

Manual Claude update (if bootstrap didn't work)

Claude Code also periodically checks for plugin updates automatically. Binaries are updated on the next hook invocation when a version mismatch is detected.

To update manually via Claude Code UI:

  1. Run /plugin, select Marketplaces, choose claude-notifications-go, then select Update marketplace
  2. Select Installed, choose claude-notifications-go, then select Update now

If the binary auto-update didn't work (e.g. no internet at the time), run /claude-notifications-go:init to download it manually. If hook definitions changed in the new version, restart Claude Code to apply them.

Supported Notification Types

The Claude triggers are listed below. Codex uses a different event mapping, described in Codex support.

StatusIconDescriptionTrigger
Task CompleteMain task completedStop/SubagentStop hooks (state machine detects active tools like Write/Edit/Bash, or ExitPlanMode followed by tool usage)
Review Complete🔍Code review finishedStop/SubagentStop hooks (state machine detects only read-like tools: Read/Grep/Glob with no active tools, plus long text response >200 chars)
QuestionClaude has a questionPreToolUse hook (AskUserQuestion) OR Notification hook
Plan Ready📋Plan ready for approvalPreToolUse hook (ExitPlanMode)
Session Limit Reached⏱️Session limit reachedStop/SubagentStop hooks (state machine detects "Session limit reached" text in last 3 assistant messages)
API Error🔴Authentication expired, rate limit, server error, connection errorStop/SubagentStop hooks (state machine detects via isApiErrorMessage flag + error field from JSONL)
Permission Request🔐Codex is waiting for tool approvalCodex PermissionRequest hook (Codex only)

Codex CLI Support (beta)

The same binary can notify for OpenAI Codex CLI sessions.

Setup

Use the one-command installer and choose Codex or both. It downloads matching release source and binaries, registers the hooks, and keeps a stable runtime copy. Then start Codex and approve the entries in /hooks.

Manual Codex registration

Skip this section if you used the one-command installer. For manual setup, download a matching release bundle and binary (v1.42.0 or newer). The Go registration command needs no jq and is not automatically added to your PATH.

From the bundle directory:

./bin/claude-notifications setup-codex --plugin-root .

On Windows, run the downloaded claude-notifications-windows-amd64.exe in PowerShell:

.\bin\claude-notifications-windows-amd64.exe setup-codex --plugin-root .

Run these commands in the bundle directory. If you have explicitly added the binary to PATH, claude-notifications setup-codex --plugin-root <bundle-directory> also works.

It installs a self-contained copy of the plugin at ~/.codex/claude-notifications-go and writes the hook entries into ~/.codex/hooks.json. Existing foreign hook definitions and unknown fields are preserved, and every run saves a uniquely named backup of the previous file next to it.

Then start Codex, run /hooks, review the entries and trust them.

Useful flags: --dry-run shows what would change, --print outputs the JSON so you can merge it yourself, --codex-home and --plugin-root override the paths.

For manual updates, run the registration command again to refresh the installed copy. Unchanged hook definitions retain trust; changed definitions require review again. The one-command installer handles this registration step automatically.

Claude Code installation and updates continue to use the existing installation steps. Both products share settings at the shared file selected by config path; installing Codex does not require installing Claude Code. Keep your existing settings file when updating.

How registration works

setup-codex registers user hooks explicitly, using a stable runtime directory independent of the plugin cache. This is the setup path covered by this project's installer tests. The bundle also includes a Codex plugin manifest. Codex versions can differ in plugin-hook loading; follow the current Codex hooks documentation for native plugin setup. Use one registration path to avoid duplicate hooks, and inspect /hooks after installation.

Codex includes the command string in its trust hash, so the registration deliberately points at the stable ~/.codex/claude-notifications-go copy rather than a versioned plugin cache directory — that is what keeps the trust valid across updates.

What works today:

  • Stop - a turn finishes; the status comes from the final assistant message: short failure reports map to the API Error / Session Limit statuses, a trailing question mark maps to Question, otherwise Task Complete. The Codex rollout transcript is not parsed (it is an internal, unstable format).
  • Question payloads (experimental) - if Codex emits PreToolUse for request_user_input, the plugin delivers the question/header text. Options, ids, and secret fields are excluded. Live firing of this tool hook is not yet qualified; do not rely on it for every question.
  • PermissionRequest - Codex is waiting for your approval of a tool call; delivered as the time-sensitive Permission Request status. Only the tool name is shown, never the tool input.
  • SubagentStop (opt-in) - with notifyOnSubagentStop: true and suppressForSubagents: false, subagent completions notify with the subagent's final message.

Known limitations:

  • PermissionRequest cannot fire when Codex never asks for approval (bypassPermissions, --ask-for-approval never, headless codex exec).
  • The error statuses for Codex come from a text heuristic over the final message (short messages with failure phrasing), not from structured error data - false negatives are possible.
  • The request_user_input question hook is limited to the modes where Codex exposes that tool.
  • Windows support for the Codex route is not declared until the Windows launcher is proven.
  • Codex hooks require a trust review (/hooks inside Codex); changed definitions require review again.

Both products share one config file (the shared file selected by config path).

Platform Support

Supported platforms:

  • macOS (Intel & Apple Silicon)
  • Linux (x64 & ARM64)
  • Windows 10+ (x64)

No additional dependencies:

  • ✅ Binaries auto-download from GitHub Releases
  • ✅ Pure Go - no C compiler needed
  • ✅ All libraries bundled
  • ✅ Works offline after first setup

Windows-specific features:

  • Native Toast notifications (Windows 10+)
  • After installation, notifications work in PowerShell, CMD, Git Bash, or WSL
  • MP3/WAV/OGG/FLAC audio playback via native Windows APIs
  • System sounds not accessible - use built-in MP3s or custom files

Click-to-Focus (macOS & Linux)

Clicking a notification activates your terminal window. Auto-detects terminal and platform.

macOS — via AX API with bundle ID detection:

TerminalFocus method
GhosttyExact tab focus via Ghostty AppleScript, with AXDocument fallback
VS Code / Insiders / CursorAXTitle (focus-window subcommand)
iTerm2Exact tab/pane targeting via iTerm2 Python API when available, otherwise app-level iTerm activation
Warp, kitty, WezTerm, Alacritty, Hyper, Apple TerminalAXTitle (focus-window subcommand)
Any other (custom terminalBundleId)AXTitle (focus-window subcommand)

Linux — via D-Bus daemon with automatic compositor detection:

TerminalSupported compositors
VS CodeGNOME, KDE, Sway, X11
GNOME Terminal, Konsole, Alacritty, kitty, WezTerm, Tilix, Terminator, XFCE4 Terminal, MATE TerminalGNOME, KDE, Sway, X11
Any otherFallback by name

Linux focus methods (tried in order): GNOME extension, GNOME Shell Eval, GNOME FocusApp, wlrctl (Sway/wlroots), kdotool (KDE), xdotool (X11).

Multiplexers (both platforms): tmux (including iTerm2 -CC integration mode), zellij, WezTerm, kitty — click switches to the correct pane/tab.

iTerm2 note: to open the exact iTerm2 tab or split pane, enable iTerm2 > Settings > General > Magic > Enable Python API. If you just toggled it, restart iTerm2 once. Without the Python API, the plugin falls back to app-level iTerm activation instead of exact tab targeting.

Windows — clicking a notification raises the originating terminal window (Windows Terminal, VS Code, conhost, …) via a protocol-activated toast. Window-level only: tab/split-pane targeting isn't possible (one window hosts all tabs), and picking among multiple WT windows in one process is best-effort. See the guide for details.

See Click-to-Focus Guide for configuration details.

Configuration

The following workflow requires the coordinated config-capable runtime and installer; older releases may not provide these commands. Do not use a legacy full-file writer as a fallback.

Run /claude-notifications-go:settings to configure sounds, volume, webhooks, and other options via an interactive wizard. You can re-run it anytime to reconfigure.

Manual Configuration

Use the installed config-capable executable (shown as $NOTIFICATIONS_BIN in recipes):

"$NOTIFICATIONS_BIN" config path --json
"$NOTIFICATIONS_BIN" config inspect --json

One file is selected per environment context: explicit E, otherwise existing L, otherwise N. Existing L is preserved; there is no automatic migration, copy, merge or synchronization.

SelectionNative file path
E: AGENT_NOTIFICATIONS_CONFIGAn absolute file, not a directory
L: existing legacy file, macOS/Linux$HOME/.claude/claude-notifications-go/config.json
L: existing legacy file, Windows%USERPROFILE%\.claude\claude-notifications-go\config.json
N: fresh macOS$HOME/Library/Application Support/agent-notifications/config.json
N: fresh LinuxAbsolute nonempty $XDG_CONFIG_HOME/agent-notifications/config.json, otherwise $HOME/.config/agent-notifications/config.json
N: fresh Windows%APPDATA%\agent-notifications\config.json

Relative XDG_CONFIG_HOME is ignored with a diagnostic. Windows uses USERPROFILE for L, not Git Bash HOME; missing/relative APPDATA without L is an error. macOS ignores XDG_CONFIG_HOME. Missing home in automatic mode is an error; a valid explicit E supports portable contexts without HOME/APPDATA.

Unset E enables automatic selection; set-empty, whitespace-only, relative, ~/file and invalid native paths are errors, never fallback. The resolver does not expand variables or tilde in E. Expand them in the calling shell if intended; Git Bash may use cygpath -w to supply a native absolute Windows path. Do not trim legitimate spaces in filenames.

For writable targets, .lock filenames and generated .tmp-<32 hex digits> / .backup-<32 hex digits> names are reserved for coordination and recovery metadata. Choose another filename for a portable config.

If L and N both exist, L wins with a diagnostic even if identical or N is newer. To intentionally select N, set E in every new adapter and CLI environment. Unsetting E restores legacy-first selection. Old binaries ignore E. CODEX_HOME, CLAUDE_HOME, CLAUDE_CONFIG_DIR, product, cwd and bundle/install paths do not select notification config. They retain their resource/installation meanings; permission markers, venv and state paths do not move.

config init is create-only: existing valid config is a byte/mode/mtime-preserving no-op; invalid existing config is an error. Hooks never write config and use in-memory defaults only for truly missing automatic config after historical recovery checks. Explicit missing E, corrupt/unreadable canonical files and unresolved recovery artifacts are errors, with no bundle/default fallback.

Use the settings recipe for config edit --stdin --expect-revision TOKEN: private input, only requested JSON Pointer leaf edits, raw values, and an explicit user decision after any conflict. A volume plus one status sound edit preserves every other raw field, status, channel, webhook secret/payload and future-agent setting. Inspect is a safe projection, not a replacement document; absent free-form values are not unset.

Before any updater deletes/refreshes cache, personalized or unknown historical cache-only/custom-root settings require explicit import using a verified new helper: stop old writers, inspect the selected destination, then config init --from FILE only if that destination is missing. Never auto-copy a bundle, guess the newest cache, overwrite existing canonical config, or treat this as migration/reset. If preflight/helper is unavailable, stop the update and retain the old runtime. For existing invalid config, stop writers and explicitly repair/recover it while preserving damaged bytes; init cannot reset it.

Existing L with v1-shaped JSON remains readable by the old Go reader, which ignores additive unknown fields. The old wizard loses unknown fields and is an unsupported concurrent writer. N/E require a bridge-aware runtime, or explicit stopped-writer recovery to a single legacy canonical file with a private backup and all contexts switched; two live copies are not a workaround. No downloadable bridge release is promised here. Native Windows replacement/ACL, macOS/Linux crash/concurrency and OS E2E qualification remain release gates, not results established by this documentation patch.

For support, share only config inspect --json, never cat of config; keep saved diagnostics private and review paths before posting. The response includes selection (path/source/exists/diagnostics), revision, schemaVersion, valid, optional errorCode, and safe settings: desktopEnabled, desktopSound, volume and known-status enabled/desktopEnabled/webhookEnabled. It omits free-form sounds, webhook secrets/payloads and unknown fields.

The following JSON illustrates the schema. Do not replace your existing document with it; apply only explicitly requested leaf edits:

{
  "notifications": {
    "desktop": {
      "enabled": true,
      "sound": true,
      "volume": 1.0,
      "audioDevice": "",
      "clickToFocus": true,
      "terminalBundleId": "",
      "showSessionLabel": true,
      "appIcon": "${CLAUDE_PLUGIN_ROOT}/claude_icon.png"
    },
    "webhook": {
      "enabled": false,
      "preset": "slack",
      "url": "",
      "chat_id": "",
      "format": "json",
      "headers": {},
      "payloadFields": {}
    },
    "suppressQuestionAfterTaskCompleteSeconds": 12,
    "suppressQuestionAfterAnyNotificationSeconds": 7,
    "notifyOnSubagentStop": false,
    "suppressForSubagents": true,
    "notifyOnTextResponse": true,
    "respectJudgeMode": true,
    "notifyOnlyWhenUnfocused": false,
    "notifyDelaySeconds": 0,
    "suppressFilters": [
      {
        "name": "Suppress ClaudeProbe completions (remote-control)",
        "status": "task_complete",
        "gitBranch": "",
        "folder": "ClaudeProbe"
      }
    ]
  },
  "statuses": {
    "task_complete": {
      "title": "✅ Completed",
      "sound": "${CLAUDE_PLUGIN_ROOT}/sounds/task-complete.mp3"
    },
    "review_complete": {
      "title": "🔍 Review",
      "sound": "${CLAUDE_PLUGIN_ROOT}/sounds/review-complete.mp3"
    },
    "question": {
      "title": "❓ Question",
      "sound": "${CLAUDE_PLUGIN_ROOT}/sounds/question.mp3"
    },
    "plan_ready": {
      "title": "📋 Plan",
      "sound": "${CLAUDE_PLUGIN_ROOT}/sounds/plan-ready.mp3"
    },
    "session_limit_reached": {
      "title": "⏱️ Session Limit Reached",
      "sound": "${CLAUDE_PLUGIN_ROOT}/sounds/error.mp3"
    },
    "api_error": {
      "title": "🔴 API Error: 401",
      "sound": "${CLAUDE_PLUGIN_ROOT}/sounds/error.mp3"
    },
    "api_error_overloaded": {
      "title": "🔴 API Error",
      "sound": "${CLAUDE_PLUGIN_ROOT}/sounds/error.mp3"
    }
  }
}
OptionDefaultDescription
notifyOnSubagentStopfalseSend notifications when subagents (Task tool) complete. Has no effect unless suppressForSubagents is also set to false.
suppressForSubagentstrueSuppress subagent (SubagentStop) notifications, plus any Stop notification whose transcript is a subagent/teammate transcript. Detection uses the

Files in the repo

Repository payload29 top-level entries
  • .claude-plugin
  • .codex-plugin
  • .github
  • bin
  • cmd
  • commands
  • config
  • docs
  • hooks
  • internal
  • landing
  • pkg
  • scripts
  • sounds
  • swift-notifier
  • .codecov.yml
  • .gitattributes
  • .gitignore
  • .golangci.yml
  • .orphaned_at
  • CHANGELOG.md
  • claude_icon.png
  • CONTRIBUTING.md
  • go.mod
  • go.sum
  • LICENSE
  • Makefile
  • README.md
  • setup.sh

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More plugins

Makes your AI agent think like the laziest senior dev in the room. The best code is the code you never wrote.

138k
1 add

Graphs that teach > graphs that impress. Turn any code into an interactive knowledge graph you can explore, search, and ask questions about. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, and more.

82k
code-yeongyu/
oh-my-openagent

OmO: Just type "mass ulw" keyword with your prompt. Now you are the master of graph engineering.

69k

Persistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode + More

94k

Opinionated Oxlint rules for rejecting low-evidence TypeScript and JavaScript patterns

4.3k