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

dsh-drift-guard

v0.1.0

Published

drift-guard (防跑偏): zero-dep drift guard for DeepSeek Harness (dsh) coding agents — loop retry, empty-turn and result-stall detection, optional hard deny. Advisory by default.

Readme

dsh-drift-guard 防跑偏

DeepSeek Harness (dsh) 的 agent 漂移守护插件:零依赖、默认只提醒不拦截,在 coding agent 跑偏烧 token 时拉它一把。检测三种高发跑偏形态,并可选的硬阻断:

  • 结果停滞(R1):参数在变、结果原地打转——"换着花样重试同一个失败",对目标无实际进展。
  • 空转回合(C):一个回合烧了大量输出 token(多为 reasoning)却零工具调用、几乎无文本产出就结束。
  • 循环重试(B):同一工具 + 同一参数反复调用(如 npm test 连跑 3 次不读失败原因)。
  • 硬阻断(L2,opt-in):tools/pre-execute 在链达阈值时执行前 deny(工具根本不跑)。

与官方守卫的分工:官方 @deepseek-ai/dsh-repeat-tool-reminder 由 dsh-base 宿主层挂载 (阈值 [3,5,8],建议式),所有 standard 系会话自带——循环重试(B)的建议提醒官方已覆盖。 因此 drift-guard 的循环提醒默认关闭;它的独有价值是官方没有的: 结果停滞(R1)(官方只看输入 name+args,抓不到"参数变了结果不变")、 空转回合(C)、以及官方纯建议、drift-guard 可执行前拦截的 L2。


安装

前置:Node.js ≥ 22.19、已装 dsh CLI(含 pnpm)。插件以 npm bundle 包形式提供, dsh plugin 会把它装进你选择的 profile(web / dsh-tui / 其它),装完对 该 profile 下所有 preset 的会话生效(宿主层挂载,与官方 repeat-tool-reminder 同层)。

方式一 · dsh 命令(推荐)

把 <名字> 换成你的 profile(本机常见 dsh-tui 或 web):

dsh plugin --profile <名字> add dsh-drift-guard
# 例:dsh plugin --profile dsh-tui add dsh-drift-guard

装完重启该 profile(退出 dsh-tui / 停掉 web 再启动),开新会话即生效。 确认装上的方法:dsh --profile <名字> --dump-config 里应能看到 id: drift-guard 行。

卸载:dsh plugin --profile <名字> remove dsh-drift-guard(同样需重启)。

方式二 · 让 dsh 自己安装(提示词)

在任意 dsh 会话里粘贴下面这段(dsh 会自己执行命令):

请帮我安装 dsh-drift-guard 插件:先运行 dsh plugin --profile dsh-tui add dsh-drift-guard (把 dsh-tui 换成我实际在用的 profile 名),确认安装成功后, 告诉我需要重启哪些进程(退出并重开 dsh-tui / 重启 web 服务)插件才会生效, 以及装好后怎么快速验证。

安装后验证(30 秒)

开一个新会话,故意做三件"错事",应各看到一条 guard 提醒(additionalContexts, source 为 drift-guard):

  1. 同参循环:同一命令连发 3 次相同调用(官方 reminder 提醒,3/5/8 档);
  2. 改参空转:用不同参数连跑同一个失败命令 4 次(第 4 次触发 stalled × 3);
  3. 空转回合:连续 2 个回合只推理不调用工具、不输出文本。

不想看到提醒的正常工作完全不受影响(低误报设计,见下)。

作用范围与去重(重要)

  • 宿主层挂载 = 该 profile 的所有会话都生效,无论选哪个 agent preset;
  • 若你的某份 agent preset 里也挂了 drift-guard 行(本地 preset 用法,见仓库 agent.cordis.yml 里的 drift-guard 段),会和 npm 宿主挂载双挂重复提醒——二选一: 用 npm 包就把 preset 里的 drift-guard 行删掉;反之别装 npm 包。

配置(全部可选,默认值已可用)

作为宿主插件装好后

改你的 profile 自己的 patch($DSH_HOME/profiles/<名字>/cordis.patch.yml), 按 patch 语义整行替换(要写全所有键):

- id: drift-guard
  name: dsh-drift-guard
  config:
    enabled: true
    loop:
      enabled: false        # 官方已在 [3,5,8] 提醒;想用 drift-guard 的循环就开并避开 3/5/8
      thresholds: [3, 5, 8]
      exclude: []
      argumentsPreviewChars: 500
    hardDeny:
      enabled: false        # L2 硬阻断(执行前 deny),默认关
      threshold: 10
    emptyTurn:
      enabled: true
      minOutputTokens: 8000
      maxTextChars: 600
      minTurns: 2
    resultStall:
      enabled: true
      mode: error           # 'error'=只对失败结果建指纹(最稳) / 'any'=成功也算(更激进)
      threshold: 3
      minTextChars: 16
      normalizeCap: 2048
      exclude: []

| 键 | 默认 | 说明 | | --- | --- | --- | | enabled | true | 总开关(false = 不注册任何监听器) | | loop.enabled | false | 循环链建议提醒。默认关:官方 repeat-tool-reminder 已在 3/5/8 档提醒 | | loop.thresholds | [3,5,8] | 连续同参调用达此数时提醒;想开时建议避开 [3,5,8](如 [6,10,15]) | | loop.exclude | [] | 通配工具名,被排除的调用不计链也不重置链(例:['todo_write']) | | loop.argumentsPreviewChars | 500 | 详细提醒里参数预览截断长度 | | hardDeny.enabled | false | L2 硬阻断:链达阈值时执行前 deny(工具不跑)。可独立于 loop 工作 | | hardDeny.threshold | 10 | 硬阻断阈值 | | emptyTurn.enabled | true | 空转回合检测 | | emptyTurn.minOutputTokens | 8000 | 回合累计输出 token 下限 | | emptyTurn.maxTextChars | 600 | 回合文本产出上限(排除大文本回答/报告) | | emptyTurn.minTurns | 2 | 连续空转回合数达到才提醒 | | resultStall.enabled | true | 结果停滞检测(R1,默认主力之一) | | resultStall.mode | error | error=只对失败结果建指纹;any=成功结果也算(慎开) | | resultStall.threshold | 3 | 连续"参数变+结果不变"达此数提醒一次 | | resultStall.minTextChars | 16 | 清洗后文本短于此的结果不建指纹(防琐碎输出误报) | | resultStall.normalizeCap | 2048 | 参与哈希的清洗文本长度上限;0=全文 | | resultStall.exclude | [] | 通配工具名,透明(不计不重置) | | phrases.* | 见源码 | 提醒文案模板覆盖({tool} {count} {turns} {tokens} 占位符) |

干预档位组合语义

| loop | hardDeny | 行为 | | --- | --- | --- | | off | off | 无链行为(循环交给官方 3/5/8;guard 只跑空转 C + 结果停滞 R1) | | off | on | 链静默推进,达阈值时执行前 deny(无建议、纯执法) | | on | off | 与官方类似的建议式提醒(按自设阈值) | | on | on | 先按 thresholds 建议,达 hardDeny.threshold 后执行前 deny |

resultStall(R1)与上表完全正交:只依赖 post-execute,loop/hardDeny 全关也照常工作; 精确重复(同参同果)对它透明(那是 loop/官方的活),不会与任何档位重复提醒。


检测口径(低误报设计)

  • 读文件/探索不算跑偏;"做了却没产出"才算。
  • 空转签名:completed 结束 + 零工具调用 + 输出 token ≥ 阈值 + 文本 ≤ 阈值。
  • 结果停滞签名:参数 key 变化 + 结果指纹相同连续达阈值才提醒。指纹 = 清洗 (时间戳/epoch/UUID/hex 哈希/Windows 绝对路径/耗时 → 占位符、压空白)后的文本 FNV-1a 64 哈希;mode:error 下成功结果不参与。真正换了结果的调用重置连续计数。
  • 提醒走 tools/post-execute 的 additionalContexts(官方 guard 同款通道:持久化、 模型可见、可回放);不替换任何结果内容。
  • 状态仅驻留内存(与官方 guard 同取舍):resume 后从全新计数开始,不翻旧账。
  • 任何运行时异常降级为"放行一切 + warnOnce",guard 自身的 bug 不会毁会话。

验证证据

  • 假 ctx 单测 75 项断言全过(配置 fail-loud、链触发/重置、三类非误报豁免、 硬阻断 deny、各检测器解耦、enabled:false 零注册)。
  • 离线回放:真实会话日志 255 对工具调用重放 → 结果停滞 0 误报; 合成"3 次改参同错"序列第 4 次准时触发。
  • 真机挂载(preset 形态):real session 组合加载无错;同参演练 drift-guard 提醒恰好注入一次, 其余调用零误报;官方 reminder 另发一条(证明同参重复需靠 loop 默认关来避免)。

从源码开发 / 测试

git clone https://github.com/lxwallac/dsh-drift-guard
cd dsh-drift-guard
node test-drift-guard.mjs      # 75 项断言
node replay-stall.mjs          # 离线回放验证(读本机会话日志)

另一种用法:作为 agent preset 的本地行(高级)

不装 npm 包时,也可以把 drift-guard.mjs 放进你自己的 user preset 目录 (~/.dsh/.agent-presets/<名字>/),并在其 agent.cordis.yml 加一行:

- id: drift-guard
  name: ./drift-guard.mjs
  config:
    enabled: true
    # ...同上配置表,缺省用默认

这种用法只对你选了这个 preset 的会话生效,且不会与 npm 宿主挂载混用(见上文去重说明)。 仓库根目录的 agent.cordis.yml 是本地组合示例(含 @deepseek-ai standard 副本 + drift-guard 行), 按 .gitignore 不进本仓库。