DeepSeek Harness 的引用回复层:把一段话引用到输入框上方的可编辑托盘,随下一回合作为模型上下文注入(不进消息正文),并在该回合下方显示为可展开的一行。
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/17 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add liuhaolong16/dsh-quote-reply该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · other
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 16 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-quote-reply(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/16 04:09:11
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 21 处,展示前 19 条)
- 写入本地文件lib/index.js:108
const flush = () => { try { writeFileSync(STATUS, JSON.stringify(state, null, 2), 'utf8') } catch (e) {} } - 写入本地文件lib/index.js:164
try { writeFileSync(REPORT_FILE, JSON.stringify({ receivedAt: new Date().toISOString(), report: rep }, null, 2), 'utf8') } catch (e) {} - 发起网络请求lib/client.js:173
var p = fetch('/quote-reply/health') - 发起网络请求lib/client.js:333
var p = fetch(url, { method: 'POST', headers: { 'content-type': 'application/json' }, body: payload }); - 发起网络请求lib/client.js:364
var p = fetch('/quote-reply/report', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(out) }); - 发起网络请求lib/client.js:504
var p = fetch('/quote-reply/health'); - 发起网络请求lib/client.js:567
var p = fetch('/quote-reply/health') - 读取本地文件_check-client.cjs:19
const src = fs.readFileSync(FILE, 'utf8') - 读取本地文件_preflight.cjs:38
function mustRead(p) { return fs.readFileSync(p, 'utf8') } - 读取本地文件_preflight.cjs:44
if (!fs.existsSync(p)) add('FAIL', 'A 文件存在', f + ' 缺失') - 读取本地文件_preflight.cjs:46
add('PASS', 'A 文件存在', FILES.filter((f) => fs.existsSync(path.join(HERE, f))).length + '/' + FILES.length) - 写入本地文件_preflight.cjs:53
fs.copyFileSync(path.join(HERE, file), tmp) - 执行外部命令来自配置/变量_preflight.cjs:54
execFileSync(NODE, ['--check', tmp], { stdio: 'pipe' }) - 删除本地文件_preflight.cjs:55
fs.unlinkSync(tmp) - 执行外部命令来自配置/变量_preflight.cjs:57
execFileSync(NODE, ['--check', path.join(HERE, file)], { stdio: 'pipe' }) - 读取本地文件_preflight.cjs:69
try { asar = fs.readFileSync(ASAR) } catch (e) { - 读取本地文件_preflight.cjs:70
if (fs.existsSync(ASAR)) add('FAIL', 'B 读 DSH 源文件', '读不到 ' + ASAR + ':' + e.message) - 读取本地文件_preflight.cjs:100
try { ents = fs.readdirSync(dir, { withFileTypes: true }) } catch (e) { return } - 执行外部命令来自配置/变量_preflight.cjs:130
const out = execFileSync(NODE, [path.join(HERE, '_check-client.cjs')], { encoding: 'utf8', stdio: 'pipe' })
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成dsh-quote-reply —— 「引用」层(v0.4.1)
⚠️ 重启前必过门(硬规矩:动过宿主半体就必须先跑它,0 FAIL 才允许请求重启)
node _preflight.cjs :: 退出码 0 = 可以安全重启;非 0 = 先修,别重启
为什么必须是硬门:宿主半体只在 DSH 启动时加载(实测:启用/禁用、卸载重装、改 inject 全都无效)。
若它引用了不存在的 API、或与别的插件撞路由/撞上下文名,重启就是白重启一次(严重时会打断宿主 boot)。
所以「能不能重启」必须先验成一条可复跑的命令,而不是凭我的判断。
它验 6 组共 19 项:A 文件与两半体语法 · B 对 DSH 源文件(app.asar)核对 API 签名(systemPrompt.context / PromptContext 字段 / webServer.register / ctx.effect / ctx.get)· C 出厂先例(源文件里已有插件用 systemPrompt.context({name:"sandbox:policy"}) ⇒ 第三方可行)· D 冲突(路由前缀 / 上下文名 / 槽位 id,与已装插件的 13895 个文件比对)· E 客户端夹具 · F 自证机制与「不打断 boot」。
展开完整文档(README 剩余 1 节)
dsh-quote-reply —— 「引用」层(v0.4.1)
⚠️ 重启前必过门(硬规矩:动过宿主半体就必须先跑它,0 FAIL 才允许请求重启)
node _preflight.cjs :: 退出码 0 = 可以安全重启;非 0 = 先修,别重启
为什么必须是硬门:宿主半体只在 DSH 启动时加载(实测:启用/禁用、卸载重装、改 inject 全都无效)。
若它引用了不存在的 API、或与别的插件撞路由/撞上下文名,重启就是白重启一次(严重时会打断宿主 boot)。
所以「能不能重启」必须先验成一条可复跑的命令,而不是凭我的判断。
它验 6 组共 19 项:A 文件与两半体语法 · B 对 DSH 源文件(app.asar)核对 API 签名(systemPrompt.context / PromptContext 字段 / webServer.register / ctx.effect / ctx.get)· C 出厂先例(源文件里已有插件用 systemPrompt.context({name:"sandbox:policy"}) ⇒ 第三方可行)· D 冲突(路由前缀 / 上下文名 / 槽位 id,与已装插件的 13895 个文件比对)· E 客户端夹具 · F 自证机制与「不打断 boot」。
2026-10-15 实测:PASS 18 · WARN 0 · FAIL 0。
生效规则(血泪)
| 改了什么 | 怎么生效 |
| 客户端半体(lib/client.js) | plugin_manager set_bundle enabled=true target=dsh-quote-reply → 刷新页面 |
| 宿主半体(lib/index.js) | 必须重启 DSH 宿主进程(禁用/启用、卸载重装都不会重新加载它) |
| 怎么确认宿主半体真跑了 | 看 lib/.host-status.json(apply() 把注册结果写在这里);GET /quote-reply/health 应为 200 |
一句话
选中回答里的一段话 → 点「引用回复」→ 它落到输入框上方的「引用」行(和「目标」「队列」同区)。
不用再点「插入」:引用自动作为上下文随下一回合送达模型(不进你的消息正文),浮窗里可逐条展开/删除/清空。
端到端实测(2026-10-15 02:3x):推入标记「ZQ7-紫色河马」→ 下一步模型上下文里真的出现了它(## 用户当前引用…)→ 随即清空(pending:0)。链路:客户端 → /quote-reply/quotes → 宿主 pending → systemPrompt.context → 模型。
为什么不是「塞进输入框」
把引用塞进输入框,会和你要说的话混在一起:分不清哪句是引用、哪句是你说的,也没法统一管理。
v0.2 因此把引用做成独立一层:引用在浮窗里,你的话在输入框里,两者分开。
怎么用(v0.2)
1. 在某条回答里选中一段(或直接对着整条回答);
2. 点该回答动作行里的 「引用回复」 → 上方出现/更新 「引用(N)」浮窗,这条变成 引用一/二/…;
3. 浮窗里可以:点标题折叠/展开 · 逐条删除 · 清空 · 单条「插入」或「全部插入输入框」(临时逃生通道,发出去时就会带上)。
下一阶段(已探明可行路径,尚未做)
1. 发送时自动带上引用:需要一个专用发送按钮(如「发送并引用」)——宿主没有「发送前钩子」,所以只能这样;
2. 发送后折叠显示:引用以机器可读块随消息发出(模型能看到),你的那条消息里用样式隐去原块,在该回合尾部显示一行 「引用」(与「已完成 用时…」同款、可点开)→ 逐条列出 引用一/二/… 与内容。
为什么不直接替换 user 消息渲染器:那是 shadows-shipped-ui(会接管官方渲染、丢掉官方后续特性),风险不值得。
技术要点(改它之前先读)
- 两个槽位:conversation.input.dock(输入框上方浮窗,order 30 —— 现有占用者是 goal(10)/queue(20))与 conversation.chat.assistant-actions(每条助手消息的动作条,order 30)。
- 引用层是模块级 Map(按 sessionId 分桶):要在两个槽位之间共享,且切会话/重挂载不能丢。
暴露 __quote(add/remove/clear/list/cn)供自检直接验证行为。
- 「引用回复」按钮必须 onMouseDown: e => e.preventDefault(),否则按下会先塌陷选区、拿不到「选中那段」。
- apply 全程不抛(服务读取经 safe()、每块注册各自 guard()),失败只留一行 console.error。
自检
node _check-client.cjs :: 客户端半体真夹具:导出形状 · 两个槽位落点 · 引用层行为 · 敌意 ctx 不抛
(用假的 window.__ModuleLoader__ 与 React 桩把客户端半体在 Node 里真跑一遍;反证有效:把浮窗 order 改成 99,夹具立刻变红。)
它长什么样 / 怎么用
1. 在某条已完成的回答里选中你想回应的那段文字(拖选即可);
2. 在这条回答的动作行里点 「引用回复」(和自带的 反馈 / 跳转 按钮并排);
3. 输入框里会出现形如
你选中的那段原文
光标在下面,直接接着写你的问题就行。
没选中任何文字时,点它会整条引用该回答(并在旁边提示「未选中文字,已整条引用该回答」)——这样「就想对整条回应」的场景也是一下点击。
它不做什么(边界)
- 不自动发送:只把引用放进输入框,发不发、怎么改都由你。
- 不碰你没选的内容:引用块只含你选中的那段(超长会截断并写明「已截断,原长 N 字」)。
- 插入失败不静默丢:如果你点击的那一瞬间草稿被改动(或被别的东西占用),插入会被宿主拒绝;此时引用原样保留在按钮旁,并给一个「复制保留的引用」——绝不悄悄丢弃你的操作。
技术要点(给后来改它的人)
- 落点:客户端槽位 conversation.chat.assistant-actions("Ordered actions for one finalized assistant message", ownerProps = { messageId },standardProps 自带 inputActions)。本插件取 order = 30 (排在自带 mf#feedback(10)、dsh-context#context-jump(20) 之后)。
- 插入正门:inputActions.captureInsertion() → inputActions.insertText(text, span)。
后者仅在草稿版本未变且编辑器允许编辑时插入一次可撤销的编辑,失败返回 falsy。
- onMouseDown 必须 preventDefault():否则按下按钮会先塌陷选区,"选中一段再点"就永远拿不到那段话。
- 取文本:选区优先;无选区时按 messageId 找消息节点(试 data-message-id 等若干属性名)取正文兜底。
- 宿主半体(lib/index.js)故意为空,只保证包根可被 import ——(踩过:宿主半体里误写成 Markdown 标题 + 孤立 */,宿主直接报 failed to import,整个插件不工作。)
- apply 全程不抛:服务读取经 safe()、每块注册各自 guard(),失败只留一行 console.error,绝不把异常抛进加载器(这是 2026-10-13 一次整站白屏换来的纪律)。
安装 / 卸载
:: 安装(走官方入口;本插件纯客户端,无宿主侧行为)
dsh plugin --profile desktop add link:E:\DeepSeek\skills\quote-reply\bundle
:: 或在本仓库里用 plugin_manager 的 install_bundle(同样的官方路径)
改完客户端代码要刷新页面才生效(客户端半体是随页面下发的;而"新装一个客户端插件"必须重新加载页面)。
自检(改之前先跑)
node --check lib/index.js :: 宿主半体语法
node <本目录>\_check-client.cjs :: 客户端半体语法 + 关键点在场(槽位/插入正门/防塌陷/导出形状)预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
liuhaolong16/dsh-quote-reply
DeepSeek Harness 的引用回复层:把一段话引用到输入框上方的可编辑托盘,随下一回合作为模型上下文注入(不进消息正文),并在该回合下方显示为可展开的一行。
相关插件 · 其他
模型破甲清洗YuJunZhiXue/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 14,822已汉化DeepSeek 客户端
73
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 718已汉化DSH
71.2
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,261已汉化DSH
70.7
破甲评测WoYun520/dsh-purge
在本机分离宿主拦截与模型拒绝,做受控红队评测
★ 199已汉化DSH
69.7