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.
~/.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.floating level) — 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 |
```bash
xcode-select --install
```
All dependencies (swiftc, codesign) come from Xcode CLT. install.sh will check and exit early if CLT is missing.
When the user requests installation, follow these steps:
bash ~/.claude/skills/cc-sticky-notify/install.sh
What this script does:
xcode-select -p fails.chmod +x notify.sh — ensures the script is executable (git clone may strip the +x bit)..app bundle — compiles sticky-window.swift, writes Info.plist + entitlements, signs with codesign. Skipped if the bundle already exists.~/.claude/settings.json for existing cc-sticky-notify entries and prints the required hook commands if none are found.notify.sh.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'"
}
# 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.
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
30.5)86400) to keep the note visible for nearly a full dayTo persist the setting, add it to your shell config (~/.zshrc or ~/.bashrc):
echo 'export CC_STICKY_NOTIFY_CLOSE_TIMEOUT=300' >> ~/.zshrc
No system notification either
~/.claude/settings.json$HOME/.claude/skills/cc-sticky-notify/scripts/notify.shxcrun: error: invalid active developer path during compilation
sudo xcode-select --resetxcode-select --installPermission denied on notify.sh
chmod +x ~/.claude/skills/cc-sticky-notify/scripts/notify.shinstall.sh after fixing (the latest version auto-runs chmod +x on startup)共 1 个版本