Vai al contenuto principale
R

dsh-annotation

ruisenbai/dsh-annotation

Select text in a finished assistant reply to add numbered annotations beside the quote; drafts submit with composer text and images as one user message, and the model replies to each annotation in order.

Installazione

dsh plugin --profile web add github:ruisenbai/dsh-annotation

README

DSH Annotation

包名:dsh-annotation

English

CI GitHub Release License: MIT Node.js

审阅一段很长的 AI 回复时,最麻烦的往往不是提出意见,而是反复复制原文、解释“我说的是哪一句”。dsh-annotation 让每条意见直接留在对应句子旁边:选中原文、就地写下注解、攒齐多条注解,再通过 DSH 官方输入框一次发送;模型会按“注解 N”逐条回答,并在回复里给每条答案挂上可悬浮查看的注解芯片。

**交互来源说明:**本插件独立、非官方地复刻了 ChatGPT 的正文注解功能,并将这套体验带到 DeepSeek Harness。复制的是使用流程,不是 OpenAI 的源码、素材、API 或品牌;本项目与 OpenAI 无隶属或官方合作关系。

**兼容性提示:**项目要求 DeepSeek Harness 0.1.1-rc.2 或更高的 0.1.x 预发布版本。DSH 仍处于预发布阶段。当前没有助手正文内部 Slot,本插件会原地装饰已有助手渲染器,不再占用 assistant-step;用户与 steering 消息仍使用优先级覆盖。升级 DSH 前请阅读兼容性说明

界面预览

整个流程都留在对话里:选中原文、添加一条或多条编号注解、检查草稿,再从熟悉的 DSH 输入框发送。

dsh-annotation 的编号注解、就地编辑器和输入框草稿列表总览

选中真正想讨论的文字,浏览器原生选区仍然保留,随时可以复制。

选中的助手回复原文及添加注解、复制操作

趁上下文还在眼前,直接在原文旁写下意见。

助手回复旁的正文注解编辑器

发送前可以集中检查和调整所有本地草稿。

带原文引用的正文注解草稿列表

暂时不想使用注解时,可在 设置 → 插件 → 插件配置 中关闭功能,已有草稿不会丢失。

DSH 插件配置中的正文注解开关

功能

  • 在一条已完成的助手回复内选中文字后,弹出带“添加注解”和“复制”两个按钮的小浮条;即使拖选结束、松开鼠标时指针已在正文区域外,浮条也会照常出现。蓝色选区保持不消失,随时可以按 Ctrl+C 复制;点击其它地方或按 Esc 浮条消失。
  • 在选区旁直接显示紧凑输入框,右侧只有取消和保存图标。空内容点击外部会关闭;有内容点击外部会保持打开、显示红边并震动,直到选择一个图标操作。
  • 输入停止 400ms 后自动保存编辑中内容并显示本地保存状态;刷新后可恢复,但不会因此变成已提交注解。
  • 编辑器完整处理中文输入法:组合输入期间的 Enter 只完成选词,组合刚结束产生的同一次 Enter 不保存,普通 Enter 保存,Shift+Enter 换行,组合期间的 Escape 不关闭编辑器;组合输入事件不会传到官方输入框。
  • 新增注解保存成功后,等一次微任务加一帧渲染,把焦点和原光标位置交还官方输入框;保存失败、取消编辑、会话切换、编辑已有注解时不抢焦点,也不覆盖输入框已有文字。
  • 将两行注解记录分成“待附着”“确认结果/待重试”“权威队列”“已发送”四类,并复用 DSH 官方按钮、状态点、图标、Tooltip 和 Toast。
  • 新注解保存成功后默认附加到官方输入框;也可以在插件配置中关闭自动附加,或随时点击标题栏回形针手动切换。切换不会展开列表,也不会立即发送;已附加时,未发送集合会随编辑、删除和新增实时变化。
  • 官方输入框是唯一任务输入和发送入口。官方文本加注解、官方图片加注解,或只有注解,都会形成一条任务和一次模型执行。
  • 文字、注解和图片合并发送:内部命令声明 images = true,图片经 rc.2 标准命令附件走官方附件通道(Base64 不进注解 JSON、不拼进命令字符串),Host 收到持久化图片块后生成一条“总体要求 + 编号注解 + 官方图片”的用户消息。
  • 发送成功后清空文字和图片并把注解标记为已发送;失败时文字、图片和注解全部保留,重试沿用同一个 submissionId,Host 对相同 submissionId 只采用首次成功结果。
  • outbox 只保存图片数量、媒体类型和摘要,不保存 Base64;页面刷新后图片无法恢复时,插件拒绝静默改成无图片提交,提示重新选择相同图片或放弃该条待发送记录。
  • 斜杠命令自动放行:附着状态下输入以 / 开头的内容时,插件暂时释放官方输入 claim 并移除零宽占位符,/goal/model 等命令正常走 rc.2 官方管线;离开命令状态后自动重新附着。claim.submit() 内会再次检查斜杠命令,竞态时直接走官方会话命令接口,不创建 outbox、不发送注解、不把注解标记成已发送;命令失败时命令文字、图片和注解全部保留。
  • 模型回复逐条对照:Host 提示词要求模型按注解顺序逐条回答、每段以“注解 N:”开头、不合并注解,并在每段前输出隐藏的 dsh-annotation-reply 关联标记、结尾输出 dsh-annotation acknowledgement 标记。Client 按文字 Range 定位“注解 N”,在对应位置覆盖 React 芯片;悬浮或键盘聚焦显示注解编号、被选中的原文和用户填写的注解。
  • 回复标记只控制显示:只识别当前会话真实存在的 submissionId + annotationId,未知、重复、伪造和格式错误的标记直接忽略;模型未按格式输出时保留普通“注解 N”文字;acknowledgement 标记才更新“已处理”状态。
  • 自定义用户节点同时显示总体要求、注解汇总框、官方图片缩略图和官方图片查看器。
  • 支持空内容注解(仅标记原文):选中原文后可以不填内容直接保存,只包含空格/换行时同样按空内容处理;编辑器提示“注解内容可留空,留空表示仅标记原文”,保存按钮在空内容时仍然可用,注解列表、紧凑概览和回复芯片显示“仅标记原文”而不是空白;清空已有注解后保存表示转成“仅标记原文”,删除仍必须使用删除操作;仅标记原文同样计入附着数量并参与发送、重试、已处理确认和逐条回复。
  • 注解 ×N 紧凑概览:输入框上方始终只显示“注解 ×N”,点击后完整注解列表向上弹出(悬浮在输入框上方的面板),不再提供完整/紧凑模式切换;数量只统计下一次发送会携带的已附着注解,新增、删除、附着、取消附着、发送成功(清零)与失败(保持不变)都会实时更新;悬浮或键盘聚焦“注解 ×N”显示只读概览(注解编号、原文摘要、注解摘要、仅标记原文状态、已附着/发送中/等待重试状态),内容较多时限制最大高度并内部滚动;没有已附着注解时隐藏入口,切换会话只显示当前会话数量。
  • 模型协议跟随 DSH 中英文环境:创建待发送记录时按 DSH 当前 locale(zh/en,无法识别时回退英文)冻结 protocolLocale,首次发送与重试使用相同语言,重试期间切换界面语言不改变已生成内容,旧待发送记录与已发送历史继续按旧英文协议处理;回复解析同时识别“注解 N:”“注解 N:”“Annotation N:”等格式,实际关联以隐藏的稳定注解标识为准。
  • 可选兼容 dsh-focus-chat:未安装时插件正常启动、不等待任何服务;安装后聚焦视图切换时,隐藏消息的原文标记与回复芯片暂停测量、消息重建后自动恢复并按消息标识去重,注解草稿与已发送记录不丢失;兼容逻辑单独封装,适配失败只关闭聚焦增强,不影响核心功能。
  • 对齐官方 Web 的助手正文流、思考过程折叠行、停止标记、输入区 Dock、图标按钮尺寸、表单字号、语义颜色、浮层表面和用户消息气泡,同时为“定位原文”保留最初的地图定位图标。
  • 支持撤销最近一次草稿删除、导出当前 Session 恢复 JSON、清空未提交草稿,并显示本地存储占用;这些本地数据控件显示在注解汇总框底部,可在插件配置中关闭“显示本地数据控件”后隐藏。
  • 保存完整原文、前后文选择器、助手消息 ID、事件序号、注解 ID 与提交 ID。
  • 对代码记录语言与起止行;对表格记录起止行列。
  • 选区重叠时合并到原有草稿,避免高亮堆叠歧义。
  • 沿用官方输入框的提交策略;注解命令通过一条可幂等重试的排队用户消息入队。
  • 使用不同的 DSH Toast 提示权威队列、持久发送和可重试失败;只有批次仍在已观测队列中时才显示撤回操作。
  • 编号位于选区结束位置所在完整正文行之后;预留防溢出区域并保持升序,同时合并思考过程展开、视口、字体和缩放触发的布局测量。
  • 点击正文数字编号后,查看卡直接出现在编号下方;从卡片发起编辑或补充时,编辑器继续锚定在同一编号下方并跟随滚动、缩放,汇总框内发起的编辑仍在汇总框内就地显示;编辑已有草稿时提供可撤销的删除操作。
  • 点击定位后,将数字编号所在的正文行垂直居中到真实会话或窗口滚动区域,并校正 CSS 缩放。
  • 使用 localStorage 恢复未发送草稿、编辑中内容和不可变重试记录。
  • 用由提交 ID 派生的稳定消息 ID 去重网络中断后的重试。
  • 只有模型明确返回对应注解 ID,状态才从“已发送”变为“已处理”。
  • 浏览器不支持 CSS Custom Highlight API 时,仍保留编号标记和定位能力。

快速开始

从源码构建

git clone https://github.com/ruisenbai/dsh-annotation.git
cd dsh-annotation
corepack enable
pnpm install
pnpm verify

把构建后的目录安装到 Web Profile:

dsh plugin --profile web add .
dsh web --profile web

打开 DSH Web 页面,在一条已完成回复中选中文字,会出现带“添加注解”和“复制”的小浮条;选区保持可选,Ctrl+C 也能复制。点击“添加注解”打开紧凑输入框,填写意见后按 Enter 或点击对号创建草稿。草稿会出现在官方输入框上方,并默认附加到官方输入框;填写可选任务文本、附加图片后,按官方 Enter 或点击发送按钮,会把文字、注解和图片一起发送。若不想自动附加,可在插件配置中关闭对应开关,之后仍可用标题栏回形针手动附加。附着状态下输入斜杠命令时,注解会暂时让路,命令正常执行,注解不丢失。

安装 GitHub Release

每个 v*.*.* 标签都会构建可安装 Tarball 并附加到 GitHub Release。下载后可以直接安装预构建包,无需执行仓库构建脚本:

gh release download v0.2.3 --repo ruisenbai/dsh-annotation --pattern '*.tgz'
dsh plugin --profile web add ./dsh-annotation-0.2.3.tgz

如果 Profile 明确允许这个可信包执行 prepare 构建,也可以安装固定标签的 Git 依赖:

dsh plugin --profile web add git+https://github.com/ruisenbai/dsh-annotation.git#v0.2.3

设置

设置 → 插件 → 插件配置 中提供可展开的 注解 卡片,其中有“启用 DSH 注解”“新增注解后自动附着到输入框”和“显示本地数据控件”三个开关,默认都开启。修改会先在卡片中暂存,点击“保存”后写入 Host 的 dsh-annotation 设置 namespace,并对这个 Host 提供的所有 Session 生效。关闭插件后会拆掉助手渲染器外面的注解层,并恢复用户消息渲染器;选区操作条、数字标记、注解列表、注解操作、隐藏传输视图和输入框附加状态都会移除,同时保留输入框中的可见文本。草稿、编辑中内容、Outbox 状态和已提交历史都不会删除;重新开启后会恢复。关闭自动附加后,新注解只保存为本地草稿,标题栏回形针仍可手动附加。关闭“显示本地数据控件”后,注解汇总框底部的本地存储占用、导出和清空草稿控件不再显示。

“恢复默认”会分别清除对应字段的用户层覆盖,并重新采用默认开启值。设置由 DSH 的 settings provider 持久化;升级时会把旧 inline-comments 设置 namespace 中的用户值迁移到新 namespace,成功后才清除旧值。0.1.3 首次启动时会保留并迁移有效的旧版浏览器启用开关,Host 接受后才删除旧 key。每个 Session 的注解草稿仍按隐私与持久化所述保存在浏览器中。

任务状态与发送方式

自动附加默认开启,因此新注解保存成功后,回形针会直接进入已附加状态。未附加时,注解保持在浏览器本地并继续可编辑;已附加时,未发送集合会实时跟随编辑、删除和新增,直到官方输入框通过 Enter 或发送按钮提交。提交事务会冻结一份不可变提交内容,只有在命令成功后才清空官方输入框,之后新增的注解归属于下一次任务。点击回形针可手动附加或取消附加,不改动文本、光标或列表展开状态。

插件不会把传输已接受直接显示成已排队。只有 ConversationSnapshot.queue 包含稳定消息 ID 后才显示“已排队”Toast 和撤回操作;持久化 user/message 出现后改为“已发送”并移除撤回。失败的事务会保留官方输入框内容、图片、附加状态、不可变提交内容和提交 ID,供稍后安全重试。

无论自动附着开关处于什么状态:斜杠命令都不携带注解,输入法选词都不触发发送,发送失败都不丢失数据。

移除的插件内“整体要求”已有内容,会在第一次成功附加时一次性迁移进官方输入框;只有官方输入框接受附加后,插件存储中的旧值才会被清除。

状态定义

  • **草稿:**仅在浏览器中,可编辑。
  • **已排队:**已进入 DSH Inbox,尚未写入模型历史。
  • **已发送:**由持久化的注解 user/message 事件重建。
  • **已处理:**模型回复明确携带提交 ID 和注解 ID 后才设置。

插件不会根据等待时长、轮次结束或界面时序推测“已处理”。

注解类型

  • **普通注解(note):**内容非空,模型根据用户填写的内容回应。
  • **仅标记原文(highlight-only):**内容为空或只有空白字符,模型直接检查并回应被标记的原文;不允许因为注解内容为空而跳过该项。旧数据缺少类型时按内容是否为空推断,已发送历史不重写。

配置

Bundle 会插入一个 dsh-annotation 行。可在当前 Profile Composition 中覆盖:

配置项默认值作用
commandNameannotation_submit浏览器到 Host 的内部传输命令名
maxPayloadBytes524288解码后 JSON 批次上限;超限拒绝,绝不截断
maxAnnotationsPerSubmission100单批注解数上限
warnSelectionChars12000长选区需要额外确认的阈值
locateHistoryPages20定位原文时最多加载的历史页数

Host 与 Client 共享同一个 Cordis 行配置,因此修改 commandName 时两端会保持一致。升级前留下的旧内部命令(inline_comments_submitinline_annotations_submit)由不可见的兼容别名转发给新处理器,不保留两套业务代码。

协议与兼容

新提交只生成 v2 协议(protocolVersion: 2source: "dsh-annotation"、注解字段为 annotationkindprotocolLocale);旧 v1 数据继续读取,旧 comment 字段读取后转换成新的内部模型,缺少 kind 时按内容是否为空推断,缺少 protocolLocale 时按旧版英文协议处理。历史消息不重写;旧版 acknowledgement 和回复标记继续识别,新消息只生成 dsh-annotation-* 标记。本地存储使用 dsh-annotation:v1:<session-id> 命名空间,启动时优先读取新存储,否则迁移并校验旧存储,迁移成功后才删除旧数据。详见兼容性说明数据模型

隐私与持久化

未发送原文、注解、编辑中内容和重试记录保存在 dsh-annotation:v1:<session-id> 对应的 localStorage 中。当前键不存在时,会把 dsh-inline-comments:v1:<session-id>dsh-inline-annotations:v1:<session-id> 下的有效数据校验、转换、写入新键,成功后才删除旧键。可见存储键继续使用 v1,其中经过校验的数据值采用 storageVersion: 2,旧版值会在读取时迁移。用户通过官方输入框提交前不会发送到 Host 或模型。提交后,原文和注解会进入当前 Session 日志和模型上下文。图片走 DSH 官方附件通道持久化,注解数据中不保存图片字节。插件不包含分析、遥测或外部网络客户端。详见隐私说明

模型体验

  • **提交前:**不产生 Prompt、Token 或 KV Cache 影响。
  • **提交时:**写入一条标准用户消息,包含官方输入框文本、完整批次、稳定 ID、原文、注解、注解类型、结构坐标、协议语言和官方图片附件。
  • **逐条回答:**提示词按 DSH 当前语言生成中文或英文协议:中文要求每段以“注解 N:”开头,英文要求每段以 “Annotation N:” 开头,并先输出隐藏关联标记;“仅标记原文”明确要求直接检查并回应对应原文,不允许跳过。Client 渲染前隐藏标记,并在对应位置覆盖注解芯片。
  • **处理确认:**消息要求模型在确实处理后返回一个列出注解 ID 的 acknowledgement 标记。Client 渲染前隐藏标记,但原始模型文本仍可重放。
  • **Token:**成本随完整选区和注解增长;插件不做静默截断。超出字节限制会在入队前拒绝。
  • **KV Cache:**Steer 或 Follow-up 与普通用户消息一样改变后续模型上下文。

开发

pnpm typecheck
pnpm lint
pnpm test
pnpm exec playwright install chromium
pnpm test:browser
pnpm test:coverage
pnpm build
pnpm verify:bundle
pnpm publint
pnpm pack

CI 会在 Node 22.19 与 24 上执行类型检查、Lint、单元测试、生产构建、Bundle 验证和 publint。Node 24 任务还会运行真实 Chromium 回归测试并创建包产物。更多信息见开发指南架构数据模型

已知限制

  • DSH 暂无助手 Markdown 内部 Slot。本插件通过 rc.2 的 ctx.slots.entries() 原地装饰现有 assistant-step 组件并合并其 inject,不新增该 keyed 单元,因此与 dsh-smooth-stream 等同类装饰可以组合;usersteering 仍以优先级 -100 覆盖。Slot 条目结构变化时需要重新兼容验证。
  • 未发送草稿只存在当前浏览器,不会跨设备同步;已发送批次可从 Session 日志恢复。
  • 模型确认属于协作协议。模型遗漏或破坏标记时,状态保持“已发送”,不会猜测为“已处理”;模型未按格式输出时,回复中的“注解 N”保持普通文字。
  • 页面刷新后,官方输入框中的未发送图片无法恢复;此时重试带图片的批次会被拒绝,需重新选择相同图片或放弃该条待发送记录。
  • 归档任务没有活跃输入框,无法附加注解;请在可编辑任务中创建注解。
  • CSS Custom Highlight 取决于浏览器支持;不支持时仍可使用编号标记和时间线定位。
  • 一次选区必须位于同一条助手回复内,跨消息选区会被拒绝。
  • DSH 暂无私有命令注册标记,因此经过严格校验的内部传输命令可能出现在斜杠命令目录中;旧命令别名不显示在插件设置页中。

社区

项目采用 MIT License

Plugin correlati