iTranslated by AI
Displaying Notifications from the Command Line on macOS
Environment: macOS Sequoia 15.5
Initial Setup
If you search, you will find information suggesting that you can use display notification with the osascript command, but for some reason, it only finishes normally without any notification appearing!!!
I found someone with the same issue, and learned that it works once you issue a notification from the Script Editor.

After running display notification "Hello" with title "Hi" in the Script Editor and enabling notifications for Script Editor in the System Settings (Notifications), I was able to issue notifications from the osascript command as well. Good for me.
Sending notifications via the osascript command
To send a notification, you can use display notification {body} with title {title}.
osascript -e 'display notification "Lorem ipsum dolor sit amet" with title "Title"'
Specifying notification content with arguments
on run argv
display notification (item 1 of argv as text) with title "通知"
end run
By running a script like this, you can specify the first argument as the notification content.
By the way, there is a technique for entering multi-line scripts in osascript by specifying -e multiple times, which can be written like this:
osascript -e 'on run argv' -e 'display notification (item 1 of argv as text)' -e 'end run' Hello
Reading notification content from standard input
osascript -e 'on run argv' -e 'display notification (item 1 of argv as text)' -e 'end run' "$(cat)"
You can do something like this.
For Claude Code Notification events
Read {"message": string, "title": string} from STDIN and issue a notification.
jq -j '.message, "\u0000", .title // "Claude Code", "\u0000"' | xargs -0 osascript -e 'on run argv' -e 'display notification (item 1 of argv as text) with title (item 2 of argv as text)' -e 'end run'
For Claude Code Stop events
Read the corresponding message from the log and issue a notification.
osascript -e 'on run argv' -e 'display notification (item 1 of argv as text) with title "Claude Code"' -e 'end run' "$(jq -r '.transcript_path' | xargs tail -n 1 | jq -r '.message.content[0].text // "Completed"')"
Discussion