npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

claude-agent-hook-relay

v0.1.22

Published

Claude Code Hook Relay - collects and forwards Claude Code Hook events

Readme

claude-agent-hook-relay

收集并转发 Claude Code Hook 事件,将事件统一汇聚到外部系统。

CLI 命令

安装后可用两个命令,功能完全相同:

| 命令 | 说明 | |------|------| | claude-agent-hook-relay | 全名 | | cahr | 缩写 |

示例:cahr startclaude-agent-hook-relay start 效果一样。


这是什么

claude-agent-hook-relay 是一个轻量的 HTTP 服务,充当 Hook 事件汇聚层。它的核心价值:

| 价值 | 说明 | |------|------| | 多终端 Hook 汇聚 | 多个 Claude Code 实例的 Hook 事件统一收集,无需在每个终端单独配置 | | Skill 调用链追踪 | 追踪哪个 Skill 调用了哪些工具,包括嵌套深度 —— 这是原生 OTel 做不到 的 |

为什么用 cahr 而不是 SDK 或 Hook 脚本?

| 方案 | 问题 | |------|------| | SDK 硬编码 | 耦合紧,升级困难 | | 分散的 Hook 脚本 | 难以管理,分散在各处 | | cahr | 集中管理,灵活可扩展 |

cahr 不是

  • 不是日志系统 —— 它只做收集和转发,存储由外部处理
  • 不是决策引擎 —— A/B 测试和业务逻辑属于 Skill 平台
  • 不依赖 SDK —— 配合任意 Claude Code Hook 配置使用

功能

  • 🔌 接收全部 26 个 Claude Code Hook 事件
  • 📁 读取 Transcript 文件计算详细用量
  • 🏷️ 通过 X-Source-ID 支持多终端
  • 🔄 可扩展的 Forwarder 架构(Console、HTTP 等)
  • 🚫 无需修改 Claude Code 或 SDK

安装

方式一:通过 npm 安装(适合最终用户)

npm install -g claude-agent-hook-relay

安装后,postinstall 脚本会自动在 ~/.claude/settings.json 中配置好 Hook 指向 http://localhost:8080

方式二:从源码安装(适合开发者)

git clone <仓库地址>
cd claude-agent-hook-relay
npm install
npm run build

安装后验证

安装完成后,按以下步骤验证 cahr 是否正常工作:

第一步:启动 cahr

cahr start
# 或
claude-agent-hook-relay start

默认监听端口 8080。如需更换端口:

cahr start 9000

第二步(可选):安装测试 Skill

如果你想验证 Skill 嵌套追踪功能,可以安装一个测试 Skill:

cahr install-test-skill

这会把两个测试 Skill(nested-test-skillweather-checker)安装到 ~/.claude/skills/

其他测试 Skill(level-3-skillsequential-skill)需要手动创建,参见 TEST-RESULTS.md

第三步:用 Claude Code 触发工具调用

在另一个终端运行:

# 基础验证:触发 Bash 工具
claude -p "列出 /tmp 目录下的所有文件"

# Skill 追踪验证(如果安装了测试 Skill):
claude -p "run nested-test-skill"

第四步:查看 cahr 输出

回到 cahr 终端,应该能看到类似这样的输出:

[Relay]
────────────────────────────────────────────────────────────
📋 weather-checker
└── 🔧 Bash: echo 'Weather check: ' && date
────────────────────────────────────────────────────────────
⏱️  耗时: 7966ms
📊 Token: (未获取到)

嵌套 Skill 示例

[Relay]
────────────────────────────────────────────────────────────
📋 nested-test-skill
├── 🤖 Skill: weather-checker
│   └── 🔧 Bash: echo 'Weather check: ' && date
├── 🔧 Bash: date
└── 🔧 Read: /home/aqiu/.claude/skills/nested-test-skill/example.txt
────────────────────────────────────────────────────────────
⏱️  耗时: 17473ms
📊 Token: (未获取到)

输出说明:

  • 📋 开头的是入口 Skill 名称
  • 🤖 表示 Skill 节点(嵌套的子 Skill)
  • 🔧 表示 Tool 节点(调用的工具)
  • Tool 节点会显示工具特定信息:commandfileurl

第五步:停止 cahr

在 cahr 终端按 Ctrl+C


其他常用命令

cahr --version                  # 查看版本,确认安装成功
cahr status                     # 查看 Hook 安装状态
cahr start [端口]               # 启动 cahr
cahr install-test-skill         # 安装测试 Skill(用于验证嵌套 Skill 追踪)
cahr uninstall                  # 移除 Claude Code 中的 Hook 配置

开发者文档

本地开发环境搭建

git clone <仓库地址>
cd claude-agent-hook-relay
npm install
npm run build

手动配置 Claude Code Hook

如果你需要手动配置 Hook(在源码开发模式下),在 ~/.claude/settings.json 中添加:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "http",
        "url": "http://localhost:8080/hook/pre-tool-use",
        "headers": { "X-Source-ID": "my-workstation" }
      }]
    }],
    "PostToolUse": [{
      "matcher": "*",
      "hooks": [{
        "type": "http",
        "url": "http://localhost:8080/hook/post-tool-use",
        "headers": { "X-Source-ID": "my-workstation" }
      }]
    }],
    "Stop": [{
      "matcher": "*",
      "hooks": [{
        "type": "http",
        "url": "http://localhost:8080/hook/stop",
        "headers": { "X-Source-ID": "my-workstation" }
      }]
    }],
    "SessionEnd": [{
      "matcher": "*",
      "hooks": [{
        "type": "http",
        "url": "http://localhost:8080/hook/session-end",
        "headers": { "X-Source-ID": "my-workstation" }
      }]
    }]
  }
}

运行测试

npm run test                  # 启动 cahr → 运行测试 → 停止 cahr
npm run test:port 8080       # 连接已有 cahr(指定端口)运行测试

测试会发送 4 种 Hook 事件序列(无 Skill、单 Skill、嵌套 Skill、SessionEnd),验证 cahr 的 Skill 追踪和聚合逻辑是否正确。测试不依赖真实的 Skill,skill 名称是测试用的模拟字符串。

cahr 输出示例

Session 结束时,cahr 会打印汇总:

{
  "sessionId": "abc-123",
  "sourceId": "my-workstation",
  "skillCount": 1,
  "skillList": [
    {
      "skill": "batch",
      "durationMs": 500,
      "nestedCalls": ["Bash", "Read"]
    }
  ],
  "totalUsage": {
    "inputTokens": 5000,
    "outputTokens": 300,
    "cacheReadTokens": 20000,
    "cacheCreationTokens": 1000,
    "costUsd": 0.05
  },
  "sessionDuration": 30000,
  "stopReason": "end_turn"
}

Claude Code 可观测性:HTTP Hook vs OpenTelemetry

Claude Code 提供两种数据收集机制:

| 机制 | 说明 | |------|------| | HTTP Hook | 实时回调,可以修改或拦截操作 | | 原生 OpenTelemetry | 标准遥测导出,用于指标/追踪/日志 |

HTTP Hook 提供了原生 OTel 无法做到的能力:

| 能力 | HTTP Hook | 原生 OTel | |------|:---------:|:---------:| | Skill 触发链追踪 | ✅ | ❌ | | 嵌套深度追踪 | ✅ | ❌ | | 实时处理 | ✅ | ⚠️(批量) | | 修改/拦截操作 | ✅ | ❌ | | Token/费用指标 | ❌ | ✅ | | 标准格式导出 | ❌ | ✅ |

详细对比见 docs/data-collection-matrix.md


支持的 Hook 事件

| 事件 | 端点 | |------|------| | PreToolUse | /hook/pre-tool-use | | PostToolUse | /hook/post-tool-use | | PostToolUseFailure | /hook/post-tool-use-failure | | PermissionRequest | /hook/permission-request | | PermissionDenied | /hook/permission-denied | | UserPromptSubmit | /hook/user-prompt-submit | | Stop | /hook/stop | | StopFailure | /hook/stop-failure | | SessionStart | /hook/session-start | | SessionEnd | /hook/session-end | | SubagentStart | /hook/subagent-start | | SubagentStop | /hook/subagent-stop | | TaskCreated | /hook/task-created | | TaskCompleted | /hook/task-completed | | PreCompact | /hook/pre-compact | | PostCompact | /hook/post-compact | | Notification | /hook/notification | | TeammateIdle | /hook/teammate-idle | | InstructionsLoaded | /hook/instructions-loaded | | ConfigChange | /hook/config-change | | CwdChanged | /hook/cwd-changed | | FileChanged | /hook/file-changed | | WorktreeCreate | /hook/worktree-create | | WorktreeRemove | /hook/worktree-remove | | Elicitation | /hook/elicitation | | ElicitationResult | /hook/elicitation-result |


扩展 Forwarder

实现 Forwarder 接口即可添加自定义转发目标:

interface Forwarder {
  forward(data: ForwardPayload): Promise<void>;
}

例如转发到 Kafka:

class KafkaForwarder implements Forwarder {
  constructor(private brokers: string[], private topic: string) {}
  async forward(data: ForwardPayload): Promise<void> {
    // 发送到 Kafka
  }
}

使用多个 Forwarder:

const forwarder = new CompositeForwarder([
  new ConsoleForwarder(),           // 本地调试
  new HttpForwarder('https://...'), // 远程服务器
]);

更多文档


License

MIT - 见 LICENSE