dsh-pick
Verified@yechayo/dsh-pick · v0.1.0 · MIT · Web UI
Pick an element in the DSH sidebar browser, or drag a region over a PDF preview, and drop the screenshot plus its DOM/text into the composer as a chip.
Install
dsh plugin add @yechayo/dsh-pick Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Creators
Readme
dsh-pick
把 Codex 那种「点哪问哪」搬进 DSH:侧栏浏览器里点一个元素、或者 PDF 预览里拖一个框,截图 + 上下文直接进输入框。
它做了什么
| 场景 | 交互 | 送进对话的东西 |
|---|---|---|
侧栏浏览器(Desktop 的 <webview>) |
点浮层按钮 → 页面进入拾取态,鼠标划过高亮元素,点一下(Esc 取消) | ①一枚胶囊 @ a.title-content ②元素区域截图(+6px padding)③element-<tag>.<class>-<时间戳>.html 附件(完整 outerHTML + 选择器 + 页面) |
| 侧栏 PDF 预览 | 点浮层按钮 → 在 PDF 上拖一个框(Esc 取消) | ①一枚胶囊 @ PDF 选区 ②框选区域截图(2x,直接从 PDF.js 的 canvas 取像素) |
输入框里只有一枚短胶囊 + 两张小卡片,跟 Codex 选元素后的观感一致。胶囊上的字很短(div.s-isindex-wrap),
真正发给模型的是它背后的 ref:
[元素]div.s-isindex-wrap(class="s-isindex-wrap s-hotsearch-wrapper …")
页面:百度一下,你就知道 — https://www.baidu.com/
截图与快照走一次真实的 paste 事件(DataTransfer{ image/png + text/html } → ClipboardEvent('paste')),
composer 自己的 intake 接手,附件栏、上传、缩略图、发送和手动粘贴完全一样。
胶囊是怎么塞进去的
composer 没有公开的「插入引用」API,但 draft 本身就是一棵 Lexical 树,而 reference-chip(就是 @文件 那种
原子节点)已经注册在编辑器里:
editor.getEditorState().toJSON()拿到当前 draft;- 在最后一个 paragraph 末尾补一个节点
{ type: "reference-chip", source: "reference", ref, label, clipboardText }; editor.parseEditorState(json)→editor.setEditorState(next)。
source 用内置的 reference:它的 codec 会把 ref 原样交给模型,所以胶囊显示短标签、线上发完整上下文。
插入失败(编辑器结构变了、节点没注册)会自动退回「粘贴一行文本」,不会让动作失败。
为什么不需要改 app.asar
<webview>元素自带executeJavaScript()与capturePage(),渲染进程直接可用,主进程不用开新 IPC;- PDF 预览是渲染在应用页面自己的 canvas 里的(
[data-pdf-preview]/[data-pdf-page]),drawImage直接取像素; - 图片进 composer 走剪贴板粘贴,不用
addFiles之类的内部通道; - 胶囊靠 Lexical 的
toJSON/parseEditorState/setEditorState这三个公开方法塞进去,不碰内部节点类。
边界(重要)
- 只在 Desktop 生效:Web 版右侧栏是跨域沙箱 iframe,拿不到被浏览页的 DOM,也没有截图能力。PDF 框选这条在 Web 版同样可用。
- 点选只到「当前页面里的元素」,不处理页面内部的 iframe 穿透。
- 截图走
capturePage,取决于 Electron 版本与页面是否可捕获;失败会在 Toast 里说明。 - 按钮是只有图标的小方块(26×26,hover 才出浅底,原生 title 提示功能),位置在浏览器工具栏里地址框右侧、「在浏览器中打开」左侧;PDF 则是预览头部右侧。不浮在页面上、不挡内容。
- 再点一次 = 取消:拾取/框选进行中按钮变成强调色、aria-label 变「取消拾取」,点它或按 Esc 都会取消,不会卡在拾取态。
安装
推荐:Plugins 页面 —— 打开 插件 → Discover,找到 @yechayo/dsh-pick 安装。需要先配置一个插件市场索引源。
命令行:
dsh plugin --profile desktop add @yechayo/dsh-pick
包自带 cordis.patch.yml bundle 层,安装后 launcher 会自动插入条目,不用手改补丁。
本地开发:
.\install.ps1 -Register # 同步到 %USERPROFILE%\.dsh\profiles\desktop 并注册 loader 条目
然后刷新一次应用窗口(Ctrl+R):新增的 loader 条目不会被 client HMR 自动加载。
验证
node test\verify.mjs
离线 harness(test/harness.html)在无头 Chrome 里跑 47 条断言:按钮挂载与落点、只有图标、进行中可取消、
captureElement 的取整/加边、胶囊节点写进 Lexical state 的字段、没有编辑器时的文本回退、拾取脚本的真实点击 / Esc / 取消钩子、
PDF 区域合成的尺寸与像素、框内文字提取。
真机验证(可选):起一个临时 profile 的 dsh web,把 bundle 装进去,node test\live.mjs <带 token 的 URL>
会真的调 captureElement → deliver,然后断言输入框里出现 [data-composer-chip] 并截图。
文件
| 文件 | 作用 |
|---|---|
lib/client.js |
全部逻辑:拾取脚本、capturePage、PDF 合成、胶囊插入、粘贴投递、浮层按钮 |
lib/index.js |
Host 半边(空插件,只为让 loader 有条目) |
test/harness.html |
离线测试台(假 webview + 假 Lexical + 真 canvas) |
test/verify.mjs |
CDP 跑 harness 并打印断言 |
test/live.mjs |
真机端到端(需要手动起一个 dsh web 实例) |