🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

划词引用 Eos010/dsh-selection-ask

DeepSeek Harness
Eos01024 天前有提交已提供中文文档扫描:未发现敏感能力

选中网页文字写批注,生成带编号引用胶囊

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/12 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Eos010/dsh-selection-ask
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/11/04·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 24 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

发起外部网络请求
查看扫描证据(共 2 处,展示前 2 条)
  • 发起网络请求
    lib/client.js:107
    fetch(ENDPOINT, {
  • 发起网络请求
    ask-panel.js:100
    fetch(ENDPOINT, {
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 选中文本写批注
  • 生成带编号引用胶囊
  • 原文高亮标编号

README

由 DeepSeek 最新模型翻译生成
dsh-selection-ask · 划词提问 给 DeepSeek Harness(DSH)网页版用的划词引用插件。 在对话里选中一段文字 → 就地写批注 → 它变成带编号的引用胶囊落进输入框,原文上同时留下高亮和编号;删掉胶囊,高亮和编号一起走。 选中之后(那片底色是插件自己接管的,不是浏览器的原生选区): 选中后的就地输入栏 回车提交之后(原文上有高亮 + 右上角编号,输入框里有胶囊): 引用进去之后的原文标注 深色宿主下同一套控件(配色走宿主 design token,插件不自己判主题): 深色主题 它解决什么 读 AI 的长回答时,你经常想指着其中某一句话追问: "这里为什么这么写?" / "展开讲讲第三点" / "这句翻译成中文是什么?" 没有这个插件,你得手动选中 → Ctrl+C → 点输入框 → Ctrl+V → 再打字;而且粘进去的是一段没有形状的裸文本,模型分不清哪句是你说的、哪句是你引的。 有了它,引用是一步动作,而且引用是有身份的:每一条引用有编号,原文上有对应的高亮与编号牌,悬停胶囊能看回原文。模型收到的仍然是 markdown 引用块: 一句话对照:上面那串"往下压"是递,撞到出口后"往回收"是归——两个动作合起来才叫递归。
展开完整文档(README 剩余 1 节)
dsh-selection-ask · 划词提问

给 DeepSeek Harness(DSH)网页版用的划词引用插件。
在对话里选中一段文字 → 就地写批注 → 它变成带编号的引用胶囊落进输入框,原文上同时留下高亮和编号;删掉胶囊,高亮和编号一起走。

选中之后(那片底色是插件自己接管的,不是浏览器的原生选区):

选中后的就地输入栏

回车提交之后(原文上有高亮 + 右上角编号,输入框里有胶囊):

引用进去之后的原文标注

深色宿主下同一套控件(配色走宿主 design token,插件不自己判主题):

深色主题

它解决什么

读 AI 的长回答时,你经常想指着其中某一句话追问:

"这里为什么这么写?" / "展开讲讲第三点" / "这句翻译成中文是什么?"

没有这个插件,你得手动选中 → Ctrl+C → 点输入框 → Ctrl+V → 再打字;而且粘进去的是一段没有形状的裸文本,模型分不清哪句是你说的、哪句是你引的。

有了它,引用是一步动作,而且引用是有身份的:每一条引用有编号,原文上有对应的高亮与编号牌,悬停胶囊能看回原文。模型收到的仍然是 markdown 引用块:

一句话对照:上面那串"往下压"是递,撞到出口后"往回收"是归——两个动作合起来才叫递归。

(这里接着写你的问题,光标已经在这了)

一次引用的生命周期

唯一事实源是"输入框里的胶囊" —— 只有一套状态说了算,三个地方才不会各说各话:

胶囊在 → 原文的高亮在、编号在胶囊没了 → 原文的高亮走、编号走还没提交 → 那片选区由插件高亮接管(你永远看不到自己的选区凭空消失)

这就是为什么删掉输入框里的胶囊,原文上的高亮和编号会跟着一起消失 ——它们不是三份各自独立的记录,而是同一件事的三种呈现。

用法

1. 在网页里选中一段文字 —— AI 的回答、你自己发过的话、工具输出、代码块,哪都行;
2. 光标旁浮出一条就地输入栏 —— 就地写批注,或者什么都不写;
3. Enter 写进输入框 / Ctrl(macOS 上 Cmd)+ Enter 写进输入框并直接发送。

| 动作 | 结果 |
| 选中正文 | 浮出就地输入栏;同时那片文字的底色不会消失(换成插件的同族高亮) |
| 就地输入栏里按 Enter | 写进输入框,不发送 —— 你还能接着改、接着补 |
| 就地输入栏里按 Ctrl/Cmd + Enter | 写进输入框并立刻发出去 |
| 写批注后提交 | 输入框里是 [胶囊] 你的批注(胶囊在前) |
| 悬停胶囊 | 浮出这条引用的原文 |
| 在输入框里删掉胶囊 | 原文的高亮与编号同时消失 |
| 点别处 / 按 Esc | 收起浮层,不动输入框 |
| 在输入框里选中文字 | 不出浮层 —— 那是在编辑,不是在引用 |
| 连续引用多段 | 每段各成一块,追加而不是覆盖 |
| 选中的内容超过 8000 字 | 截断,并提示「内容过长,已截断」 |

编号的粒度:一个页面生命周期内全局递增(选中文本 1、2、3…);同一段文字被再次引用时复用原来的编号(同一处标注不该有两个号)。

已知边界(说清楚,免得踩空)

1. 同一段文字在转录里出现多次时,高亮取第一处。 锚定方式是"按原文文字找回来" (不存字符偏移 —— 转录是 React 按会话日志重渲染的,偏移一定会漂)。
2. 引用的原文必须落在单个文本节点内(跨元素的选区锚不到)。
3. 转录虚拟化时,滚出屏幕的那段暂时不亮,滚回来就恢复。这是这套锚定方式的边界,不是 bug。
4. 高亮依赖浏览器的 CSS Custom Highlight API(Chromium 105+;DSH 桌面版与 dsh web 都是 Chromium,实测可用)。不支持时高亮与编号静默缺席,但引用本身照常工作,并在控制台留一条告警。
5. ⚠ 侧边提问(未完成,封存中):浮层上那个「侧边提问」按钮能开出右侧栏面板、能把选中的那段带进去,但面板里的发送按钮收不到真实鼠标点击(已定位到原因:面板内 pointerdown 被 preventDefault + click 在冒泡到 React 根容器之前被拦,修法已写进 项目档案)。所以它现在发不出问题,默认别用它。
6. 热更新不可靠:改完产物请刷新页面(Ctrl+F5)再看效果 —— HMR 在这台机器上实测不稳定(页面手里的 combo rev 会 404)。

安装

⚠️ 先纠一个坑(不少插件文档在这里是错的):DSH 的 CLI 会直接拒绝 --profile desktop ——

$ dsh plugin --profile desktop add github:Eos010/dsh-selection-ask
error: profile "desktop" is managed exclusively by the Electron application

桌面版的 profile 由 Electron 应用独占管理。所以按你实际在用的版本二选一:

桌面版(Electron 应用)

在 DSH 应用内安装。也可以手动两步(下面这套是实测跑通过的):

1) 把仓库放进 profile 的 node_modules
git clone https://github.com/Eos010/dsh-selection-ask
"$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-selection-ask"

2) 在 ~/.dsh/profiles/desktop/package.json 的 dsh.profile.bundles 数组里加一行: "dsh-selection-ask"

3) 重启 DSH,然后刷新网页(Ctrl+F5)

命令行版 dsh web

npm i -g pnpm # dsh plugin 是 pnpm 的转发器,PATH 上得先有 pnpm
dsh plugin --profile web add github:Eos010/dsh-selection-ask

(从本地工作副本装,就把 github:… 换成 file:<你的工作副本路径>。)

两种方式装完都要重启一次 DSH,然后刷新网页(Ctrl+F5)。
为什么必须重启这一次:安装会把本包登记进 profile 的 dsh.profile.bundles,而那个清单只在启动时读一次。

卸载就是反过来:从 dsh.profile.bundles 删掉那一行、删掉 node_modules 下的目录,重启。

怎么实现的

两半结构

index.mjs 宿主半边:一个流式问答端点(+ 两道安全门) client.js 浏览器半边:全部交互(源码) ask-panel.js 浏览器半边:侧边提问面板(源码,与 client.js 拼进同一个 bundle) selection-ask.css 全部样式 build.mjs ask-panel.js + client.js + CSS → lib/client.js(产物已提交) lib/client.js 构建产物,宿主真正加载的就是它

宿主半边不声明任何 inject 服务。这是刻意的:DSH 的插件是宿主 Cordis 树上的一个 entry,客户端半边由这个 entry 带出来 —— 所以纯 UI 插件也得有 node 半边;但声明一个拿不到的服务会让 fiber 停在 PENDING,启动器的 assertEntriesActivated 会因此 丢掉整棵插件树。少声明一个,就少一条把宿主搞挂的路。

为什么挂在 conversation.input.right 这个插槽上

要把字写进输入框,只有一条正路:DSH 公开的输入动作。而它只作为会话作用域插槽的标准属性发给插槽组件。所以本插件在输入框工具行里占一格,那一格本身只画一个 display:none 的锚点 —— 它的意义有两件:拿到 inputActions / useInput,以及用锚点反查输入框编辑器(从锚点往上走,第一个包含 contenteditable 的祖先)。
不写死任何宿主类名。

锚点还有第三个用途:数输入框里现在还剩几个胶囊 —— 这是「引用的生命周期」的判据(见上)。判据与悬停预览取 label 的方式逐字相同,两处判据不一致会出现「悬停能看原文、但高亮判定说这个胶囊不存在」这种自相矛盾的行为。

引用胶囊:借的是官方机制

DSH 的输入框是 Lexical,@文件 / @对话 插进去的就是原子引用胶囊。本插件注册一个
自己的引用源,codec.serialize(ref) 决定发送时这条引用展开成什么文本 ——
所以胶囊只是显示形态变了,模型收到的仍然是 > 引用原文。

三个踩出来的硬知识(都在 项目档案 里有完整记录):

- ctx.emit 没有返回值,要用 ctx.bail。输入机的四个事件声明是 @mode bail;用 emit 的返回值判成败 ⇒ 明明插进去了却判成失败 ⇒ 兜底的全文替换再把刚插好的胶囊抹掉。表象是「胶囊永远不出现」。
- InputState.draft 是剪贴板投影,不是编辑坐标。胶囊在编辑坐标里几乎不占位,在投影里占一大段。拿前者的长度去定位后者,永远定位不到。
- 插入位置不能只算一个,要「候选逐个试、让返回值挑」。投影与坐标换算并不总是对得上:一旦对不上,唯一的候选会被拒,第二次引用就静默失败(兜底又因为「草稿里已有胶囊」拒绝写入,用户看到的是「点了没反应」)。所以有胶囊时还会补一层小整数阶梯(胶囊数+1 … 0,降序)—— 实测追加位置总落在这个范围里。

原文高亮与编号

- 高亮走浏览器原生的 CSS Custom Highlight API(CSS.highlights + Highlight,实测色值:待定态 rgb(212,212,213)、已标注 rgb(193,193,194),都是宿主 brand token 按 18% / 26% 混出来的)—— 一个字节的 DOM 都不改,所以 React 重渲染冲不掉它。
(插 再靠 MutationObserver 重挂,在流式输出的转录里会一直和 React 打架。)
- 编号牌放在我们自己的浮层里,按 Range 位置贴上去,不插进正文;找不到就什么都不做,异常全吞 —— 绝不允许因为标注失败连累引用本身。
- 待定高亮是必须的:就地输入栏一出现就自动聚焦,而「聚焦一个 input」会让浏览器 当场清掉文档选区 —— 松手之后那片蓝色就没了,看起来就是「选完就消失」。
所以我们用自己的高亮接管那一片:同族色、比「已标注」浅一档,视觉上是 换了个颜色,不是消失。它用的是活的 DOM Range,只在浮层开着时存在。

什么时候不出浮层

- 选区落在可编辑区(含输入框自己)、input / textarea / select 里 —— 那是在编辑;
- 选区落在我们自己画的浮层里 —— 避免自引用套娃;
- 页面上有模态对话框开着 —— 模态框走浏览器 top layer,盖在所有 z-index 之上,让它出现就只是「看得见、点不着」,比不出现更糟。

主键还按着就不出浮层(拖拽事故的教训)

症状:鼠标按住拖,根本选不中字,一拖就断。
根因:选区一变成非空就触发 selectionchange,浮层立刻弹出来并自动聚焦输入栏;而「聚焦一个 input」会让浏览器当场结束这次拖拽并清掉选区。
为什么端到端全绿也没抓到:Input.dispatchMouseEvent 的拖拽是一瞬间派发完的,浮层还来不及插进去 —— 真人手速比测试慢,慢就会被自己的浮层打断。
修法三条:主键按着时什么都不做、键盘选出来的选区不抢焦点、焦点在自己 DOM 里时不因「空选区」而收起。量具也改了:24 步、每步隔一帧的慢速拖拽成了常驻断言。

开发

只需要 Node ≥ 22。运行时零依赖 —— React / react-dom 从 DSH 的平台模块表里取
(require("react")),不打包、不重复引入第二份 React。

node build.mjs # 源码 + CSS → lib/client.js
node test/bundle.test.mjs # 15 项:产物接线、插槽注册、样式落点、失败不抛
node test/selection.test.mjs # 36 项:引用块形状、草稿拼接、生命周期、浮层落位

lib/client.js 是提交进仓库的构建产物:装插件的人不该被迫先跑一次构建。
build.mjs 同时是一道闸门 —— 它会把产物反过来校验一遍(占位符恰好出现一次、内嵌 CSS 与 .css 文件逐字节一致、构建期间源码未被改写),任何"改了源码忘了重新构建" 都会当场报错。

端到端验收(真浏览器)

单元测试碰不到 DOM 与真实鼠标事件,所以另有一套 CDP 驱动的验收:它派发真实的鼠标事件序列,读真实的 DOM 与真实的 CSS.highlights 来判定。

1) 起一个独立的测试实例(不要拿你正在用的那个)
dsh web --port 3099 --no-open

2) 起一个开了远程调试的 Chrome,打开实例打印出来的那个带 token 的 URL
chrome --headless=new --remote-debugging-port=9223 \
--user-data-dir=<临时目录> "http://127.0.0.1:3099/?token=…"

3) 跑验收(需要在页面上打开一个有内容的会话)
node test/e2e/selection-ask.e2e.mjs --cdp-port 9223 --app-url http://127.0.0.1:3099

顺带产出 README 用的截图(深浅各跑一遍)
node test/e2e/selection-ask.e2e.mjs --cdp-port 9223 --app-url http://127.0.0.1:3099 \
--shots docs/images --theme dark

43 条断言,其中几条只有真浏览器抓得到:

- 浮层中心点 elementFromPoint 命中自己(没被别的层盖住)、pointer-events 没有被继承成穿透;
- 24 步慢速拖拽中途不出浮层、选区不归零,松手后才出浮层;
- 三个状态的真实高亮:选中时待定高亮 size === 1、提交后归 0 且标注高亮为 1、 删掉胶囊后标注高亮与编号牌一起归 0;
- 直发:Ctrl+Enter 之后输入框被清空、那条消息出现在正文里;
- 整轮下来没有未捕获异常 —— 这条是量具的保险丝:只在事件回调里抛的 ReferenceError,页面看着一切正常,坏的只是那一个动作。

⚠️ 跑一次 E2E 会真的向模型发一条很短的请求(验"直发"和"侧边提问"两条路径)。
它用的是你在测试实例里配的模型,注意额度。

装进正在运行的那份(免重启)

profile 的 cordis.patch.yml 是被实时监视的(patchReload: live):

1) 把包挂进 profile 的 node_modules(目录联接,改工作区源码就是改运行中的那份) New-Item -ItemType Junction -Path "$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-selection-ask" -Target "<你的工作副本路径>"

2) 往 profile 的 cordis.patch.yml 末尾追加:
- insert:
- id: selection-ask
name: dsh-selection-ask

改完源码跑一次 node build.mjs,然后刷新页面(Ctrl+F5)。
(dsh-client-hmr 会每 500ms 轮询 bundle 的 mtime/size,但它在本机实测不稳定 ——页面手里的 combo rev 可能已经过期,表现为 bundle 404。刷新才是可靠路径,所以这里不承诺热更新。)

数据与隐私

- 浏览器半边不联网:不读文件、不读凭据、不读会话内容,只做三件事 ——读当前选区、调用宿主公开的输入动作、往 document.body 挂浮层。
- ⚠ 宿主半边有一个 HTTP 端点:POST /plugins/dsh-selection-ask/ask (「侧边提问」用)。它把问题转给你已配好的模型并流式吐回浏览器 ——也就是说,它花的是你的额度。
DSH 的 cookie 鉴权只保护没被命名路由接管的请求,所以插件自己加了两道门: Host 必须是 IP 字面量或 localhost(挡 DNS rebinding)+ 带 Origin 就必须同源(挡跨站)。实测:无 Origin 200 / 同源 200 / 跨站 403 / Host 是域名 403。
- 没有配置项,也就没有配置文件。

路线

- 修掉侧边提问面板里的发送按钮(原因已定位,见「已知边界」第 5 条)——等要做的时候从那里接着走。
- 引用块可带来源标注(摘自哪条消息 / 哪个文件第几行)。
- 快捷键:选中之后直接按键引用,不经过浮层。
- 高亮的三个已知边界(见上)不打算改:这套锚定方式选的就是"稳定能用"。

许可

MIT。见 LICENSE。
预览分享卡片长什么样 ↓Eos010/dsh-selection-ask
分享 · DeepSeek Harness Hub
Eos010/dsh-selection-ask

选中网页文字写批注,生成带编号引用胶囊

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部