Skip to content

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(就是 @文件 那种 原子节点)已经注册在编辑器里:

  1. editor.getEditorState().toJSON() 拿到当前 draft;
  2. 在最后一个 paragraph 末尾补一个节点 { type: "reference-chip", source: "reference", ref, label, clipboardText };
  3. 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 实例)