mengyundawang123/dsh-quoted ↗★ 0
dsh-quoted
Quote a passage in a DSH conversation: it becomes a temporary annotation file attached to the composer as a reference chip, and is deleted once the turn reads it. 适合需要在提问时快速引用历史对话片段作为临时参考背景的用户。
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:mengyundawang123/dsh-quotedREADME
Read the full README ↗注释引用(Annotation Capture)
在对话里选中一段文字,把它变成一个临时的注释文件,并以独立的引用块(chip)附到输入框。模型读完本轮内容后,文件自动删除。
Quote a passage in a DSH conversation: it becomes a temporary annotation file attached to the composer as a reference chip, and is deleted once the turn reads it.
安装
# npm(推荐:预构建,装完即用,不需要构建授权)
dsh plugin --profile web add dsh-quoted
# 或直接从 GitHub 源码安装(本插件没有构建步骤,不需要 allowBuilds)
dsh plugin --profile web add github:mengyundawang123/dsh-quoted#v0.1.0
装完重启 dsh web,在对话里选中一段文字试一下。
兼容与权限
| 项 | 说明 |
|---|---|
| 已验证版本 | dsh 0.2.1-rc.2(Windows + Web UI) |
| 网络 | 无外部请求、无遥测 |
| 磁盘 | 在当前工作区写 .dsh-annotations/*.md,目录内自带 .gitignore,不会污染仓库 |
| 进程 | Host 侧注册同源路由 POST /api/dsh-quoted,只接受带 x-dsh-quoted: 1 的请求 |
| 依赖 | 无运行时依赖 |
用法
- 在对话区选中一段文字(只认
[data-chat-flow]之内、且不在输入框里的选区); - 右键 →「引用」,或点输入框工具行左侧的「引用」按钮;
- 输入框里出现 chip:
📄 注释 17:51,原文会被淡蓝高亮并在末尾标上序号; - 接着写你的问题,发送。
规则:同一段文字 3 秒内重复触发只生成一个文件;输入法组词期间会延后写入,避免吃掉正在输入的字。
文件生命周期
选中 → 写 /.dsh-annotations/-.md
→ 发送(消息里是 @.dsh-annotations/xxx.md)
→ 模型 read 该文件
→ 本轮正常结束 → 删除
| 情况 | 行为 |
|---|---|
| 本轮读过、且属于本轮 | 回合结束即删 |
| 本轮没读过 | 保留,交给 1 小时后清扫(宁可留着,也不静默丢内容) |
| 回合被中断 | 不删(宿主不会触发 turn-stopping),留给你重发 |
| 我干活时你又标注了下一条 | 不删:它属于下一条消息,不在本轮的归属快照里 |
| 进程重启丢了登记 | 启动 5 秒后扫已注册工作区,删 1 小时前的孤儿 |
判定「属于本轮」用的是回合开始时的文件集合快照,不是时间戳 —— 时间戳在同一毫秒内无法区分先后。
失败码
按钮失败时悬停可看到原因:
| 码 | 含义 |
|---|---|
no-workspace | 无法确定写入目录 |
no-draft | 读不到输入框草稿,因此不写文件(避免产生没有分隔符的坏引用) |
forbidden | 请求头缺失 |
write-failed | 落盘失败 |
network / http-error | 请求失败 / 服务返回异常 |
安全边界
- 路由只接受带
x-dsh-quoted: 1的 POST,跨站表单打不进来; - 写入目录由 Host 决定:会话目录优先,客户端传来的
cwd只有落在已注册工作区之内才被采纳; - 单次请求体上限 256 KiB。
测试
node tests/host.test.mjs # 16 项:不变量 + 300 步模型随机游走 + 清扫/重启/HTTP 面
node tests/client.test.mjs # 28 项:选区范围、去重、输入法、chip 载荷、角标、失败码
npm test # 串跑
Host 套件用假 Cordis 上下文驱动真实模块:只有 inject 声明的服务是上下文属性,其余必须走 ctx.get —— 与运行时语义一致,所以「漏声明依赖」这类问题会被测出来。
Client 套件把真实 client.js 装进 vm,配一个带 hook 运行时和卸载清理的 React 仿真、假 DOM、假 fetch,直接调用它注册的组件与事件处理器。
覆盖不到的部分
- 没有真浏览器:
CSS Custom Highlight与角标定位在仿真中被跳过/打桩; - 仿真的 React 不比较依赖,闭包过期类问题测不出;
- HTTP 用例串行,没有真并发;
- 「重启扫描」用重新 import 模块实例模拟,不是真的重启进程。
分隔符
宿主解析 @引用 需要前导空白:
@ 前面 | 结果 |
|---|---|
| 消息开头 | 解析成文件引用(蓝色) |
| 空格 / 换行 | 解析成文件引用(蓝色) |
紧贴文字(1111@path) | 不解析,整段按纯文本显示 |
两个位置各自处理:
- 前导(你的文字 → chip):由
SEPARATOR决定,默认' '。宿主会丢掉 chip 前紧贴的空格,所以文字直接贴着 chip 打字时,引用会退化为纯文本 —— 这是宿主行为,插件改不动。改成'\n'可以让 chip 单独起一行、恒为蓝色,代价是拆行。 - 尾随(chip → 你的后续文字):必须是独立的空格文本节点。已验证
clipboardText里的空格不会进入存储的消息(宿主用编辑器文本序列化,不读该字段),把它挪进 chip 会导致后续文字并进引用、整段变蓝。
const SEPARATOR = ' ' // 同一行(当前);改成 '\n' 即拆行模式
const text = `${prefix} ` // chip 之后必须有这个空格节点,不能省
改完刷新页面即可生效,不需要重启 DSH。
已知限制
- 用户消息气泡是纯文本渲染,宿主没有「引用块」节点类型,所以 chip 只是一种文件引用,不是原生引用卡片;
- 输入框里如果有
/命令chip,重建草稿时会退化成纯文本(宿主的Enter仍按命令判定); - Host 半改动需要重启 DSH 才装载,客户端半刷新页面即可。