← 返回列表
✓ 可直接安装
DeepSeek Harness 的「编辑某一轮」插件 ——…
自动检查通过:npm 包已发布且 engines 声明满足基线(声明 Node >=22);该结论来自程序自动检查,未经人工实机验证。 · 最近上游提交 2026/9/24 · 已提供中文文档
在 DeepSeek Harness 中编辑任意用户轮次并重新运行:内联编辑器通过官方的 surface-replace 契约将对话回滚,然后用修改后的文本重新提示智能体。仅追加的会话日志永远不会被重写。
综合分
30.7
GitHub 分
30.7
用户评分
—
★ Stars
1
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add dsh-edit-turnnpm 包 dsh-edit-turn 已校验归属本仓库,走 npm 安装最省事
信任档位:已验证本站已于 2 天前真实安装成功(L4 · 真实安装)
- 是什么
- dsh 原生插件 · chat
- 装得上吗
- 本站已真实安装成功(L4 · 真实安装,非静态推断)
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 活跃:最近一次提交在 1 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
🟢实装验证通过· 2026/9/23
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/25(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查✓ 自动检查通过
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-edit-turn @ 0.1.1
✓Node 引擎要求 >=22 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/23 08:32:48
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/dsh-settings@deepseek-ai/dsh-tools用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-edit-turn
DeepSeek Harness 的「编辑某一轮」插件 —— 点用户消息旁的编辑按钮,就地改写,确认后把会话回退到这条消息之前,用新内容重新跑这一轮。 回退走官方 surface-replace 契约(追加一条替换事件,被丢弃的内容从模型上下文里消失),重跑走官方 sessionController.prompt()。会话日志是 append-only 的,原始字节一个都不改写。
中文 · English
中文
为什么需要它
DSH 的会话日志是 append-only 的事件流:说错的提示词、问偏的问题,会一直留在模型上下文里污染后续每一轮。官方只有整段摘要式的「压缩」(/compact),没有「改一下我刚才那句话然后重来」这条路——而这恰恰是 ChatGPT / Claude 里最常用的动作。
这个插件把它补上:
- 悬停任意一条你自己发过的消息,右侧出现编辑按钮;
- 点击后在该消息下方就地展开编辑器,预填原文;
- 确认后:会话回退到这条消息之前,这条消息之后的全部内容(含当轮助手回复、思考、工具调用与结果)从模型上下文中移除;
- 然后立刻用改写后的内容重新跑这一轮,新回复照常流式出现。
特性
- 官方 seam,不改日志 —— 回退 = 追加一条带 surfaceOp: { op: 'replace', startSeq, endSeq } 的替换事件。原始事件全部留在会话文件里,只是不再进入 deriveMessages()。与官方 /compact 用的是同一套契约。
- 默认零上下文污染 —— 替换事件的载体是一个空的 system/message。官方格式文档里空的后置 system 节点是「dormant,不投影成任何消息」,所以回退后模型看到的上下文,和「对话真的停在那一点」完全一致,不会多出任何标记文本。
- 轮边界安全 —— 遮蔽窗口右端固定为日志最后一个 surface 节点,左端固定为目标消息节点,因此助手消息(内含 tool_use)与它产生的 tool/result 永远一起走,不可能留下悬空的调用/结果对。
- 重跑走官方准入路径 —— ctx.sessionController.prompt() 是唯一的口径:它会自己 resume 冷会话,并恰好开一个新轮次。
- 模型回答也能编辑 —— 回答无法被"替换":官方格式禁止 assistant/message 携带 sourceEventSeqs(已在真实校验器上验证)。做法是回退该回答及其后的内容,再追加一条带改写文本的助手消息——模型会把改写后的内容当成自己说过的话,对话可以继续。source.editedBy 会如实记录这段文字由插件写入。
- 一次点击即执行 —— 保存后不再有二次确认。编辑器本身已经是用户主动打开的动作,面板里也写明了保存会丢弃哪些内容;想恢复两步确认可在 profile 里一行开启(confirm: true)。
- 中英双语 UI,跟随 DSH 当前语言。
- 皮肤友好 —— 编辑器面板自带不透明表面(--dshet-panel)而不是借用主题的表面色变量。皮肤的本意就是让表面半透明、把插画透出来,而它只会给自己的元素补可读背景,插件类名不在其中;借用皮肤变量的面板会变成全透明,文字直接压在插画上。暗色分支走官方属性 body[data-ds-dark-theme](与 dsh-client-ui-theme 及多个官方 UI 包一致),并用 backdrop-filter 与皮肤融合。
- 可配置载体:万一某个 DSH 版本对空 system 节点处理不同,一行配置即可切回短标记载体。
- 宿主路由只限本机回环,并校验 Host 与 Origin。
安装
dsh plugin --profile web add dsh-edit-turn
从本地目录安装(开发用):
dsh plugin --profile web add /path/to/dsh-edit-turn
安装后重启该 profile 对应的 DSH 进程即可生效。
使用
1. 把鼠标移到你想改的那条用户消息上,点右侧的编辑图标(铅笔)。
2. 消息下方展开编辑器,原文已预填。改完点「保存并重跑」——一次点击即执行:这条消息之后的一切从模型上下文中移除,并立刻重新跑这一轮。
3. 编辑器与该轮之后的转录行一起消失,新提示词与新回复出现在下方。
编辑器里如果提示「这条消息包含图片或文件附件」,说明改写只保留文字,附件会被丢弃。
编辑模型的回答:悬停任意一条模型回复,同样会出现编辑入口。改完点「保存替换」——这条回答被替换为你写的内容,它之后的内容一并移除,模型从此把你写的内容当成自己说过的话,对话可以继续下去。
注意:回答里的工具调用与思考过程无法保留(替换后只留文字,编辑器会提示),因为工具调用的结果已经不再成立。
配置
写在 profile 里即可覆盖默认值:
- id: dsh-edit-turn
config:
carrier: 'system/message' # 默认:空 system 节点,模型不可见
markerText: '...' # 仅当 carrier 为 user/message 时使用的标记文本
confirm: true # 默认 true:确认后才执行回退
| 字段 | 默认 | 含义 |
|---|---|---|
| carrier | system/message | 替换事件的载体类型。system/message = 空节点,不投影成模型消息;user/message = 短标记文本,会作为一条用户消息进入上下文(等价插件在生产中用的是这种形状,作为兜底)。 |
| markerText | 一段说明文字 | carrier: user/message 时的载体文本。 |
| confirm | false | 客户端保存后是否先要求一次确认。默认关闭(一次点击即执行:编辑器本身已是用户主动打开的动作,面板里也写明了保存的后果);设为 true 可恢复两步确认。 |
工作原理
一次编辑是两步官方操作:
第一步:回退。 读事件流(sessionQuery.readSession,回退到活动会话的 snapshotEvents()),用官方折叠规则算出当前 surface 顺序,定位目标消息的节点,然后遮蔽窗口 = surface[目标下标 .. 末尾]。追加一条:
session.append('system/message', { turn, step, message: { role: 'system', content: [] } }, {
surfaceOp: { op: 'replace', startSeq, endSeq },
sourceEventSeqs: shadowed, // 完整覆盖:官方校验要求列出全部被遮蔽的节点
})
落盘后等一次持久化检查点(sessions.flush),保证重启也能看到。
第二步:重跑。
await ctx.sessionController.prompt({ requestId, sessionId, mode: 'queue', content: [{ type: 'text', text: 新内容 }] })
为什么不做文件截断? 因为那不是官方能力。dsh-session-persistence-jsonl 只暴露残帧崩溃修复用的 truncateTornTail,正常路径下「Committed events are never rewritten」;运行中的宿主把会话放在内存 append-only 日志 + 投影缓存里,改磁盘不会让它重新读取。截断还会破坏 sourceEventSeqs 的 [start,end] 压缩表示与多帧 zstd 结构。surface-replace 是官方为这件事准备的机制。
插件接口
| 类型 | 名称 | 说明 |
|---|---|---|
| 路由 | GET /dsh-edit-turn/state?sessionId= | 可编辑轮次、已遮蔽行账本、surface、忙碌状态 |
| 路由 | POST /dsh-edit-turn/apply | { sessionId, seq \| messageId \| turn, text } → 执行回退 + 重跑 |
| 工具 | edit_turn_targets | 只读:列出该会话当前可编辑的轮次与原文(供 agent 自查) |
| 前端 | conversation.input.overlay | 每会话控制器:编辑入口、就地编辑器、被遮蔽行的隐藏账本 |
验证状态
本插件在 DSH 0.1.6-alpha.2 与 0.1.7-rc.1 上完成以下验证:
| 验证 | 命令 | 结果 |
|---|---|---|
| 运行中的实例是否真的挂载了本插件(只读路由守卫探针,无需 token) | npm run probe:loaded [端口] | 通过:/state 返 400、/apply 返 405 —— 这两个状态码只有本插件会返回 |
| 浏览器半部到底问了什么、拿回了什么(只读诊断,含失败记录) | GET /dsh-edit-turn/debug | 通过:真实浏览器里确认客户端确实拿到 replies;并复现了旧 v3 会话的 session-not-found |
| 官方 append 契约(真实校验器,进程内) | npm run verify:contract | 61 项通过:替换事件被接受、派生历史真的收缩、日志 append-only、工具结果与调用同进同退、空 system 载体不产生模型消息、连续两次回退都被接受、编辑模型回答的完整机制被接受 |
| 纯逻辑 + 宿主集成 + 客户端 DOM 行为(真 HTTP、真校验器、桩服务、DOM 桩) | npm test | 83 项通过 |
| 客户端半部静态检查(注册、i18n 完整性、样式、皮肤可读性、版本三处同步、线协议) | npm run verify:client | 全部通过 |
| 实机前端产物校验(运行中的 DSH 是否在下发当前代码) | npm run verify:live -- --token-file ~/path/to/dsh.log | 全部通过(含宿主节点形状锚点) |
| 真实 profile 安装 / 补丁合成 / 启动 / 工具契约 / 路由守卫 | npm run verify:profile | 全部通过 |
| 真实浏览器端到端(agent-browser 驱动 Chrome 打开运行实例) | 手动 | 已完成:模型回答行出现「编辑这条回答」、点开编辑器预填真实回复原文、取消后网络层 0 个 apply 请求。截图见 docs/reply-editor-in-browser.png |
verify:live 针对正在运行的实例:用 DSH 启动时打印的 token 换取鉴权 cookie,读启动页里的客户端模块组,把含本插件的那一组下载下来,断言插件自己的标记确实在其中。它证明的是「浏览器刷新后会拿到当前代码」,而不是「源码看起来没问题」——前端改动后这是唯一能确认已生效的自动手段。
verify:profile 会另起独立端口 + 独立 DSH_HOME 的沙箱实例,只按 pid 结束自己启动的进程,绝不触碰你正在用的 DSH。也可以手动指定:
DSH_BIN=/path/to/dsh/lib/bin.js PORT=4123 DSH_HOME=/tmp/dsh-edit-turn-home bash tools/verify-dsh-plugin.sh
尚未验证的一环(诚实说明):与真实 DSH 界面的耦合——真实 DOM 结构、真实 CSS 布局、以及 React 调和器在重渲染行时是否会移除注入的节点——只能由真实浏览器验证(本机 React 与 Playwright 均不可用)。但纯点击路径本身已被自动覆盖:test/client.dom.test.js 用一个可读的 DOM 实现把真实的 OverlayEntry 跑起来,断言「点动作 → 编辑器出现并预填 → 点保存 → 进入确认步骤 → 点确认 → 发出正确请求 → 编辑器关闭」以及各失败分支的文案。这个测试是有意义的:把重绘标记改回旧写法时,其中 6 项会失败。
开发前置:npm test 与两个 verify: 需要 @deepseek-ai/dsh-session 与 @deepseek-ai/dsh-tools 可解析。本插件自身不依赖它们(宿主半部只 import schemastery 与 dsh-tools),测试需要一个装了 DSH 的 node_modules:
ln -s /path/to/dsh-install/node_modules ./node_modules
已知限制
- 可以编辑你自己输入的消息与模型的回答;注入的上下文行与系统提示词没有编辑入口。
- 编辑一条回答会把它替换为纯文本:该回答里的工具调用与思考过程会被移除(编辑器会提示),因为它们的结果已不再成立。
- 编辑一条用户消息会重跑那一轮;编辑一条模型回答只替换内容,不会重新问模型。
- 编辑会丢弃该消息之后的全部轮次(MVP 语义,和 ChatGPT 的编辑一致)。想保留原文形成分支,需要走 sessionController.fork({ sessionId, atSeq }),尚未实现。
- 只改写文本。消息里含图片/文件附件时,改写后只保留文字(编辑器会提示)。
- 会话必须当前在 DSH 中打开,否则返回 409 session-not-active。
- 进行中拒绝编辑:未闭合的轮次或正在压缩时返回 409 busy。
- 回退是持久的,隐藏不是。回退写进日志后,模型上下文永久改变;转录里那些行的隐藏是本插件客户端半部做的。卸载插件后,旧行会重新显示出来(而模型上下文里的回退仍然生效)——因为替换事件是官方事件,不会随插件消失。
- 回退后系统提示词保持不变(窗口永不包含 surface 节点 0,该节点也永不可编辑)。
- 旧会话(v3 格式日志)在 DSH 0.1.7 下读不到:DSH 的会话读取层对这类日志返回 session-not-found,本插件因此在其中完全不工作(表现为没有编辑入口)。新写的会话是 v4,正常。
更新日志
0.2.1 —— 修 0.1.7 上的两处界面问题,并补上让问题可自证的诊断手段。
- 修复:模型回复的编辑入口改注册进官方插槽 conversation.chat.assistant-actions,与平台自己的 复制 / 赞 / 踩 / 分支 / 用量 同排(此前是 DOM 注入,位置不一致、且会随工具调用行卸载而闪烁)。
- 修复:编辑模型回答后重新闭合该轮(step/end + turn/end)。此前修正消息被追加到 turn/end 之后、落在轮外,导致那一轮的尾巴(用时、动作条)渲染到回复正文上面。
- 修复:DSH 0.1.7 兼容——会话格式 v4 的 producer-owned source kind(plugin:)、助手消息文本取自 data.message.content。
- 新增:只读诊断路由 GET /dsh-edit-turn/debug;npm run probe:loaded [端口]。
0.2.0 —— 可以编辑模型的回答。回退该回答及其后内容,再追加一条带改写文本的助手消息(回答无法原地替换:官方格式禁止 assistant/message 携带 sourceEventSeqs)。不重跑模型;source.editedBy 如实标记文字由插件写入。
0.1.1 —— 去掉多余的二次确认(默认一次点击即执行);修皮肤下界面可读性。
0.1.0 —— 首版:回退并重跑你自己发过的消息。
姊妹插件
- dsh-delete-turn —— 单条消息/单步/单条回复的删除,同一套 surface-replace 契约。
- dsh-free-search —— 免 key 多引擎网络搜索。
- dsh-delete-session —— 侧边栏会话删除。
兼容性
- dsh.engines.dsh: >=0.1.6-alpha.2(本插件依赖该版本的消息行定义与 surface 语义;0.1.6-alpha.2 与 0.1.7-rc.1 均已实测)。
- 客户端依赖:dsh-client-locale、dsh-client-ui-chat、dsh-client-ui-conversation、dsh-client-ui-primitives。
- 宿主依赖:dsh-settings、dsh-tools(peer);@deepseek-ai/schemastery(直接依赖)。
License
MIT
English
Why
DSH 会话日志是仅追加的事件流,因此一个打错的提示词或一个
表述不佳的问题会持续污染之后每一轮的模型上下文。
唯一的官方补救手段是 /compact,它会一次性总结整段对话。
并不存在“改写那条消息再试一次”——而这恰恰是 ChatGPT 和 Claude 中最常用的
操作。
本插件补上了它:
- 悬停任何你发送的消息,该行上会出现一个编辑操作;
- 点击它会在该消息下方打开一个就地编辑器,预填原始文本;
- 确认后会把对话回退到该消息之前:它之后的一切(那一轮的回复、推理、工具调用及其结果)都会离开模型上下文;
- 修改后的文本随后会立即重新运行该轮次,新的回复照常流式返回。
功能特性
- 官方接缝,日志不受影响。 回滚会追加一个替换事件,携带 surfaceOp: { op: 'replace', startSeq, endSeq }。所有原始事件都保留在会话文件中;它只是不再进入 deriveMessages()。这与 /compact 使用的契约相同。
- 默认零上下文污染。 替换载体是一个空的 system/message。官方格式将后续的空系统节点记录为休眠状态,投影为无消息,因此编辑后的上下文与对话真的在那里停止时完全一致——不会添加任何标记文本。
- 轮次边界安全。 影子窗口始终结束于最后一个表面节点,并始终开启于被寻址的消息,因此一条助手消息(它自带 tool_use 块)及其产生的 tool/result 会被一起遮蔽。悬空的调用/结果对不可能出现。
- 官方重新运行。 ctx.sessionController.prompt() 是唯一的提示准入路径;它会自行恢复冷会话,并恰好开启一个新轮次。
- 模型的回复也可编辑。 回复无法就地替换:格式拒绝在 assistant/message 上使用 sourceEventSeqs(已针对真实校验器验证)。答案会连同其后的一切一起回滚,修正后的文本会作为新回复追加——模型会继续将其视为自己的回复。source.editedBy 会如实记录这些文字是插件写入的。
- 一键应用——无需二次确认。编辑器本身就是用户打开的显式操作,面板会说明保存会丢弃什么;配置文件可通过 confirm: true 恢复两步流程。
- 双语 UI,跟随当前 DSH 区域设置。
- 对皮肤友好——编辑器绘制自己的不透明表面(--dshet-panel),而不是借用主题的表面颜色。皮肤的存在是为了让表面半透明,从而透出它的美术作品,并且它只会补偿自身的元素;插件的类名不在该列表中,因此借用这些变量的面板最终可能完全透明,文字直接落在美术作品上。深色分支使用官方的 body[data-ds-dark-theme] 钩子(与 dsh-client-ui-theme 及若干官方 UI 包使用的相同钩子),并通过 backdrop-filter 融合。
- 可配置载体:如果某个 DSH 版本对空系统节点的处理方式不同,一行配置即可恢复标记文本载体。
- 仅限回环的主机路由,带 Host 和 Origin 校验。
安装
dsh plugin --profile web add dsh-edit-turn
从本地检出安装(开发):
dsh plugin --profile web add /path/to/dsh-edit-turn
重启为该配置文件提供服务的 DSH 进程以使其生效。
用法
1. 悬停在你想要更改的用户消息上,然后点击铅笔操作。
2. 其下方会打开一个编辑器,并预填原始文本。点击“保存并重新运行”——一次点击即可应用:此消息之后的所有内容都会离开模型上下文,该轮次会立即重新运行。
3. 编辑器会连同被丢弃的行一起消失;新的提示词及其回复会出现在下方。
如果编辑器警告该消息带有附件,重写只会保留文本并丢弃附件。
编辑模型说过的话。 将鼠标悬停在任何模型回复上,会出现同样的编辑操作。点击“保存替换”——该回复会被你的文本替换,其后所有内容都会被移除,模型会继续将你的话当作它自己的话,因此对话可以从那里继续。
请注意,该回复中的工具调用和推理无法在替换后保留(只保留文本,并且编辑器会先发出警告):一旦你更改了模型说过的话,它们的结果就不再有效。
配置
- id: dsh-edit-turn
config:
carrier: 'system/message' # default: an empty system node, invisible to the model
markerText: '...' # used only when carrier is user/message
confirm: true # default: require a confirmation step
| 字段 | 默认值 | 含义 |
|---|---|---|
| carrier | system/message | 承载替换内容的事件类型。system/message 是一个空的休眠节点,不会投影为任何模型消息。user/message 是一个会进入上下文的短标记;一个等效插件在生产环境中以这种形态运行,因此它是回退方案。 |
| markerText | 一行说明文字 | 当 carrier: user/message 时的载体文本。 |
| confirm | false | 客户端在应用前是否要求二次确认。默认关闭——一次点击即可应用,因为编辑器本身就是用户打开的明确操作,并且面板会说明保存会丢弃什么。将其设为 true 可恢复两步流程。 |
工作原理
一次编辑包含两个官方操作。
第一步,回滚。 读取事件流(sessionQuery.readSession,回退到实时会话的 snapshotEvents()),折叠官方表面顺序,定位目标消息节点,并取窗口 surface[index .. end]。然后追加:
session.append('system/message', { turn, step, message: { role: 'system', content: [] } }, {
surfaceOp: { op: 'replace', startSeq, endSeq },
sourceEventSeqs: shadowed, // complete coverage: the validator requires every shadowed node
})
随后,该追加会等待官方持久化检查点(sessions.flush),因此重新加载或 DSH 重启后仍能看到这次回滚。
第二步,重新运行。
await ctx.sessionController.prompt({ requestId, sessionId, mode: 'queue', content: [{ type: 'text', text }] })
为什么不截断日志? 因为那不是官方能力。dsh-session-persistence-jsonl 只暴露 truncateTornTail,用于崩溃恢复;在正常路径上,“已提交的事件永远不会被重写”。一个正在运行的
host 将会话保存在内存中的仅追加日志加上投影缓存里,
所以直接改磁盘上的字节并不会让它重新读取。截断还会
破坏 [start, end] 行程压缩的 sourceEventSeqs 表示以及
多帧 zstd 布局。表面替换正是该格式为此提供的机制。
插件表面
| 类型 | 名称 | 用途 |
|---|---|---|
| 路由 | GET /dsh-edit-turn/state?sessionId= | 可编辑轮次、隐藏行账本、表面、忙碌状态 |
| 路由 | POST /dsh-edit-turn/apply | { sessionId, seq \| messageId \| turn, text } → 回滚 + 重新运行 |
| 工具 | edit_turn_targets | 只读:列出会话的可编辑轮次及其文本 |
| 客户端 | conversation.input.overlay | 每会话控制器:编辑入口、就地编辑器、隐藏行账本 |
验证状态
已针对 DSH 0.1.6-alpha.2 验证,完全无需模型调用:
| 检查 | 命令 | 结果 |
|---|---|---|
| 插件是否真的挂载在运行实例中?(只读路由守卫探测,无需 token) | npm run probe:loaded [port] | 通过:/state 返回 400,/apply 返回 405——只有此插件才会产生的状态码 |
| 针对真实校验器的官方追加契约,进程内 | npm run verify:contract | 61 项检查通过:替换被接受,派生历史确实缩短,日志保持仅追加,工具结果随其调用一起离开,空系统载体不添加模型消息,两次连续回滚均被接受,整个回复编辑机制被接受 |
| 纯逻辑、宿主集成和浏览器半部分 DOM 行为(真实 HTTP、真实校验器、打桩服务、DOM 桩) | npm test | 83 项测试通过 |
| 浏览器半部分静态检查(注册、i18n 完整性、样式、皮肤可读性、三向版本同步、线上契约) | npm run verify:client | 全部通过 |
| 实时客户端产物(运行中的 DSH 是否在提供当前代码?) | npm run verify:live -- --token-file ~/path/to/dsh.log | 全部通过,包括对宿主 node 形状的锚定 |
| 真实 profile:安装、补丁组合、启动、工具契约、路由守卫 | npm run verify:profile | 全部通过 |
| 真实浏览器,端到端(agent-browser 在运行实例上驱动 Chrome) | 手动 | 已完成:模型回复行上出现编辑操作,编辑器打开时预填真实回复,取消后留下零个 apply 请求。见 docs/reply-editor-in-browser.png |
verify:live 针对的是一个已经在运行的实例:它用 DSH 启动时打印的
token 换取认证 cookie,从启动页面读取客户端模块组,下载包含此插件的
组,并断言该插件自身的标记就在其中。这证明了“浏览器重新加载会得到
当前代码”,这比“源码看起来是对的”更强——而且在前端编辑之后,
这是确认更改已生效的唯一自动方式。
verify:profile 会在自己的端口上启动一个沙箱实例,使用自己的
DSH_HOME,并且只终止它自己启动的那个进程,按 pid 终止。它绝不会
碰你正在使用的 DSH:
DSH_BIN=/path/to/dsh/lib/bin.js PORT=4123 DSH_HOME=/tmp/dsh-edit-turn-home bash tools/verify-dsh-plugin.sh
唯一未被验证的一环,直说如下: 与真实 DSH 界面的耦合——真实的 DOM 结构、真实的 CSS 布局,以及 React 的协调器在重新渲染某一行时是否会丢弃注入的节点——需要真实浏览器(本机上 React 和 Playwright 都不可用)。点击路径本身现在已被覆盖:test/client.dom.test.js 在一个可读的 DOM 实现上运行真实的 OverlayEntry,并断言“点击操作 -> 编辑器出现且已预填充 -> 点击保存 -> 确认步骤出现 -> 点击确认 -> 正确的请求被发送 -> 编辑器关闭”,外加每个失败分支的消息。这个测试是有意义的:把重新渲染标记改回旧形式会让它的 6 个用例失败。
开发前提: npm test 和两个 verify: 命令都需要 @deepseek-ai/dsh-session 和 @deepseek-ai/dsh-tools 能够解析。插件本身并不依赖它们(宿主部分只导入 schemastery 和 dsh-tools),所以测试需要一个来自 DSH 安装的 node_modules:
ln -s /path/to/dsh-install/node_modules ./node_modules
已知限制
- 人类提示和模型回复都可编辑;注入的上下文行和系统提示不提供编辑入口。
- 编辑回复会将其替换为纯文本:其中的工具调用和推理会被移除(编辑器会先警告),因为它们的结果不再有效。
- 编辑用户消息会重新运行该轮次;编辑模型回复不会再次询问模型——它只替换文本。
- 一次编辑会丢弃之后的所有轮次(MVP 语义,与 ChatGPT 的编辑一致)。将原始内容保留为分支需要 sessionController.fork({ sessionId, atSeq }),这尚未实现。
- 仅限文本。 带有图片或文件附件的消息会保留其文本并丢弃附件(编辑器会先警告)。
- 会话必须在 DSH 中打开,否则路由会返回 409 session-not-active。
- 正在运行的工作会被拒绝:未关闭的轮次或进行中的压缩会返回 409 busy。
- 回滚是持久的;隐藏不是。 一旦写入,回滚会永久改变模型上下文。在转录中隐藏这些行是本插件的浏览器部分。卸载插件后,旧行会重新出现——而模型上下文中的回滚仍然有效,因为替换是一个官方事件,其生命周期长于插件。
- 系统提示永远不会被触碰:窗口永远无法包含表面节点 0,且该节点永远不可编辑。
姊妹插件
- dsh-delete-turn - 在相同的 surface-replace 契约下删除一条消息、一个步骤或一条回复。
- dsh-free-search - 无需 API 密钥的多引擎网络搜索。
- dsh-delete-session - 从侧边栏删除会话。
兼容性
- dsh.engines.dsh:>=0.1.6-alpha.2(此插件依赖该版本的消息行定义和 surface 语义,并已在该版本上验证)。
- 客户端依赖:dsh-client-locale、dsh-client-ui-chat、dsh-client-ui-conversation、dsh-client-ui-primitives。
- 宿主依赖:dsh-settings、dsh-tools(对等依赖);@deepseek-ai/schemastery(直接依赖)。
许可证
MIT