From 109444e46a8ccebaddb5cf18bd749e4ced58e654 Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sun, 30 Nov 2025 09:08:27 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 15 +++ README.md | 3 + commands/webhook-config-wrapper.sh | 34 +++++++ commands/webhook-config.md | 153 +++++++++++++++++++++++++++++ commands/webhook-logs-wrapper.sh | 34 +++++++ commands/webhook-logs.md | 126 ++++++++++++++++++++++++ commands/webhook-test-wrapper.sh | 34 +++++++ commands/webhook-test.md | 118 ++++++++++++++++++++++ hooks/hooks.json | 38 +++++++ hooks/webhook-notify.sh | 50 ++++++++++ plugin.lock.json | 73 ++++++++++++++ 11 files changed, 678 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100755 commands/webhook-config-wrapper.sh create mode 100644 commands/webhook-config.md create mode 100755 commands/webhook-logs-wrapper.sh create mode 100644 commands/webhook-logs.md create mode 100755 commands/webhook-test-wrapper.sh create mode 100644 commands/webhook-test.md create mode 100644 hooks/hooks.json create mode 100755 hooks/webhook-notify.sh create mode 100644 plugin.lock.json diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..32bca94 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "webhook-notifier", + "description": "现代化通知系统 - TypeScript 5.3+ 开发,支持 Webhook(飞书/Slack/Discord) + macOS 原生通知,预构建分发无需编译,提供强大 CLI 工具集", + "version": "2.0.0", + "author": { + "name": "Zephyr", + "email": "zephyrTang@aliyun.com" + }, + "commands": [ + "./commands" + ], + "hooks": [ + "./hooks" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fb4e245 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# webhook-notifier + +现代化通知系统 - TypeScript 5.3+ 开发,支持 Webhook(飞书/Slack/Discord) + macOS 原生通知,预构建分发无需编译,提供强大 CLI 工具集 diff --git a/commands/webhook-config-wrapper.sh b/commands/webhook-config-wrapper.sh new file mode 100755 index 0000000..b1929b1 --- /dev/null +++ b/commands/webhook-config-wrapper.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Webhook Config Wrapper - 智能依赖检查和配置管理 + +# 确定插件目录 +if [ -n "$CLAUDE_PLUGIN_ROOT" ]; then + PLUGIN_DIR="$CLAUDE_PLUGIN_ROOT" +else + # 如果环境变量未设置,使用脚本所在目录的父目录 + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + PLUGIN_DIR="$(dirname "$SCRIPT_DIR")" +fi + +NODE_MODULES="$PLUGIN_DIR/node_modules" + +# 检查 node_modules 是否存在 +if [ ! -d "$NODE_MODULES" ] || [ ! -d "$NODE_MODULES/node-notifier" ]; then + echo "⚠️ 缺少必需的依赖" + echo "" + echo "此插件需要安装 node-notifier 依赖才能发送 macOS 通知。" + echo "" + echo "📦 需要安装的依赖:" + echo " - node-notifier (macOS 系统通知支持)" + echo "" + echo "💡 请让 Claude 执行以下命令安装依赖:" + echo "" + echo " cd \"$PLUGIN_DIR\"" + echo " npm install" + echo "" + echo "安装完成后,即可使用 /webhook-config 配置通知系统。" + exit 1 +fi + +# 依赖已安装,执行配置命令 +exec node "$PLUGIN_DIR/scripts/bin/index.js" config "$@" diff --git a/commands/webhook-config.md b/commands/webhook-config.md new file mode 100644 index 0000000..46f9e84 --- /dev/null +++ b/commands/webhook-config.md @@ -0,0 +1,153 @@ +# /webhook-config - 配置 Webhook 通知 + +配置和管理 webhook-notifier 插件,支持 macOS 原生通知和 Webhook 通知。 + +## 🚀 首次使用 + +**重要**:此插件首次使用需要安装依赖(仅需一次) + +如果看到依赖缺失提示,请执行: +```bash +cd ${CLAUDE_PLUGIN_ROOT} +npm install +``` + +安装完成后即可使用所有功能。 + +## 功能说明 + +此命令支持配置通知系统的所有选项: +- 查看和验证当前配置 +- 初始化默认配置文件 +- 管理 Webhook 和 macOS 通知设置 + +配置文件:`${CLAUDE_PLUGIN_ROOT}/.webhookrc.yaml`(YAML 格式) +日志目录:`~/.claude/webhook-notifier/logs` + +## 命令选项 + +### 配置管理 +- `--show` - 显示当前配置(包括配置文件路径和所有设置) +- `--init` - 初始化默认配置文件(创建 .webhookrc.yaml) +- `--validate` - 验证配置文件有效性 + +## 配置文件说明 + +插件使用 YAML 格式配置文件,支持以下位置: +1. `${CLAUDE_PLUGIN_ROOT}/.webhookrc.yaml`(推荐) +2. `~/webhookrc.yaml` +3. `~/.claude/webhook-notifier/config.yaml` + +## 使用示例 + +### 查看当前配置 +```bash +/webhook-config --show +``` + +### 初始化配置文件 +```bash +/webhook-config --init +``` + +### 验证配置有效性 +```bash +/webhook-config --validate +``` + +### 手动编辑配置 +配置文件位于 `${CLAUDE_PLUGIN_ROOT}/.webhookrc.yaml`,可以直接编辑: + +```yaml +# 日志配置 +logging: + level: info # debug | info | warn | error + directory: ~/.claude/webhook-notifier/logs + format: json # json | text + rotation: daily # daily | size + +# 事件配置 +events: + notification: + enabled: true # 启用 Notification 事件(Claude 等待输入时) + extract_context: true # 提取对话上下文 + context_length: 200 # 上下文最大长度 + session_end: + enabled: true # 启用 Session End 事件(会话结束时) + +# 通知器配置 +notifiers: + # Webhook 通知器 + webhook: + enabled: false # 是否启用 Webhook + url: https://your-webhook.com/notify # Webhook URL(启用时必需) + timeout: 10 # 超时时间(秒) + + # macOS 原生通知 + macos: + enabled: true # 启用 macOS 通知 + title: Claude Code # 通知标题 + sound: default # 通知声音:default | Ping | Glass | Hero + actions: # 点击通知时的操作 + - label: Open Terminal + command: open -a Terminal + templates: # 通知模板 + notification: + title: "{{title}}" + subtitle: "等待输入" + message: "{{last_message}}" + session_end: + title: "{{title}}" + subtitle: "会话结束" + message: "原因: {{reason}}" +``` + +## 配置验证规则 + +- **Webhook URL**: 启用 webhook 时必须提供有效的 URL +- **日志级别**: 必须是 `debug`、`info`、`warn` 或 `error` 之一 +- **macOS 通知**: 仅在 macOS 平台可用 + +## 相关命令 + +- `/webhook-test` - 发送测试通知验证配置 +- `/webhook-logs` - 查看通知发送历史 + +## 故障排除 + +### 依赖缺失错误 +如果看到 "缺少必需的依赖" 提示: + +```bash +cd ${CLAUDE_PLUGIN_ROOT} +npm install +``` + +安装完成后重新运行命令。 + +### 配置文件不存在 +运行 `/webhook-config --init` 创建默认配置文件。 + +### 配置验证失败 +使用 `/webhook-config --validate` 查看详细的验证错误信息。 + +### Webhook URL 错误 +- 启用 webhook 时必须提供有效的 URL +- URL 必须以 `http://` 或 `https://` 开头 +- 如果不使用 webhook,设置 `enabled: false` 即可 + +### macOS 通知不显示 +- 确保在 macOS 系统上运行 +- 检查系统通知权限(系统设置 → 通知) +- 运行 `/webhook-test --notifier macos` 测试 + +### 查看详细日志 +使用 `/webhook-logs` 查看通知发送历史和错误日志。 + +--- + +**执行方式:** + +```bash +bash ${CLAUDE_PLUGIN_ROOT}/commands/webhook-config-wrapper.sh "$@" +``` diff --git a/commands/webhook-logs-wrapper.sh b/commands/webhook-logs-wrapper.sh new file mode 100755 index 0000000..cf45646 --- /dev/null +++ b/commands/webhook-logs-wrapper.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Webhook Logs Wrapper - 智能依赖检查和日志查看 + +# 确定插件目录 +if [ -n "$CLAUDE_PLUGIN_ROOT" ]; then + PLUGIN_DIR="$CLAUDE_PLUGIN_ROOT" +else + # 如果环境变量未设置,使用脚本所在目录的父目录 + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + PLUGIN_DIR="$(dirname "$SCRIPT_DIR")" +fi + +NODE_MODULES="$PLUGIN_DIR/node_modules" + +# 检查 node_modules 是否存在 +if [ ! -d "$NODE_MODULES" ] || [ ! -d "$NODE_MODULES/node-notifier" ]; then + echo "⚠️ 缺少必需的依赖" + echo "" + echo "此插件需要安装 node-notifier 依赖才能正常运行。" + echo "" + echo "📦 需要安装的依赖:" + echo " - node-notifier (macOS 系统通知支持)" + echo "" + echo "💡 请让 Claude 执行以下命令安装依赖:" + echo "" + echo " cd \"$PLUGIN_DIR\"" + echo " npm install" + echo "" + echo "安装完成后,即可使用 /webhook-logs 查看通知日志。" + exit 1 +fi + +# 依赖已安装,执行日志命令 +exec node "$PLUGIN_DIR/scripts/bin/index.js" logs "$@" diff --git a/commands/webhook-logs.md b/commands/webhook-logs.md new file mode 100644 index 0000000..7802108 --- /dev/null +++ b/commands/webhook-logs.md @@ -0,0 +1,126 @@ +# /webhook-logs - 查看通知日志 + +查看通知系统的发送历史和错误日志。 + +## 🚀 首次使用 + +**重要**:此命令首次使用需要安装依赖(仅需一次) + +如果看到依赖缺失提示,请执行: +```bash +cd ${CLAUDE_PLUGIN_ROOT} +npm install +``` + +安装完成后即可查看日志。 + +## 功能说明 + +此命令显示通知系统的日志信息,帮助您: +- 查看 macOS 和 Webhook 通知发送历史 +- 排查发送失败问题 +- 监控通知状态和性能 + +## 命令选项 + +- 无参数 - 显示最近 20 条日志 +- `--lines N` - 显示最近 N 条日志 +- `--level LEVEL` - 过滤特定级别(debug/info/warn/error) +- `--follow` - 实时跟踪日志(开发中) + +## 使用示例 + +### 查看最近日志 +```bash +/webhook-logs +``` + +### 查看最近 50 条 +```bash +/webhook-logs --lines 50 +``` + +### 仅查看错误 +```bash +/webhook-logs --level error +``` + +## 日志文件位置 + +日志文件存储在 `~/.claude/webhook-notifier/logs/` 目录: + +``` +~/.claude/webhook-notifier/logs/ +├── 2025-10-31.log # 按日期记录(JSON 格式) +├── errors.log # 错误专用日志 +``` + +## 日志格式 + +日志采用 JSON 格式,便于程序解析: + +### 标准日志示例 +```json +{ + "timestamp": "2025-10-31T08:00:00.000Z", + "level": "info", + "message": "Processing Notification event" +} +{ + "timestamp": "2025-10-31T08:00:01.000Z", + "level": "info", + "message": "Sending notifications via 1 notifiers" +} +{ + "timestamp": "2025-10-31T08:00:05.000Z", + "level": "info", + "message": "macOS notification sent successfully" +} +``` + +### 错误日志示例 +```json +{ + "timestamp": "2025-10-31T08:05:00.000Z", + "level": "error", + "message": "macOS notification failed", + "meta": { + "error": "Message property is required" + } +} +``` + +## 故障排除 + +### 依赖缺失 +如果看到 "缺少必需的依赖" 提示: +```bash +cd ${CLAUDE_PLUGIN_ROOT} +npm install +``` + +### 日志目录不存在 +日志目录会自动创建,如果遇到权限问题: +```bash +mkdir -p ~/.claude/webhook-notifier/logs +chmod 755 ~/.claude/webhook-notifier/logs +``` + +### 日志太大 +日志按天轮转,旧日志可以手动删除: +```bash +rm ~/.claude/webhook-notifier/logs/2025-10-*.log +``` + +## 相关命令 + +- `/webhook-test` - 生成测试日志 +- `/webhook-config` - 配置日志级别和目录 + +--- + +**执行方式:** + +```bash +bash ${CLAUDE_PLUGIN_ROOT}/commands/webhook-logs-wrapper.sh "$@" +``` diff --git a/commands/webhook-test-wrapper.sh b/commands/webhook-test-wrapper.sh new file mode 100755 index 0000000..86f8d3a --- /dev/null +++ b/commands/webhook-test-wrapper.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Webhook Test Wrapper - 智能依赖检查和测试执行 + +# 确定插件目录 +if [ -n "$CLAUDE_PLUGIN_ROOT" ]; then + PLUGIN_DIR="$CLAUDE_PLUGIN_ROOT" +else + # 如果环境变量未设置,使用脚本所在目录的父目录 + SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + PLUGIN_DIR="$(dirname "$SCRIPT_DIR")" +fi + +NODE_MODULES="$PLUGIN_DIR/node_modules" + +# 检查 node_modules 是否存在 +if [ ! -d "$NODE_MODULES" ] || [ ! -d "$NODE_MODULES/node-notifier" ]; then + echo "⚠️ 缺少必需的依赖" + echo "" + echo "此插件需要安装 node-notifier 依赖才能发送 macOS 通知。" + echo "" + echo "📦 需要安装的依赖:" + echo " - node-notifier (macOS 系统通知支持)" + echo "" + echo "💡 请让 Claude 执行以下命令安装依赖:" + echo "" + echo " cd \"$PLUGIN_DIR\"" + echo " npm install" + echo "" + echo "安装完成后,即可使用 /webhook-test 测试通知功能。" + exit 1 +fi + +# 依赖已安装,执行测试命令 +exec node "$PLUGIN_DIR/scripts/bin/index.js" test "$@" diff --git a/commands/webhook-test.md b/commands/webhook-test.md new file mode 100644 index 0000000..cdd2efa --- /dev/null +++ b/commands/webhook-test.md @@ -0,0 +1,118 @@ +# /webhook-test - 测试通知功能 + +发送测试通知,验证 Webhook 和 macOS 通知配置是否正确。 + +## 🚀 首次使用 + +**重要**:此命令首次使用需要安装依赖(仅需一次) + +如果看到依赖缺失提示,请执行: +```bash +cd ${CLAUDE_PLUGIN_ROOT} +npm install +``` + +安装完成后即可使用测试功能。 + +## 功能说明 + +此命令支持测试所有已启用的通知器: +- **macOS 通知** - 发送系统通知到通知中心 +- **Webhook 通知** - 发送 HTTP POST 请求到配置的 URL +- **全部测试** - 测试所有启用的通知器 + +## 命令选项 + +- 无参数 - 测试所有启用的通知器 +- `--notifier macos` - 仅测试 macOS 通知 +- `--notifier webhook` - 仅测试 Webhook 通知 +- `--notifier all` - 测试所有通知器(默认) + +## 使用示例 + +### 测试所有通知器 +```bash +/webhook-test +``` + +### 仅测试 macOS 通知 +```bash +/webhook-test --notifier macos +``` + +### 仅测试 Webhook +```bash +/webhook-test --notifier webhook +``` + +## 测试内容 + +### macOS 通知测试 +发送系统通知到 macOS 通知中心,包含: +- 标题:配置的通知标题 +- 副标题:"等待输入" +- 消息:测试消息内容 +- 声音:配置的通知声音 + +### Webhook 通知测试 +发送 HTTP POST 请求到配置的 Webhook URL,包含: +```json +{ + "event": "notification", + "notification_type": "waiting_for_input", + "message": "This is a test notification", + "timestamp": "2025-10-31T08:00:00.000Z", + "session": { + "id": "test-cli-1234567890" + }, + "project": { + "directory": "/current/working/directory", + "git_branch": "main", + "git_commit": "abc123..." + } +} +``` + +## 检查结果 + +执行命令后,检查以下内容: + +1. **终端输出** - 查看是否显示 "✅ Test completed successfully!" +2. **macOS 通知中心** - 应该看到测试通知弹窗(如果启用) +3. **日志文件** - `~/.claude/webhook-notifier/logs/` + ```bash + /webhook-logs --lines 10 + ``` +4. **Webhook 端点** - 检查服务端是否收到测试请求 + +## 故障排除 + +### 依赖缺失 +如果看到 "缺少必需的依赖" 提示: +```bash +cd ${CLAUDE_PLUGIN_ROOT} +npm install +``` + +### macOS 通知未显示 +- 检查配置:`/webhook-config --show` +- 验证 macos.enabled 是否为 true +- 检查系统通知权限 + +### Webhook 测试失败 +- 验证 URL 配置正确 +- 检查网络连接 +- 查看详细日志:`/webhook-logs --level error` + +## 相关命令 + +- `/webhook-config` - 配置通知系统 +- `/webhook-logs` - 查看通知历史和错误日志 + +--- + +**执行方式:** + +```bash +bash ${CLAUDE_PLUGIN_ROOT}/commands/webhook-test-wrapper.sh "$@" +``` diff --git a/hooks/hooks.json b/hooks/hooks.json new file mode 100644 index 0000000..7197668 --- /dev/null +++ b/hooks/hooks.json @@ -0,0 +1,38 @@ +{ + "description": "在 Claude Code 会话事件发生时自动发送通知(支持 Webhook 和 macOS 通知)", + "hooks": { + "Notification": [ + { + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/hooks/webhook-notify.sh", + "timeout": 30 + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/hooks/webhook-notify.sh", + "timeout": 30 + } + ] + } + ], + "SessionEnd": [ + { + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/hooks/webhook-notify.sh", + "timeout": 30 + } + ] + } + ] + } +} diff --git a/hooks/webhook-notify.sh b/hooks/webhook-notify.sh new file mode 100755 index 0000000..c22b5a7 --- /dev/null +++ b/hooks/webhook-notify.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +set -euo pipefail + +# ============================================================================ +# Webhook Notifier Hook Wrapper +# ============================================================================ +# 这是一个简单的 wrapper 脚本,用于调用 TypeScript 编译后的主程序 +# +# Hook Events: Notification, Stop, SessionEnd +# Input: JSON from stdin containing event info +# Output: JSON to stdout for Claude Code +# ============================================================================ + +# 常量定义 +readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$SCRIPT_DIR/..}" +readonly MAIN_SCRIPT="${PLUGIN_ROOT}/dist/index.js" +readonly LOG_DIR="${HOME}/.claude/webhook-notifier/logs" + +# 确保日志目录存在 +mkdir -p "${LOG_DIR}" + +# 日志函数(用于 wrapper 自己的错误) +log_error() { + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') + echo "[${timestamp}] WRAPPER ERROR: $*" >> "${LOG_DIR}/wrapper-errors.log" 2>&1 +} + +# 验证 Node.js +if ! command -v node &> /dev/null; then + log_error "Node.js is not installed or not in PATH" + echo '{"continue": true, "systemMessage": "Webhook notifier error: Node.js not found"}' 2>/dev/null + exit 1 +fi + +# 验证主程序存在 +if [[ ! -f "${MAIN_SCRIPT}" ]]; then + log_error "Main script not found at: ${MAIN_SCRIPT}" + log_error "Please run: cd ${PLUGIN_ROOT} && npm run build" + echo '{"continue": true, "systemMessage": "Webhook notifier error: Not built yet"}' 2>/dev/null + exit 1 +fi + +# 调用主程序(从 stdin 读取,输出到 stdout) +# 主程序会处理所有逻辑:配置读取、日志记录、通知发送等 +node "${MAIN_SCRIPT}" 2>> "${LOG_DIR}/wrapper-errors.log" + +# 返回主程序的退出码 +exit $? diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..f1f7ad4 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,73 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:ZephyrDeng/cc-plugins:plugins/webhook-notifier", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "0a8b604e4cea50bd60828634387dec35093f3235", + "treeHash": "b2e88421e33b71491692842a095e765b23b6e590ba627cc0ac7a16971ea00279", + "generatedAt": "2025-11-28T10:12:59.818135Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "webhook-notifier", + "description": "现代化通知系统 - TypeScript 5.3+ 开发,支持 Webhook(飞书/Slack/Discord) + macOS 原生通知,预构建分发无需编译,提供强大 CLI 工具集", + "version": "2.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "677c6c0b9df462b127914187a8c26d97c7df4405546b29159e7abe577d0776a5" + }, + { + "path": "hooks/webhook-notify.sh", + "sha256": "cff5448a2f726d9eb5e89bbd8c3c726026876a60d2bfced2979b46b3e528ee25" + }, + { + "path": "hooks/hooks.json", + "sha256": "732e43b544f534124f72400cab46b743dcab064be056fc36e649504221dc8ca2" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "5da1412546118823099125689e5a2599f511cf02f536c221d032c4704ca6b384" + }, + { + "path": "commands/webhook-logs-wrapper.sh", + "sha256": "b8cf69d61a7ed438bea3d7721c6c3d47888afe1680773d217f8c0452b4028839" + }, + { + "path": "commands/webhook-test.md", + "sha256": "ea657830fc9f5c0bc3d208be811543a436ed8118718c3fe094da36ed52eaac5c" + }, + { + "path": "commands/webhook-config.md", + "sha256": "6755225087938fd9a37eef762101f7a05d597cb687549f39c7a7e1699f351f6e" + }, + { + "path": "commands/webhook-config-wrapper.sh", + "sha256": "8bd62a56f56d2565fd96e84b2a7dc0b89aa7902f8a1b510db85372d7864e8233" + }, + { + "path": "commands/webhook-test-wrapper.sh", + "sha256": "8e08129f3394920209e456a6d0fe35f3a5f6203a953fece333d2cba03c8f4ba0" + }, + { + "path": "commands/webhook-logs.md", + "sha256": "a977c482ba3d0bbc512d0700a27f381d98b2068b0b5380b5956bd5d1295138b1" + } + ], + "dirSha256": "b2e88421e33b71491692842a095e765b23b6e590ba627cc0ac7a16971ea00279" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file