How to get notified when OpenCode or Copilot CLI finishes on Mac
OpenCode: set attention.enabled to true in ~/.config/opencode/tui.json for a desktop notification and a sound when a session finishes, asks a question, needs permission or fails; or write a small plugin on session.idle. Copilot CLI: it has no notification setting of its own, but a hook file in ~/.copilot/hooks/ can run osascript on agentStop and notification. Ambient connects to both, in beta, with one click, and shows them next to your Claude Code, Codex and Gemini CLI sessions.
Get Ambient Free for macOS 14 and later.
OpenCode: the built-in attention settings
OpenCode's terminal UI can ask for your attention, but the feature is off by default. Turn it on in ~/.config/opencode/tui.json (or a tui.json in the project root):
{
"$schema": "https://opencode.ai/tui.json",
"attention": {
"enabled": true,
"notifications": true,
"sound": true,
"volume": 0.4
}
}
With that on, OpenCode requests attention for questions, permission requests, session errors and completed sessions. Sounds play for each of them; desktop notifications are sent only when the terminal isn't in front, so you aren't interrupted while you're watching. sounds lets you swap in your own files for the question, permission, error, done and subagent_done events, and sound_pack picks a different set. The OpenCode desktop app sends system notifications on its own when a reply is ready or a session errors, without any of this.
OpenCode: a plugin for anything else
OpenCode has no command hooks, but it loads every JavaScript file in ~/.config/opencode/plugins/ at startup and hands each one its events. This plugin posts a macOS notification when a session goes idle, which is OpenCode's “finished responding”, and when it asks for permission:
// ~/.config/opencode/plugins/notify.js
export const Notify = async ({ $ }) => ({
event: async ({ event }) => {
if (event.type === "session.idle") {
await $`osascript -e 'display notification "OpenCode is done" with title "OpenCode"'`
}
if (event.type === "permission.asked") {
await $`osascript -e 'display notification "OpenCode needs your permission" with title "OpenCode"'`
}
},
})
Swap osascript for afplay /System/Library/Sounds/Glass.aiff if you'd rather hear it, or run anything else: a curl to a push service, a tmux display-message. Notifications from osascript appear as coming from Script Editor, so allow that under System Settings › Notifications if nothing shows. Restart OpenCode after adding the file.
Copilot CLI: hooks, since there's no setting
GitHub Copilot CLI's command and settings references list no notification, sound or bell option. Its hooks reference does list the events you need. Hook files are JSON, loaded from .github/hooks/*.json in a repository and, for every project, from ~/.copilot/hooks/*.json. agentStop runs when the main agent finishes a turn; notification runs, without blocking, when Copilot would tell you something, including a permission_prompt or an elicitation_dialog, its name for a question. Save this as ~/.copilot/hooks/notify.json:
{
"version": 1,
"hooks": {
"agentStop": [
{ "type": "command", "bash": "osascript -e 'display notification \"Copilot is done\" with title \"Copilot CLI\"'", "timeoutSec": 5 }
],
"notification": [
{ "type": "command", "matcher": "permission_prompt|elicitation_dialog", "bash": "osascript -e 'display notification \"Copilot needs you\" with title \"Copilot CLI\"'", "timeoutSec": 5 }
]
}
}
Copilot waits for an agentStop hook and reads its output as a decision, so keep the command quick and silent: printing nothing means “carry on as usual”. The matcher on notification is a regular expression on the notification type; without it the hook also fires for finished background shells and subagents. Start a new session for the file to be picked up.
Ambient: both agents, one place
Ambient shows every agent on your Mac in one notch island, menu bar list and set of notifications, most urgent first: needs you, then error, done and working. OpenCode and GitHub Copilot CLI are supported in beta alongside Claude Code, Codex, Gemini CLI, Antigravity and Cursor. Connect them under Settings › Agents, or from a terminal:
~/.ambient/bin/ambient install opencode copilot
~/.ambient/bin/ambient doctor
For OpenCode that writes a plugin of Ambient's own, ~/.config/opencode/plugins/ambient.js, which turns session.idle, permission.asked, session.error and the rest into events for the local ambient command without waiting for it. For Copilot CLI it writes a hook file of its own, ~/.copilot/hooks/ambient.json, one entry per event. Neither touches any file you wrote, and ambient uninstall removes them. Ambient then shows prompts, tools and finished or failed turns for both, and needs you for OpenCode's permission requests and Copilot's permission prompts and questions. As with every agent, banners and chimes come only for moments that need you, and stay quiet while you're already in the terminal running the agent.
Beta means the connection follows each tool's documented events but hasn't yet been run against the tool itself the way the others have. If a state doesn't show, ambient doctor checks the chain, and the issue tracker is the place to say so.
Stop babysitting terminals.
Free for macOS 14 and later. Works with Claude Code, Codex and Gemini CLI.
Get AmbientOr brew install --cask viveky259259/tap/ambient · Star on GitHub
Common questions
Does OpenCode notify me when it's done out of the box?
Not until you turn it on. The TUI's attention feature is off by default; set attention.enabled to true in ~/.config/opencode/tui.json and you get a desktop notification and a sound for completed sessions, questions, permissions and errors. The OpenCode desktop app sends system notifications on its own.
Does Copilot CLI have a notification setting?
Not one documented in its command or settings reference. What it does have is hooks: a JSON file in ~/.copilot/hooks/ can run a command on agentStop, when a turn ends, and on notification, when it asks for permission or a question. Ambient uses those same hooks.
Why does Ambient call its OpenCode and Copilot CLI support beta?
Both connections follow each tool's documented events but haven't yet been exercised against the tool itself the way the Claude Code, Codex and Gemini CLI ones have. If something doesn't show, run ambient doctor and open an issue on GitHub.
Can I get a sound instead of a banner?
Yes. OpenCode's attention settings play a sound of their own, with a volume and custom sound files per event. In a Copilot CLI hook, swap osascript for afplay /System/Library/Sounds/Glass.aiff. Ambient plays a different two-note chime for needs you, done and error, for every agent it tracks.
Sources
- TUI, OpenCode docs (attention, sounds)
- Plugins, OpenCode docs (plugin folders,
session.idle, the notification example) - Copilot CLI hooks reference, GitHub Docs (hook file locations,
agentStop,notificationtypes) - Copilot CLI command reference, GitHub Docs
- Ambient README, Supported agents
More guides: Codex notifications on Mac · Gemini CLI notifications on Mac · Claude Code notifications on Mac