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-evolution

v0.1.0

Published

DSH 自动进化(本地优先):记录开发会话账本,用你自己已配好的模型做跨会话复盘,把踩过的坑和有效做法沉淀成本地知识;默认不联网、不上传、可一键导出。

Readme

⚠️ v0.1.0 为占位发布:本版本只注册包名并发布项目介绍,不含功能代码;功能代码将在调试完成后的后续版本(v0.2.0 起)提供。

dsh-evolution

DSH 的本地优先自动进化插件:记录你的开发会话,用你自己已配好的模型做跨会话复盘, 把踩过的坑和有效做法沉淀成本地知识。

默认不联网、不上传、不写你的代码仓库。 数据全是磁盘上的人可读文件,随时可以看、可以导出、可以删。

当前状态:v0.1.0 · Phase 0(数据地基) 已经可用:会话账本采集、数据预览、试跑(看效果、算成本,不调模型)、 脱敏、界面化配置、目录自检。 尚未接通:自动复盘(调模型归纳)与注入。开着插件不会有任何模型费用。


为什么做这个

DSH 本身很会干活,但它不记得你上次踩过什么坑。每次开新会话,你都得重新解释一遍: "这个项目的 ConfirmOut 守卫要放在幂等判断之前"、"别用 float 存金额"、"发版前必须先跑那个脚本"。

现有的做法通常有两个问题:

  1. 要么全在云端 —— 你的全部开发对话上传到别人的服务器。
  2. 要么只有事实、没有进化 —— 只是把结论存下来,不会告诉你"这个问题你已经犯过三次了"。

这个插件想做的是第三件事:在你自己的电脑上,把跨会话的模式找出来, 在你下次动手前提醒你。而数据不出你的机器。

想了解背后的设计取舍,看 docs/DESIGN.md


它到底怎么工作

正常对话
  → 每次事件被结构化记进本地账本(纯本地、零成本、不调模型)
  → 攒够 N 轮 / 空闲时,用你自己配的模型做归纳
  → 归纳结果写成 markdown 放在本地
  → 下次进这个仓库时,把相关的几条注入到上下文里

三个关键设计决定:

| 决定 | 为什么 | |---|---| | 账本记录零 LLM、零网络 | 所以可以每轮都记、可以回扫历史,成本近似为零 | | 只用信号,不记工具的输入输出 | 工具参数与输出体积大、几乎不含可复用决策;记它们等于给自己埋一个越来越大的坑 | | 默认一切"往外"的行为都关闭 | 上传、写你的仓库、向量化、跨工作区聚合,全部需要你显式打开 |


安装

dsh plugin --profile web add dsh-evolution

装完重启 dsh web,侧边栏底部会出现「自动进化」按钮。

从源码安装(开发用):

git clone <repo> && cd dsh-evolution
npm run build
dsh plugin --profile web add "link:E:/path/to/dsh-evolution"

client/dist/index.js 是构建产物,但故意入库 —— 这样想直接从 git 安装的人 不需要装 esbuild 就能用。改完 client/ 记得跑一次 npm run build 并提交产物。

装完先做这三件事

  1. 侧边栏底部点「自动进化」→ 总览 页,确认「运行中」且数据落点路径符合预期。
  2. 数据与隐私 页点一次「重新自检」,确认目录都能创建。
  3. 正常对话几轮,回 数据预览 页点刷新 —— 看到记录就说明采集通了。

它存了什么,存在哪

全部在 ~/.dsh-evolution/(Windows: C:\Users\<你>\.dsh-evolution\)。

~/.dsh-evolution/
├── config.json          # 你的配置(纯 JSON,可手改)
├── state.json           # 回扫水位等内部状态
├── ledger/
│   └── 2026-09-17.ndjson   # 账本:一行一条事件,按天分片
├── observations/        # (Phase 1)单会话抽取产物
├── drafts/              # skill 草稿,等你决定要不要导出
└── exports/             # 导出留档

想换位置:设环境变量 DSH_EVOLUTION_HOME,或在面板「配置」里填数据目录。

一条账本记录长什么样

{"sid":"session-8c32…","seq":412,"ts":1758000000000,"day":"2026-09-17",
 "kind":"user_message","turn":7,"repo":"lescent-middle-center",
 "text":"把 ConfirmOut 的幂等判断移到守卫之后"}

明确不会记录的内容

| 内容 | 记不记 | 说明 | |---|---|---| | 你的提问与助手回答 | ✅ 记(截断后可配) | 这是复盘的主要素材 | | 工具名字与成功/失败 | ✅ 记 | 失败信号正是"踩坑"的来源 | | 工具的参数输出 | ❌ 不记 | 体积大、噪音多、含大量无关内容 | | 模型思考过程 | ❌ 不记 | | | 图片等非文本块 | ❌ 不记 | | | 绝对路径 | ⚠️ 默认脱敏成 <path>/文件名 | 见下 |


隐私

脱敏在写磁盘之前发生

不是"上传时才脱敏"。你在面板的「脱敏预览」页粘什么文本,就能看到真正会被记录的样子。

内置规则(全部可关):

  • sk- 前缀的 API key、Bearer/Basic 凭证
  • key=value 形式的密钥赋值 —— 保留键名,只掩值
  • JWT、GitHub token、AWS AccessKey、阿里云 AccessKey、私钥块标记
  • 绝对路径 → <path>/文件名
  • 你自己的敏感词表

刻意不做的事:不误伤正常代码。 const password = process.env.DB_PASSWORDapiKey = readFromVault()this.token = config.db.token 这类写法原样保留。 脱敏过头的后果是记忆全变马赛克、功能直接废掉,比漏掉一个密钥更糟。

默认值一览(都是最保守的一侧)

| 开关 | 默认 | |---|---| | 记录会话账本 | ✅ 开(纯本地) | | 自动复盘(消耗模型额度) | ❌ 关 | | 上传到任何服务器 | ❌ 关 | | 写入你的代码仓库 | ❌ 关 | | 向量检索(会把正文发往你配的端点) | ❌ 关 | | 连接外部数据库 | ❌ 关 | | 跨工作区聚合个人画像 | ❌ 关 |

三个承诺

  1. 不提供、也不托管任何云端服务。 作者不会接触你的任何数据。
  2. 默认不上传、不外发。 所有外向行为都需要你显式配置。
  3. 不做任何面向管理者展示个人画像的功能。 这是效率工具,不是监控工具。

面板

侧边栏底部「自动进化」→ 六个页面:

| 页面 | 作用 | |---|---| | 总览 | 采集状态、开关一览、历史回扫结果、数据落点 | | 试跑 | ⭐ 开启自动复盘前先看这里:会不会真的跑、会注入哪几段、大概花多少钱。不调模型、不写文件 | | 数据预览 | 逐条看已写入磁盘的内容;按会话展开折叠摘要(将来喂给模型的就是这个) | | 脱敏预览 | 左原文右结果并排对照,逐行差异 | | 配置 | 全部配置项,带人话说明,保存即生效(不用重启) | | 数据与隐私 | 这个插件会/不会做什么、脱敏现状、目录自检、你的权利 |

试跑页为什么必须存在:归纳质量差的项目,价值是负的——错误结论会被注入上下文 并长期生效。所以你可以先看再决定要不要打开开关。它也会如实告诉你 「当前条件下这次会话会不会被抽取」,而不是让你猜。

配置改动会在底部显示"未保存 N 项",点保存才落盘 —— 避免误触即生效。


配置项

配置文件是 ~/.dsh-evolution/config.json,也可以用面板改。面板是纯数据驱动渲染的: 配置项的说明、范围、可选值都在 lib/config.jsSCHEMA_FIELDS 里, 加一个配置项不需要动面板代码。

主要分组:总开关 / 会话账本 / 自动复盘 / 隐私与脱敏 / 本地 skill 落点 / 接口对接(可选) / 数据库对接(可选) / 检索 / 注入

关于 skill 落点

面板里可选三种:

| 选项 | 实际路径 | 说明 | |---|---|---| | 插件数据目录(默认) | ~/.dsh-evolution/skills/ | 不碰你的仓库、不需要改任何 DSH 配置 | | 仓库内 .agents/skills | <仓库>/.agents/skills/ | DSH 原生发现,随 git 走,团队天然共享 | | 仓库内 .dsh/skills | <仓库>/.dsh/skills/ | DSH 最高优先级的项目根 | | 自定义路径 | 你填 | ⚠️ 需要你在 DSH 配置里额外加 customSkillDirs,否则写了不生效 |

⚠️ DSH 的 skill 发现根按 rank 顺序扫描(dsh-skill-filesystem 文档实测):

| rank | 来源 | 路径 | |---|---|---| | 100 | project-dsh | <仓库>/.dsh/skills | | 200 | project-agents | <仓库>/.agents/skills | | 300 | custom | Config.customSkillDirs | | 400 | user-dsh | <$DSH_HOME>/skills | | 500 | user-agents | <~/.agents>/skills | | 600 | bundled | $DSH_BUNDLED_SKILL_DIR |

项目根 = 包含 .git 的最近祖先目录(没有则用当前 cwd)。 用列表外的目录名(比如 .agent 单数)不会被自动发现 —— 这时要么选 customSkillDirs 并在 DSH 配置里加一行,要么就落插件数据目录。 这是选"自定义路径"时面板会提醒的原因。

关于接口与数据库(默认关)

本插件不实现、也不托管任何服务端。 这两个开关只是留给"你有自己的团队服务"的场景:

  • 接口:填地址 + token 所在的环境变量名(不要把 token 写进配置文件), 上传模式目前只有 off / redacted 两档。
  • 数据库sqlite 用 Node 内置的 node:sqlite(零依赖、无需编译); postgres 需要你自备,连接串同样从环境变量读。

两者的用途是把知识共享给团队,不是把数据交给作者。


文档

| 文档 | 内容 | |---|---| | docs/DESIGN.md | 为什么这么定:五个核心决策、从 Hermes 学什么/不学什么、Phase 1 设计、已知限制 | | docs/ARCHITECTURE.md | 怎么实现的:五条设计纪律、每个模块的关键契约、踩过的坑 | | docs/HANDOFF.md | 会话交接:当前状态、下一步、调研结论索引、代码地图 |


开发

npm run check    # host 半语法检查(12 个文件)
npm run build    # 构建浏览器半(产物 client/dist/index.js)
npm test         # 冒烟测试 54 项 + 集成自检 11 项
npm run pack     # 打包到 release/

两个测试脚本分工不同:

| 脚本 | 证明什么 | |---|---| | scripts/smoke.mjs | 逻辑对:配置规范化、脱敏规则、事件折叠、账本读写、注入渲染、试跑 | | scripts/integration.mjs | 能装上去:用假 ctx 真实调用 apply(),验证模块图可解析、事件订阅与路由注册发生在正确时机、试跑确实不写文件 |

其中有三项测试专门守试跑的"不回写"不变式:对比试跑前后整个数据目录的文件指纹、 确认没创建 config.json / state.json、以及扫源码确认 lib/dry-run.js 没有 import 任何写函数或网络调用。

改 host 半(lib/)需要重启 dsh web;改浏览器半(client/)跑一次 npm run build 后刷新页面即可。

目录结构

lib/                  host 半(Node,跑在 DSH 进程里)
├── index.js            插件入口:事件订阅、历史回扫、生命周期
├── routes.js           Host↔Client HTTP 路由
├── config.js           配置模型 + 默认值 + 面板字段表(单一事实来源)
├── config-store.js     配置读写、mtime 变更检测、坏配置备份
├── paths.js            数据目录解析
├── storage.js          原子写 / NDJSON 追加读 / 按天分片
├── ledger.js           事件 → 账本记录折叠 + 会话摘要聚合
├── ledger-store.js     账本读写与缓冲落盘
├── repo.js             git 仓库定位(宁可认不出,不要认错)
├── redact.js           脱敏
├── inject.js           四段注入渲染 + 预算计算(纯函数,零 IO)
└── dry-run.js          试跑编排(只读:不 import 任何写函数)

client/               浏览器半(React,跑在 Web 里)
├── index.js            面板六页 + 侧边栏入口
├── build.mjs           esbuild 构建脚本
└── dist/index.js       构建产物(随包发布)

scripts/smoke.mjs       冒烟测试(逻辑,54 项)
scripts/integration.mjs 集成自检(能否挂载,11 项)

三条给后来者的经验

  1. session/event 回调里绝不做重活。 宿主每次 append 都会触发它, 在这里 await 一个 git 子进程或磁盘 IO,会直接拖慢 agent 循环,连"停止"按钮都会失灵。 所以:回调里只做内存折叠,落盘走缓冲+定时器,git 探测走异步+缓存。

  2. 写测试,尤其测脱敏。 这个仓库的脱敏规则在被冒烟测试覆盖之前, 连续出过三个静默 bug:正则捕获组编号错位导致规则永不生效、 替换时把键名一起掩掉、负向前瞻被回退绕过导致只掩了半个标识符。 三个都不报错,只是悄悄做错事。

  3. 测试代码本身也会骗你。 集成自检里最初有 3 个 async 检查写成了同步 check(fn), 断言失败会变成 unhandled rejection 而不计入失败数——看起来全绿,实际什么都没验。 现在同步/异步分成 check / atest 两个函数。同一类问题还出过一次: 测试数据用宿主事件名(user/message)当账本 kind(应为 user_message), 摘要静默变空;现在 foldSessionSummary 会返回 suspiciousInput 把这种情况标出来。


路线图

  • [x] Phase 0 账本采集、数据预览、脱敏、界面化配置 ← 当前
  • [ ] Phase 1 单会话复盘(接 ctx.llm,用你自己的模型)+ 项目级洞察 + 检索注入
  • [ ] Phase 2 个人进化(跨工作区,单独开关)+ 一键导出/删除
  • [ ] Phase 3 团队共享(git 仓库模式:把洞察写成 skill 草稿,你决定要不要提交)
  • [ ] Phase 4 可选能力:向量检索、自带 HTTP 后端

已知限制

  • DSH 没在跑的时候不会发生任何复盘。 没有服务端定时任务,复盘由插件进程内的定时器驱动。
  • 复盘会消耗你自己的模型额度,所以默认关闭,且提供每日预算刹车。
  • 归属判定用 git rev-parse:如果你的工作目录本身是个 git 仓库(比如 dotfiles 管理的家目录), 该会话会被归到那个仓库名下。这是 rev-parse 的语义,不是 bug,但值得知道。

许可

MIT