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

@ocdb/tool-sdk

v0.1.1

Published

为业务工具添加调试元数据的轻量 SDK。

Readme

@ocdb/tool-sdk

为业务工具添加调试元数据的轻量 SDK。

通过 defineDebugTool() 包装业务工具,声明其副作用级别默认 replay 策略,使 @ocdb/plugin 的 Tool Cassette 在 fork/replay 时能做出正确的处理决策。

可选但强烈推荐:未包装的工具仍会被 capture,但 replay 时只能使用默认的 re_execute 策略,无法自动跳过副作用或复用历史结果。


安装

npm install @ocdb/tool-sdk

快速上手

import { defineDebugTool } from '@ocdb/tool-sdk'

// 只读查询:replay 时直接复用历史结果
export const queryMetadata = defineDebugTool({
  name: 'query_metadata',
  sideEffectLevel: 'read_only',
  defaultReplayPolicy: 'reuse_result',
  execute: async (args: { reportId: string }) => {
    return await metadataService.query(args.reportId)
  },
})

defineDebugTool(options) API

function defineDebugTool<TArgs, TResult>(
  options: DebugToolOptions<TArgs, TResult>
): DebugToolDef<TArgs, TResult>

参数

| 字段 | 类型 | 说明 | |------|------|------| | name | string | 工具名称,需与 OpenClaw tool 注册名一致 | | sideEffectLevel | SideEffectLevel | 副作用级别(见下表) | | defaultReplayPolicy | ReplayPolicy | 默认 replay 策略(见下表) | | execute | (args: TArgs) => Promise<TResult> | 原始实现,不需要修改 |

返回值

interface DebugToolDef<TArgs, TResult> {
  name: string
  sideEffectLevel: SideEffectLevel
  defaultReplayPolicy: ReplayPolicy
  execute: (args: TArgs) => Promise<TResult>
  __isDebugTool: true   // 标记,供 plugin 识别
}

副作用级别(SideEffectLevel

| 值 | 含义 | 典型工具 | |---|---|---| | 'none' | 纯函数,无任何副作用 | 格式转换、计算 | | 'read_only' | 只读查询,不修改状态 | 查询数据库、读取配置 | | 'expensive_read' | 只读但代价高(慢/贵) | 大 SQL 查询、外部 API 调用 | | 'write' | 写入操作,可能影响后续状态 | 保存报表、更新数据库 | | 'external_irreversible' | 外部不可逆操作 | 发送消息、提交工单、扣费 |


Replay 策略(ReplayPolicy

| 值 | 含义 | 适用场景 | |---|---|---| | 'reuse_result' | 直接返回历史结果,跳过真实调用 | 只读/昂贵读工具,结果稳定 | | 're_execute' | 重新真实调用 | 无副作用工具,或需要最新数据 | | 'mock_result' | 返回 --mock-tool 配置的数据 | 测试特定工具输出的影响 | | 'manual_confirm' | 需要人工确认(当前版本等同于 re_execute) | 写入类工具的交互式调试 | | 'forbid_replay' | 阻止重放并报错 | 写入/不可逆工具,防止意外重复执行 |

注意defaultReplayPolicy 是默认值。ocdb replay --tool-policy <tool>=<policy> 可以在单次 fork 时覆盖。


完整示例

import { defineDebugTool } from '@ocdb/tool-sdk'

// ✅ 元数据查询 — 幂等,总是复用历史结果
export const queryReportMetadata = defineDebugTool({
  name: 'query_report_metadata',
  sideEffectLevel: 'read_only',
  defaultReplayPolicy: 'reuse_result',
  execute: async (args: { reportId: string; version?: number }) => {
    return await reportDB.getMetadata(args.reportId, args.version)
  },
})

// ✅ SQL 执行 — 昂贵,复用结果避免重复费用
export const executeBigQuery = defineDebugTool({
  name: 'execute_bigquery',
  sideEffectLevel: 'expensive_read',
  defaultReplayPolicy: 'reuse_result',
  execute: async (args: { sql: string; params?: unknown[] }) => {
    return await bigquery.query(args.sql, args.params)
  },
})

// ✅ 图表生成 — 无副作用,可自由重跑
export const generateChartOption = defineDebugTool({
  name: 'generate_chart_option',
  sideEffectLevel: 'none',
  defaultReplayPolicy: 're_execute',
  execute: async (args: { data: unknown[]; chartType: string }) => {
    return chartEngine.compile(args)
  },
})

// ⚠️ 报表保存 — 有写入副作用,默认禁止 replay
export const saveArtifact = defineDebugTool({
  name: 'save_artifact',
  sideEffectLevel: 'write',
  defaultReplayPolicy: 'forbid_replay',
  execute: async (args: { reportId: string; content: unknown }) => {
    return await artifactStore.save(args)
  },
})

// 🚫 通知发送 — 不可逆,严格禁止 replay
export const sendUserNotification = defineDebugTool({
  name: 'send_user_notification',
  sideEffectLevel: 'external_irreversible',
  defaultReplayPolicy: 'forbid_replay',
  execute: async (args: { userId: string; message: string }) => {
    return await notifyService.send(args)
  },
})

ocdb replay 配合使用

声明了 defaultReplayPolicy 之后,ocdb replay 默认遵从工具自身的策略。也可以在命令行临时覆盖:

# 默认行为:每个工具用自己声明的策略
ocdb replay run-xxx --from ckp-yyy

# 临时覆盖:强制让 save_artifact 使用 mock 数据而不是报错
ocdb replay run-xxx --from ckp-yyy \
  --tool-policy save_artifact=mock_result

# 全局覆盖:所有工具都复用历史结果(最快,适合定位 prompt 问题)
ocdb replay run-xxx --from ckp-yyy \
  --tool-policy reuse_result

# 混合:全局复用 + 特定工具重新执行
ocdb replay run-xxx --from ckp-yyy \
  --tool-policy reuse_result \
  --tool-policy generate_chart_option=re_execute

类型导出

export { defineDebugTool }
export type { DebugToolDef, DebugToolOptions }

// 以下类型从 @ocdb/core 重新导出(方便使用,无需额外安装):
// SideEffectLevel, ReplayPolicy