#!/usr/bin/env bash # macOS notification for omo (senpi) Stop and Notification hooks. # Reads the hook JSON payload on stdin. Wired up in ~/.omo/agent/hooks.json. # Hooks run with a minimal environment, so make Homebrew tools reachable. export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH" payload=$(cat) field() { jq -r "$1 // empty" <<<"$payload" 2>/dev/null; } event=$(field '.hook_event_name') project=$(basename "$(field '.cwd')") case "$event" in Stop) # Esc/interrupts are your own doing; no need to be told about them. [[ "$(field '.stopReason')" == "aborted" ]] && exit 0 # Only top-level sessions live under .omo/agent/sessions/. Subagents, team members # and other background sessions keep transcripts elsewhere (e.g. senpi-task/children). transcript=$(field '.transcript_path') [[ -z "$transcript" || "$transcript" == */.omo/agent/sessions/* ]] || exit 0 if [[ "$(field '.stopReason')" == "error" ]]; then message="Stopped with an error" else message="Task finished" fi sound="Glass" ;; Notification) # Only alert when a question appears, not when it is answered or times out. [[ "$(field '.kind')" == "ask-user-asked" ]] || exit 0 message="Needs your input: $(field '.title')" sound="Ping" ;; *) exit 0 ;; esac log="${OMO_NOTIFY_LOG:-$HOME/.local/state/omo-notify.log}" mkdir -p "$(dirname "$log")" printf '%s %s %s %s [%s %s]\n' "$(date '+%F %T')" "$event" "$project" "$message" \ "$(field '.session_id')" "$(field '.transcript_path')" >>"$log" # Pass values as argv so quotes in titles cannot break the AppleScript. osascript - "omo: ${project:-session}" "$message" "$sound" <<'APPLESCRIPT' >/dev/null 2>&1 on run argv display notification (item 2 of argv) with title (item 1 of argv) sound name (item 3 of argv) end run APPLESCRIPT exit 0