/install cc-sticky-notify
cc-sticky-notify
A pinned sticky note notification system for Mac. Key Claude Code events appear as a yellow floating sticky note in the top-right corner, persisting until manually closed.
File Structure (fully self-contained)
~/.claude/skills/cc-sticky-notify/
├── SKILL.md
├── install.sh ← one-time setup: chmod + settings.json guidance
└── scripts/
├── notify.sh ← main notification script (called directly by hooks)
├── sticky-window.swift ← Swift source (compiled by install.sh on first install)
└── sticky-notify.app/ ← .app bundle (built automatically on first use)
└── Contents/
├── Info.plist
└── MacOS/
└── sticky-notify-app
Two-layer notification mechanism:
display notification— no permissions required, appears instantly in top-right corner- Swift NSWindow (
.floatinglevel) — pinned sticky note, close manually with ✕
Hook coverage (consistent with popo-notify):
| Hook | Trigger | Sticky note content |
|---|---|---|
Stop |
Task completed | ✅ Task completed + time/project/session |
Notification/permission_prompt |
Permission approval needed | 🔐 Permission approval required |
Notification/idle_prompt |
Waiting for user selection | 💬 Awaiting your input |
PostToolUse/Bash (on failure) |
Command execution failed | ❌ Command failed, exit code |
Requirements
-
macOS 12 Monterey or later
-
Xcode Command Line Tools — required for compiling the Swift floating window, code signing, and JSON parsing
xcode-select --installAll dependencies (
swiftc,codesign) come from Xcode CLT.install.shwill check and exit early if CLT is missing.
Installation
When the user requests installation, follow these steps:
Step 1 — Run install.sh
bash ~/.claude/skills/cc-sticky-notify/install.sh
What this script does:
- Check Xcode CLT — exits early with instructions if
xcode-select -pfails. chmod +x notify.sh— ensures the script is executable (git clone may strip the +x bit).- Build
.app bundle— compilessticky-window.swift, writesInfo.plist+ entitlements, signs withcodesign. Skipped if the bundle already exists. - Check hook configuration — inspects
~/.claude/settings.jsonfor existingcc-sticky-notifyentries and prints the required hook commands if none are found. - Smoke test — fires a test notification via
notify.sh.
Step 2 — Configure settings.json hooks
Read ~/.claude/settings.json and append one sticky-notify entry to each of the following four locations in the hooks field (skip if already present).
Stop — append to Stop[0].hooks:
{
"type": "command",
"command": "$HOME/.claude/skills/cc-sticky-notify/scripts/notify.sh"
}
Notification/permission_prompt — append:
{
"type": "command",
"command": "$HOME/.claude/skills/cc-sticky-notify/scripts/notify.sh '🔐 Claude Code Permission approval required, check terminal'"
}
Notification/idle_prompt — append:
{
"type": "command",
"command": "$HOME/.claude/skills/cc-sticky-notify/scripts/notify.sh '💬 Claude Code Awaiting your input, check terminal'"
}
PostToolUse/Bash — append (triggers only on failure):
{
"type": "command",
"command": "bash -c 'INPUT=$(cat); STATUS=$(echo \"$INPUT\" | jq -r \".tool_response.exitCode // 0\"); [ \"$STATUS\" != \"0\" ] && $HOME/.claude/skills/cc-sticky-notify/scripts/notify.sh \"❌ Claude Code Command failed, exit code: $STATUS\" || true'"
}
Step 3 — Verify
# Test arg mode (simulates Notification hook)
$HOME/.claude/skills/cc-sticky-notify/scripts/notify.sh '✅ Installation verified'
# Test stdin mode (simulates Stop hook)
echo '{"session_id":"test12345678"}' | $HOME/.claude/skills/cc-sticky-notify/scripts/notify.sh
A yellow sticky note and system notification appearing in the top-right corner confirms successful installation.
Configuration
CC_STICKY_NOTIFY_CLOSE_TIMEOUT — Auto-close timeout
Sticky notes automatically close after 1 hour (3600 seconds) by default. Override with this environment variable:
export CC_STICKY_NOTIFY_CLOSE_TIMEOUT=300 # auto-close after 5 minutes
- Unit: seconds (decimals supported, e.g.
30.5) - Must be greater than 0; otherwise falls back to the default 3600 seconds
- Set a large value (e.g.
86400) to keep the note visible for nearly a full day
To persist the setting, add it to your shell config (~/.zshrc or ~/.bashrc):
echo 'export CC_STICKY_NOTIFY_CLOSE_TIMEOUT=300' >> ~/.zshrc
Troubleshooting
No system notification either
- Verify the hooks configuration is correctly written in
~/.claude/settings.json - Path should be
$HOME/.claude/skills/cc-sticky-notify/scripts/notify.sh
xcrun: error: invalid active developer path during compilation
- Xcode Command Line Tools path is broken (common after macOS upgrade or Xcode reinstall)
- Fix:
sudo xcode-select --reset - If that doesn't work, reinstall:
xcode-select --install - The floating sticky window will be disabled if swiftc can't compile, but system notifications still work
Permission denied on notify.sh
- The script is missing execute permission — happens when files are cloned/copied without preserving permissions
- Fix:
chmod +x ~/.claude/skills/cc-sticky-notify/scripts/notify.sh - Re-run
install.shafter fixing (the latest version auto-runschmod +xon startup)
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install cc-sticky-notify - After installation, invoke the skill by name or use
/cc-sticky-notify - Provide required inputs per the skill's parameter spec and get structured output
What is cc-sticky-notify?
Install, configure, or fix cc-sticky-notify — a notification system that displays a pinned yellow sticky note in the Mac top-right corner for key Claude Code... It is an AI Agent Skill for Claude Code / OpenClaw, with 156 downloads so far.
How do I install cc-sticky-notify?
Run "/install cc-sticky-notify" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is cc-sticky-notify free?
Yes, cc-sticky-notify is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does cc-sticky-notify support?
cc-sticky-notify is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created cc-sticky-notify?
It is built and maintained by BucleLiu (@bucleliu); the current version is v1.0.2.