Cc-skills dual-channel-watchexec

Dual-channel notifications on watchexec events. TRIGGERS - watchexec alerts, Telegram+Pushover, file change notifications.

install
source · Clone the upstream repo
git clone https://github.com/terrylica/cc-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/terrylica/cc-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/devops-tools/skills/dual-channel-watchexec" ~/.claude/skills/terrylica-cc-skills-dual-channel-watchexec && rm -rf "$T"
manifest: plugins/devops-tools/skills/dual-channel-watchexec/SKILL.md
source content

Dual-Channel Watchexec Notifications

Send reliable notifications to both Telegram and Pushover when watchexec detects file changes or process crashes.

Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

When to Use This Skill

Use this skill when:

  • Setting up file change monitoring with notifications
  • Implementing process crash alerting via Telegram and Pushover
  • Creating watchexec wrappers with dual-channel notification support
  • Formatting messages for both HTML (Telegram) and plain text (Pushover)
  • Troubleshooting notification delivery or formatting issues

Core Pattern

watchexec wrapper scriptdetect eventnotify-scriptTelegram + Pushover

# wrapper.sh - Monitors process and detects restart reasons
watchexec --restart -- python bot.py

# On event, call:
notify-script.sh <reason> <exit_code> <watchexec_info_file> <crash_context>

Critical Rule: Format Differences

Telegram: HTML mode ONLY

MESSAGE="<b>Alert</b>: <code>file.py</code>"
# Escape 3 chars: & → &amp;, < → &lt;, > → &gt;

Pushover: Plain text ONLY

/usr/bin/env bash << 'SKILL_SCRIPT_EOF'
# Strip HTML tags before sending
MESSAGE_PLAIN=$(echo "$MESSAGE_HTML" | sed 's/<[^>]*>//g')
SKILL_SCRIPT_EOF

Why HTML for Telegram:

  • Markdown requires escaping 40+ chars (
    .
    ,
    -
    ,
    _
    , etc.)
  • HTML only requires escaping 3 chars (
    &
    ,
    <
    ,
    >
    )
  • Industry best practice

Quick Reference

Send to Both Channels

/usr/bin/env bash << 'SKILL_SCRIPT_EOF_2'
# 1. Build HTML message for Telegram
MESSAGE_HTML="<b>File</b>: <code>handler_classes.py</code>"

# 2. Strip HTML for Pushover
MESSAGE_PLAIN=$(echo "$MESSAGE_HTML" | sed 's/<[^>]*>//g')

# 3. Send to Telegram with HTML
curl -s -d "chat_id=$CHAT_ID" \
  -d "text=$MESSAGE_HTML" \
  -d "parse_mode=HTML" \
  https://api.telegram.org/bot$BOT_TOKEN/sendMessage

# 4. Send to Pushover with plain text
curl -s --form-string "message=$MESSAGE_PLAIN" \
  https://api.pushover.net/1/messages.json
SKILL_SCRIPT_EOF_2

Execution Pattern

# Fire-and-forget background notifications (don't block restarts)
"$NOTIFY_SCRIPT" "crash" "$EXIT_CODE" "$INFO_FILE" "$CONTEXT_FILE" &

Validation Checklist

Before deploying:

  • Using HTML parse mode for Telegram (not Markdown)
  • HTML tags stripped for Pushover (plain text only)
  • HTML escaping applied to all dynamic content (
    &
    ,
    <
    ,
    >
    )
  • Credentials loaded from env vars/Doppler (not hardcoded)
  • Message archiving enabled for debugging
  • File detection uses
    stat
    (not
    find -newermt
    )
  • Heredocs use unquoted delimiters for variable expansion
  • Notifications run in background (fire-and-forget)
  • Tested with files containing special chars (
    _
    ,
    .
    ,
    -
    )
  • Both Telegram and Pushover successfully receiving

Summary

Key Lessons:

  1. Always use HTML mode for Telegram (simpler escaping)
  2. Always strip HTML tags for Pushover (plain text only)
  3. Escape only 3 chars in HTML:
    &
    &amp;
    ,
    <
    &lt;
    ,
    >
    &gt;
  4. Archive messages before sending for debugging
  5. Use
    stat
    for file detection on macOS (not
    find -newermt
    )
  6. Load credentials from env vars/Doppler (never hardcode)
  7. Fire-and-forget background notifications (don't block restarts)

Reference Documentation

For detailed information, see:

Bundled Examples:

  • examples/notify-restart.sh
    - Complete dual-channel notification script
  • examples/bot-wrapper.sh
    - watchexec wrapper with restart detection
  • examples/setup-example.sh
    - Setup guide and installation steps

Troubleshooting

IssueCauseSolution
Telegram escaping errorsUsing Markdown instead of HTMLSwitch to HTML mode with parse_mode=HTML
Pushover shows HTML tagsHTML not strippedStrip tags with sed before sending to Pushover
Notifications not arrivingCredentials missingVerify BOT_TOKEN, CHAT_ID, Pushover keys
Special chars brokenMissing HTML escapingEscape &, <, > in dynamic content
find -newermt fails macOSmacOS incompatibilityUse stat for file detection instead
Notifications blockingNot running in backgroundAdd & to run notify script fire-and-forget
Duplicate notificationsRestart loopAdd debounce logic or cooldown period
Missing crash contextContext file not writtenVerify watchexec info file path exists

Post-Execution Reflection

After this skill completes, check before closing:

  1. Did the command succeed? — If not, fix the instruction or error table that caused the failure.
  2. Did parameters or output change? — If the underlying tool's interface drifted, update Usage examples and Parameters table to match.
  3. Was a workaround needed? — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.

Only update if the issue is real and reproducible — not speculative.