#!/usr/bin/env python3 """Notification hook: a desktop notification when Claude is waiting on you. settings.json wires it to `idle_prompt|permission_prompt` (the Notification matcher is the `notification_type`). Push notifications are off in this setup, so this is the local counterpart of pi's notify.ts. Uses notify-send where present (the Wayland/GUI hosts) and silently no-ops on a headless box or without a session bus. Payload fields are read defensively -- the docs do not pin the Notification input schema: `message`, `title`, `notification_type`, `cwd`. """ import json import os import shutil import subprocess import sys TITLES = { "idle_prompt": "Claude Code is waiting for you", "permission_prompt": "Claude Code needs a permission", } def main(): try: data = json.load(sys.stdin) except Exception: return exe = shutil.which("notify-send") if not exe: return kind = data.get("notification_type") or "notification" title = data.get("title") or TITLES.get(kind, "Claude Code") body = (data.get("message") or "").strip() or kind cwd = data.get("cwd") or "" if cwd: home = os.path.expanduser("~") body += "\n" + (("~" + cwd[len(home):]) if cwd.startswith(home) else cwd) try: subprocess.run( [exe, "--app-name=Claude Code", "--urgency=normal", "--expire-time=8000", # same tag -> a newer notification replaces the previous one instead of stacking f"--hint=string:x-canonical-private-synchronous:claude-code-{kind}", title, body], timeout=5, capture_output=True, ) except Exception: pass if __name__ == "__main__": main()