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

@jochenyang/dsh-rewind-plugin

v0.1.4

Published

Message recall for DSH: cut the conversation back to before a chosen user message so it leaves the model's context, hide it in the transcript, and put its original text back in the composer. Works through the kernel's own surface-replacement mechanism, so

Downloads

597

Readme

给 DeepSeek Harness 用的消息撤回:把会话退回到某条 已发送消息之前。

已发送的消息改不了也收不回。这个插件把模型可见的对话表面裁到某条用户消息之前:这条消息及其之后的 内容退出模型上下文、从对话界面隐藏,原文回到输入框,可以改完重发。被撤回的那些回合改动过的文件会 恢复原样,而每一个被移走的字节都留在隔离区里,可以查看、可以清空。

效果

撤回前的确认框:会改动 1 个文件,附改动前后的差异;被移走的字节进隔离区

撤回前的确认框:这次撤回会改动哪些文件、每个文件的真实前后差异,以及挡路的那些字节最后去了哪里。 不会删除任何东西。

它带来什么

| 位置 | 说明 | |-----------------------|----------------------------------------------------------------------------------| | 每条消息上的撤回图标 | 把鼠标停在对话里的一条用户消息上 | | /rewind | 留空列出可撤回的消息;/rewind <n> 撤回第 n 条;/rewind plan <n> 只看预览不动手 | | 输入框回填 | 被撤回消息的原文回到输入框,一次撤回只回填一次 | | 设置 → 撤回隔离区 | 设置里独立的一页:按会话分组列出每个被移走的文件,逐条或整段清空,清空前有一次确认 |

隔离区这一页注册在 settings.section——设置外壳自己留给功能插件的座位,所以它和内置的「通用 / 模型 / 插件」并列。没有设置外壳的 profile 只是少这一页,其余功能不受影响。

安装

# 从 registry 装
dsh plugin --profile web add @jochenyang/dsh-rewind-plugin

# 或者直接用 Release 里的 tgz,不经过 registry
dsh plugin --profile web add https://github.com/JochenYang/dsh-rewind-plugin/releases/latest/download/dsh-rewind-plugin.tgz

# 或者从仓库装,安装时自动构建
dsh plugin --profile web add github:JochenYang/dsh-rewind-plugin

web 是随包发行的 profile 名,换成你自己在用的那个即可。三种写法都会把这个包写进该 profile 的依赖, 并把包名追加到 dsh.profile.bundles;重启这个 profile 才会加载它。

peerDependencies 里刻意不写任何 @deepseek-ai/dsh-*:安装器会把每一个这类 peer 与当前运行版本做 比较,不满足就拒绝安装,那等于把这个插件限制在某一个 DSH 版本上。而这个插件运行起来不需要额外安装任何 东西——下面列的运行时包在任何 DSH profile 里都已经存在——所以跳过这项校验,任何运行版本都能装上。 代价是明确的:将来某个 DSH 版本改了这些接口,插件会装上并在调用时失败,而不是在安装时被拒。

为什么不会丢东西

会话日志只追加,它始终是唯一的事实来源。一次撤回只追加一条带 surfaceOp: { op: 'replace', startSeq, endSeq } 的事件,所以日志里每个事件都还在;不理会 surface op 的读取方看到的仍是完整对话。

文件从不被删除。挡路的那些字节先被移进 $DSH_HOME/storages/dsh-rewind-plugin/quarantine/<会话>/<槽位>/(连同写明原路径的 manifest.json), 然后才写回改动前的版本。被撤回区间新建出来的文件也是移进去,而不是删掉。

运行时需要什么

从 profile 里解析,不打包进产物:

@deepseek-ai/cordis、@deepseek-ai/dsh-commands、@deepseek-ai/dsh-session、 @deepseek-ai/dsh-session-projection、@deepseek-ai/dsh-llm、@deepseek-ai/dsh-home-paths、 @deepseek-ai/dsh-client-connection、@deepseek-ai/schemastery、zod。

浏览器半边只需要 react、react/jsx-runtime、react-dom/client 与 @deepseek-ai/dsh-client-ui-primitives,这四者由外壳自己的模块表提供。它们不写进 dsh.client.external,因为外壳本来就能回答。

使用注意

  • 一个会话同时只有一个写入者。 DSH 对每个会话持有一把跨进程独占写锁,直到写句柄关闭才释放。 因此共用同一个 $DSH_HOME 的两个 DSH 进程无法同时写同一个会话:后者的命令执行会被 session/writer-held 拒绝,撤回则会报「请求没能送到内核」。第二个实例读同一个会话没问题, 不同会话之间也从不冲突——把那个会话在另一个窗口里关掉,或者换一个会话继续。
  • 撤回需要 agent 处于空闲。正在跑的回合会被直接拒绝而不是去抢,因为从回合中间裁剪会让该回合后面的 工具结果失去对应的调用。

已知限制

  • 由命令行命令改动的文件,或者任何绕开通道、用自己的文件句柄写入的工具,都不会经过 fs/write-intent / fs/edit-intent 这两条瀑布。这类改动无法恢复,确认对话框和结果都会如实说明, 不会谎称已经完整还原。
  • 占位符是一条内容为空的 user/message。DeepSeek 的请求构造会丢掉空的用户消息,所以它在那边不产生 面向模型的回合;换成不丢空用户内容的 provider,一次撤回会多出一条空的用户消息。

开发

npm install
npm run build      # 产出 lib/index.js + lib/client.js
npm run typecheck
npm test           # 用 esbuild 打包 tests/*.test.ts,再跑 node --test

npm run build 把 @deepseek-ai/*、@cordisjs/*、react、react-dom、zod 标为外部依赖,并把 浏览器半边包进 web 客户端要求的 window.__ModuleLoader__.load({ id, factory }) 闭包。不要把任何 @deepseek-ai/* 打进产物:第二份拷贝会让类身份对不上运行中的宿主。

lib/ 已入库,所以 dsh plugin add github:JochenYang/dsh-rewind-plugin 不需要构建就能装—— pnpm 默认拒绝运行 git 依赖的构建脚本,除非该 profile 把它加进允许名单。改过 src/ 之后跑一次 npm run build;prepublishOnly 会在发布到 registry 前做同一件事。

目录

| 路径 | 内容 | |--------------------------------------------------------|------------------------------------------------| | src/index.ts | host 半边:/rewind 命令、写入记录器、快照与回滚 | | src/cut.ts | 撤回计算:锚点、替换范围、占位符 | | src/projection.ts | rewindAnchors 投影,客户端全部的读取面 | | src/routes.ts、src/quarantine.ts、src/snapshots.ts | 隔离区的 HTTP 路由、列表与清空、改动前的镜像 | | src/recorder.ts | 哪个文件改动属于哪个回合 | | src/wire.ts | 两半共用的载荷形状与错误码 | | src/client.ts | 客户端半边:图标、选择器、回填、隐藏回合、设置页 | | src/client/ | 组件、中英文案、注入的样式表 | | cordis.patch.yml | 挂载插件的唯一一行 insert |

更新日志与版本号

每个版本都记在 CHANGELOG.md 里,格式遵循 Keep a Changelog 1.1.0;版本号遵循 语义化版本 2.0.0。中文版即本文件对应的 CHANGELOG.zh-CN.md。

许可

MIT