| name | say |
| description | Give an audible nudge via the macOS `say` command when a task finishes and needs review, or is blocked and needs human input. A standing general preference — invoke any time work reaches a stopping point a human should know about, not just from PR-maintenance flows. |
| metadata | {"copyright":"Copyright Cloud Posse, LLC 2026","version":"1.0.0"} |
Audible Task Notifications
A written summary is easy to miss when it lands in a background session hours after the user
stopped watching. This skill gives that moment an audible signal too.
When to use it
Two triggers, general-purpose — not tied to any one feature:
- A task or cycle finished in a way that needs human review (e.g. a fix was applied but the
result deserves a second look).
- Execution is blocked and needs human input to proceed (e.g. a merge conflict, an ambiguous
finding, a failure the caller correctly declined to touch).
Any skill or agent reaching one of these states should invoke this — it is not specific to
fix-all or any other single caller.
Phrasing rule
Keep it under ~15 words. Be specific, not a summary dump — include identifying context (a PR
number, branch, or file) so the listener knows what without reading anything.
- Good:
"PR 2718 has a merge conflict, needs your attention."
- Bad: a multi-sentence recap of the whole cycle.
Invocation
say is macOS-only. Wrap it defensively so a caller on another platform (or a machine without
say) never fails because of this notification. Build the message in a shell variable first, then
pass it via quoted expansion — never substitute untrusted text (a PR title, branch name, file
path) directly into the command source, since a stray " could terminate the quote and inject
additional shell content:
message="PR ${pr_number} needs your attention."
command -v say >/dev/null 2>&1 && say "$message" || true
No DATA-vs-instructions treatment is needed here: say only produces local audio output, no
state mutation, so it's exempt from the untrusted-content framing applied to things like
CodeRabbit comment bodies elsewhere in this repo's automation.
Requires .claude/settings.json → "Bash(say:*)" in allow — this skill owns that dependency;
callers don't need their own entry for it.
Related
fix-all skill — example caller, invokes this on every
human-attention exit path in its check/fix cycle (scheduled hourly by
pr-maintenance-loop, or run directly for a one-shot).
test-coverage skill — example caller, invokes this when a
test-fix attempt caps out still red or a coverage gap is genuinely untestable.
lint skill — example caller, invokes this when a finding needs a
broader refactor than patch scope allows.