Purpose
Thin check-centric setup per the uniform setup contract (docs/PLUGIN-PHILOSOPHY.md
"Setup is explicit and repeatable" in the marketplace repository): check inspects and
reports, apply resolves. This plugin owns no consumer-project configuration. The only
tunables are the four native userConfig toggles (master + one per channel), and every
remaining prerequisite is a system tool or an OS package. So apply is pure
guidance-and-verify with no write path: it installs nothing and edits nothing.
Action routing: no argument or check runs the check; apply runs the check first, then
offers the resolution for each finding. Both are non-interactive. Never prompt when the
action is given.
check (read-only)
The hook script and the shared library it sources are the single source of truth for what this
plugin requires and how it degrades: ${CLAUDE_PLUGIN_ROOT}/hooks/desktop-notification.sh and
${CLAUDE_PLUGIN_ROOT}/hooks/hook-utils.sh.
Read it first. Probe what it actually does, don't recite this file. Then run each probe via
Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything.
When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to
INFO. The hook exits through its enabled-gate before probing anything, so a deliberately
disabled plugin is not broken. Report the probes informationally and note that re-enabling
restores the FAIL semantics.
- Bash version. Check
${BASH_VERSION} against the hook's documented floor (README
Requirements: Bash 3.2+). INFO when below 5.0: EPOCHREALTIME is unset there, so the
opt-in telemetry envelope is skipped while notifications still fire, a degrade, not a
failure.
jq. command -v jq. FAIL if absent: without it the hook can neither classify the
notification nor emit its terminal sequence, so it surfaces a once-per-session
systemMessage notice and drops every notification for the session.
- Per-OS
os_toast dependency. Detect the current OS family with uname -s and probe
ONLY that family's requirement (the hook's case "$(uname -s)" does exactly this):
- Linux.
command -v notify-send (libnotify). FAIL only if the os_toast channel is
enabled and it is absent; otherwise INFO. Absent → the os_toast channel is a
documented silent no-op; remediation is the README's install hint (libnotify-bin on
Debian/Ubuntu, libnotify on Fedora). The terminal channels are unaffected.
- macOS (Darwin). INFO:
osascript is built-in, no dependency. Note the first toast
prompts to allow notifications for the terminal app.
- Windows / other. INFO: the hook has no
os_toast branch on this platform (a
fire-and-forget process leaves no live activator host for a WinRT toast). The
terminal_notify OSC 9 channel carries attention here; nothing to install.
- Channel toggles. Report the effective value of all four native booleans (unexpanded
or empty means the default
true): master ${user_config.desktop_notification_enabled},
${user_config.desktop_notification_bell_enabled},
${user_config.desktop_notification_terminal_notify_enabled}, and
${user_config.desktop_notification_os_toast_enabled}. Call out when the master toggle is
off (the whole hook is muted) or when the only channel that would fire on this OS is
disabled.
- Hook registration. INFO: confirm the plugin is enabled for this project
(
/plugin → Installed) rather than parsing settings files.
apply (idempotent)
Run check, then for each FAIL or actionable INFO offer the resolution. This skill installs
nothing and writes nothing, so every remediation is a pointer the user acts on:
- missing
jq / old Bash. The platform install instructions from the README Requirements
section. This skill never installs system packages.
- missing
notify-send (Linux, os_toast enabled). sudo apt install libnotify-bin
(Debian/Ubuntu) or sudo dnf install libnotify (Fedora), per the README's per-OS table.
Guidance only. The user runs it.
- a toggle is off. Reconfigure through Claude Code's native flow, per the marketplace's
plugin-reconfiguration convention, which owns the verified-version record
(https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/plugin-reconfiguration/README.md):
interactive
/plugin configure desktop-notification@<marketplace> any time, or headless
claude plugin install desktop-notification@<marketplace> -s <scope> --config <key>=true
(repeatable per key) — against an already-installed plugin it prints already installed and
still writes the value. Do not uninstall to reconfigure: uninstalling drops this plugin's
entire stored pluginConfigs entry, resetting every option in the README's Options reference
to its manifest default. -s defaults to user; pass the install scope claude plugin list
reports for this plugin, and run from that project's directory for a project/local scope,
or the write lands at a scope that does not load. These options are personal userConfig
values, so this skill never writes user settings or pluginConfigs. Afterwards rerun check
in a fresh session — the rendered ${user_config.*} is injected at skill load and each
hook receives its CLAUDE_PLUGIN_OPTION_* from an environment fixed at session start, so a
same-session check still reports the OLD value; report the observed effective value, never an
unobserved change.
After the user reports acting on any system-tool remediation, re-run the relevant check
probe and report its actual result. Never claim resolved on the user's say-so alone.
Re-running apply when everything already passes changes nothing and reports "already
configured".
What this skill does NOT do
- Install
jq, libnotify, or any system package. apply is guidance-and-verify with no
write path.
- Fire a notification. A
permission_prompt or idle_prompt exercises the hook end-to-end.
- Write the plugin cache, Claude Code user settings, or
pluginConfigs. Nor the hook scripts.
1---2name: setup-533description: Verify the desktop-notification hook's runtime prerequisites and per-OS channel configuration for this machine. Use when: 'set up desktop-notification', 'configure desktop-notification', 'is desktop-notification working', notifications silently aren't firing, or the hook reported a missing prerequisite. Actions: check (read-only verification, default) | apply (resolve what check found). Re-runnable and safe.4---56## Purpose78Thin check-centric setup per the uniform setup contract (`docs/PLUGIN-PHILOSOPHY.md`9"Setup is explicit and repeatable" in the marketplace repository): `check` inspects and10reports, `apply` resolves. This plugin owns no consumer-project configuration. The only11tunables are the four native `userConfig` toggles (master + one per channel), and every12remaining prerequisite is a system tool or an OS package. So `apply` is pure13guidance-and-verify with **no write path**: it installs nothing and edits nothing.1415Action routing: no argument or `check` runs the check; `apply` runs the check first, then16offers the resolution for each finding. Both are non-interactive. Never prompt when the17action is given.1819## `check` (read-only)2021The hook script and the shared library it sources are the single source of truth for what this22plugin requires and how it degrades: `${CLAUDE_PLUGIN_ROOT}/hooks/desktop-notification.sh` and23`${CLAUDE_PLUGIN_ROOT}/hooks/hook-utils.sh`.2425**Read it first.** Probe what it actually does, don't recite this file. Then run each probe via26Bash and report a PASS/FAIL/INFO table with one remediation line per FAIL. Do not modify anything.2728When the plugin's toggle is disabled, every prerequisite absence downgrades from FAIL to29INFO. The hook exits through its enabled-gate before probing anything, so a deliberately30disabled plugin is not broken. Report the probes informationally and note that re-enabling31restores the FAIL semantics.32331. **Bash version**. Check `${BASH_VERSION}` against the hook's documented floor (README34 Requirements: Bash 3.2+). INFO when below 5.0: `EPOCHREALTIME` is unset there, so the35 opt-in telemetry envelope is skipped while notifications still fire, a degrade, not a36 failure.372. **`jq`**. `command -v jq`. FAIL if absent: without it the hook can neither classify the38 notification nor emit its terminal sequence, so it surfaces a once-per-session39 `systemMessage` notice and drops every notification for the session.403. **Per-OS `os_toast` dependency**. Detect the current OS family with `uname -s` and probe41 ONLY that family's requirement (the hook's `case "$(uname -s)"` does exactly this):42 - **Linux**. `command -v notify-send` (libnotify). FAIL only if the `os_toast` channel is43 enabled and it is absent; otherwise INFO. Absent → the `os_toast` channel is a44 documented silent no-op; remediation is the README's install hint (`libnotify-bin` on45 Debian/Ubuntu, `libnotify` on Fedora). The terminal channels are unaffected.46 - **macOS (Darwin)**. INFO: `osascript` is built-in, no dependency. Note the first toast47 prompts to allow notifications for the terminal app.48 - **Windows / other**. INFO: the hook has no `os_toast` branch on this platform (a49 fire-and-forget process leaves no live activator host for a WinRT toast). The50 `terminal_notify` OSC 9 channel carries attention here; nothing to install.514. **Channel toggles**. Report the effective value of all four native booleans (unexpanded52 or empty means the default `true`): master `${user_config.desktop_notification_enabled}`,53 `${user_config.desktop_notification_bell_enabled}`,54 `${user_config.desktop_notification_terminal_notify_enabled}`, and55 `${user_config.desktop_notification_os_toast_enabled}`. Call out when the master toggle is56 off (the whole hook is muted) or when the only channel that would fire on this OS is57 disabled.585. **Hook registration**. INFO: confirm the plugin is enabled for this project59 (`/plugin` → Installed) rather than parsing settings files.6061## `apply` (idempotent)6263Run `check`, then for each FAIL or actionable INFO offer the resolution. This skill installs64nothing and writes nothing, so every remediation is a pointer the user acts on:6566- **missing `jq` / old Bash**. The platform install instructions from the README Requirements67 section. This skill never installs system packages.68- **missing `notify-send`** (Linux, `os_toast` enabled). `sudo apt install libnotify-bin`69 (Debian/Ubuntu) or `sudo dnf install libnotify` (Fedora), per the README's per-OS table.70 Guidance only. The user runs it.71- **a toggle is off**. Reconfigure through Claude Code's native flow, per the marketplace's72 plugin-reconfiguration convention, which owns the verified-version record73 (<https://github.com/melodic-software/claude-code-plugins/blob/main/docs/conventions/plugin-reconfiguration/README.md>):74 interactive `/plugin configure desktop-notification@<marketplace>` any time, or headless75 `claude plugin install desktop-notification@<marketplace> -s <scope> --config <key>=true`76 (repeatable per key) — against an already-installed plugin it prints `already installed` **and77 still writes the value**. Do **not** uninstall to reconfigure: uninstalling drops this plugin's78 entire stored `pluginConfigs` entry, resetting every option in the README's Options reference79 to its manifest default. `-s` defaults to `user`; pass the install scope `claude plugin list`80 reports for this plugin, and run from that project's directory for a `project`/`local` scope,81 or the write lands at a scope that does not load. These options are personal `userConfig`82 values, so this skill never writes user settings or `pluginConfigs`. Afterwards rerun `check`83 in a **fresh session** — the rendered `${user_config.*}` is injected at skill load and each84 hook receives its `CLAUDE_PLUGIN_OPTION_*` from an environment fixed at session start, so a85 same-session `check` still reports the OLD value; report the observed effective value, never an86 unobserved change.8788After the user reports acting on any system-tool remediation, re-run the relevant `check`89probe and report its actual result. Never claim resolved on the user's say-so alone.90Re-running `apply` when everything already passes changes nothing and reports "already91configured".9293## What this skill does NOT do9495- Install `jq`, `libnotify`, or any system package. `apply` is guidance-and-verify with no96 write path.97- Fire a notification. A `permission_prompt` or `idle_prompt` exercises the hook end-to-end.98- Write the plugin cache, Claude Code user settings, or `pluginConfigs`. Nor the hook scripts.