dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DSH WebUI 文件输入增强:Ctrl+V 粘贴(带首次告知弹窗)+ 拖拽 + 选择文件,发送时复制进会话工作区临时目录
简体中文 | English
DSH WebUI 文件输入增强插件:Ctrl+V 粘贴 + 全页面拖拽 + 选择文件/文件夹,发送时复制进会话工作区临时附件目录,并把对话气泡里的附件文本块折叠为文件 chip。
派生自 dsh-external/dsh-multimedia-webui-input(MIT),在其基础上新增剪贴板粘贴输入、首次告知弹窗与气泡附件折叠。
你的 DSH 版本决定装哪个插件版本(装错会崩:常见症状 useConversation is not a function)- DSH 0.1.2-alpha.1 ~ 0.2.1-alpha.1:装新版(下方默认命令;各 DSH 版本对应的插件 tag 见下方变更记录)
- 更旧的 DSH(0.1.1-rc.2 及以前):无可用版本
安装方式(v0.2.10 起自动挂载):本包自 v0.2.10 起自带cordis.patch.yml并声明dsh.bundle.patch——dsh plugin --profile web add安装后自动注册 profile 层并挂载,不再需要手写insert配置行(固定旧 tag 的部署仍需)。GUI 注意:插件页「添加插件」只接受注册表包名或本地目录路径;name@github:owner/repo#tag是 pnpm 别名规格(CLI 专用),粘进 GUI 会报ERR_PNPM_INVALID_PACKAGE_NAME——GUI 请克隆后用本地目录路径,或等 npm 发布后用包名。
# 方式一:git 依赖固定 tag(公开镜像,推荐;也可用 github:lhh010/dsh-paste-input)
dsh plugin --profile web add '@dsh-community/dsh-paste-input@github:lhh010/dsh-paste-input#v0.2.14'
# 方式二:本地 link
# dsh plugin --profile web add link:/path/to/dsh-paste-input并在 ~/.dsh/profiles/web/cordis.patch.yml 追加(热重载,无需重启):
- insert:
- id: dsh-paste-input
name: '@dsh-community/dsh-paste-input'安装提示:pnpm 11 首次安装可能拦截 node-pty 等构建脚本——在~/.dsh/profiles/web下执行pnpm approve-builds --all放行后重跑安装命令;装完硬刷新浏览器(Ctrl/Cmd+Shift+R)。
更新浮标会结合当前运行的 DSH 版本(宿主端从 dsh 安装清单读取)与仓库根的 compatibility.json(版本→支持的 DSH 列表,精确匹配)判定提示形态:
兼容数据拉取失败或无该版本条目时,自动回退为旧的普通升级提示(离线安全)。发版时需同步维护 `compatibility.json`(与版本表/变更记录同一步骤新增一行)。
ctx.sessions 在桌面端插件侧为空,改用 ctx.get('workspaceRegistry') 按 sessionIds→workspace.path 服务端解析 cwd(无客户端路径输入,不破坏原安全模型);② 上传传输——桌面转发层破坏二进制 PUT body(Content-Length 与实际字节不符),桌面端改走 base64 JSON 通道(POST /batches//files//base64),web 端保留二进制快路径。实机验证:桌面端粘贴→copied→发送成功,文件落盘 ✓。同时移除 v0.2.4/0.2.5 的“桌面端不可用”弹窗(已过时),保留 live-session-not-found toast 作为回归安全网。node --check 通过node --check 通过add() 在 draft 末尾无空格时调用 input.setDraft() 追加空格——但 setDraft 替换整个 draft 文本并销毁所有 chip 的 occurrence 绑定。用户粘贴 3 张图后打字(draft 末尾非空格),再粘贴第 4 张时 setDraft 先行清除了前 3 张的 occurrences,订阅判定 alive=false,records 被清理——发送时模型只看到最后一张(磁盘证据:batch 目录只有 paste_image(4).png)。setDraft 尾部空格调用(美观不值得销毁 occurrence 绑定);另为未提交 record 加 150ms vanishTimer 宽限期作为纵深防御。node --check 通过。node --check 通过node --check 通过node --check 通过node --check 通过/file 端点验证(要求真实发送目录的 owner marker 与文件清单声明),伪造/手打的 marker 块不再被折叠成官方样式的文件 chip,防止以假附件文本误导模型或阅读者add(sessionId, …) 的 sessionId 未定义(拖拽会以 toast 报错),改为 current.sessionIdnode --check 通过/dsh-paste-input/v1/latest 端点返回当前 DSH 版本;客户端更新判定结合 compatibility.json——最新版不支持当前 DSH 时显示琥珀色「需更高 DSH 版本」提示,支持中间版本时提示中间版node --check 通过适配 dsh 0.1.6-alpha.2 多实例重构:当前会话改由 uiSession.current({ key, ctx })解析(alpha.1 的 sessions.list.current 字段已移除,此前导致粘贴/拖拽/附件按钮全部弹「请先打开一个会话」);粘贴、拖拽、附件按钮三条路径均已切换,alpha.1 回退保留。lib node --check 全绿,alpha.2 实机验证 chips 恢复显示。
声明支持 dsh-v0.1.6-alpha.1(npm 已发布,钉版本实机验证;client 插件面零代码差异,lib node --check 全绿,实机加载正常)。安装命令统一更新为 #v0.2.14。
==== END DSH_PASTE_INPUT ==== 与旧缓存 bundle 写入的 ==== END DSH_PASTE_INPUT_V1 ====),解析器只认后者之外的现行格式导致旧消息折叠失败并刷 Console 警告;现兼容两种拼写。注:V1 结尾拼写为历史遗留(仅极早期 bundle 写入),后续版本可能不再兼容,依赖旧格式折叠的历史消息请尽快升级fs-ext 安装修复,client 插件面零代码差异;npm 已发布,钉版本实机验证;同步 lib 内烙死的 PLUGIN_VERSION 常量(避免幻影自更新)ctx.agent 移除 / 宿主 client bundle 服务路由改 /plugins/?? 组合路由,client 插件面零代码差异;npm 已发布,钉版本实机验证,无需代码改动;启动清单确认加载sessionStorage——页面刷新后,输入框里残留的粘贴引用 chip 仍可正常发送(此前会报 "Attachment selection is no longer available in this browser tab")。+/-/0/Esc 快捷键、工具栏含缩放百分比/重置/复制完整路径/关闭;GIF 在查看器中持续播放GET /dsh-paste-input/v1/file?root=&path=:仅服务所有权标记(`.dsh-paste-input.json`)声明过的图片文件(SVG 除外,避免同域脚本执行),路径解析约束在发送目录内,单文件 ≤64 MiBbusy 变量,chip 一渲染即 ReferenceError,整个 dock 槽位被错误边界吞掉(表现:dock 上的附件气泡消失);已移除该悬空引用conversation.input.left 槽位不提供 owner props(无 input),props.input.phase 读取 undefined 崩溃(Console 报 Cannot read properties of undefined (reading 'phase'),槽位条目被框架错误边界捕获)。改用可选链 + 'plain' 默认值(add() 自身有 phase 守卫不会误操作)。dock 槽位的 occurrences 同样加防御api.github.com(未认证限流 ~60 req/hr → 403)改为 data.jsdelivr.com/v1/packages/gh/(CDN,无限流,CORS 友好)dsh --version 确认本地 DSH 版本,对照 README「版本兼容」表选对应 tag,不匹配则改装)与第 3 步(安装失败/版本不匹配/启动报错先查 README「版本兼容」「已知限制」章节);原两步安装流程不变[attachment: …] 文本),而 consumeToken 的 span 校验在 detect 投影坐标(chip 仅占 1 个 U+FFFC 字符)下工作——旧代码直接把 clipboard 坐标传入导致替换必然失败,record 却已删除:dock chip 显示 unavailable、输入框 chip 残留。现按「前面每个 chip 缩短 length−1」精确换算成 detect 坐标再调用 consumeToken,失败时回退 setDraft 整段切除insertReference 的插入点原来取 snapshot.draft.length(clipboard 投影长度),第一个附件存在后插入点越界 → The DSH composer changed before the attachment could be inserted。现同样按存活 chip 折算成 detect 坐标,多个附件可连续粘贴共存paste_image.、其他文件 paste_file.(扩展名优先取原文件名,缺省按 MIME 补全);重名自动追加 (2)、(3)… 序号(以 composer 实时 chips + records 为冲突集),改名同步进上传路径。仅粘贴路径改名,拖拽与文件/文件夹选择保留原始文件名paste_image.png 与 paste_image(2).png 共存;dock × 删除上下同步;node --check 通过0.1.1-rc.1 实机 boot 验证通过——boot 清单包含本插件、client.js 返回 200;0.1.4 的 rc.8 适配(consumeToken 整段删除、appearance: 'file' 官方外观、内联 chip 整体编辑保护)在 0.1.1-rc.1 上行为无回归(所依赖的 inputTriggers.registerSource、conversation.input.for 门面与 conversation.input.left/dock、settings.section 槽位均保持不变)@ + label 的完整行内区间(不再是 1 个占位符字符),v0.1.3 点击 dock chip 的 × 只删掉 @ 一个字符,输入框内残留附件文本。现改用 rc.8 官方删除动词 input.consumeToken(span CAS 整段切除),旧宿主回退为按 occurrence.length 切除📎 emoji 前缀与 8 字符截断(在 rc.8 上渲染为「蓝色 @ + 回形针 + 蓝色文件名」),label 改为纯文件名并附带官方 appearance: 'file',与官方 @file 引用的内联 chip 外观一致;完整路径与大小仍显示在输入框上方的 dock chip 中beforeinput,任何只触碰 chip 一部分的编辑(在 label 中间打字、退格删一个字符、选半截替换)都被阻止并把选区扩展到整个 chip(下一次按键即整体删除/替换);已完整选中整个 chip 的删除/替换放行。守卫通过 textarea.value === draft 识别 composer,不影响队列编辑等其他输入框;dock 的 × 按钮仍走 consumeToken 整段删除0.1.0-rc.8 实机验证——粘贴/拖拽 → dock chip → × 删除后输入框同步清空;发送 → 复制进附件目录 → 气泡折叠 chip 全链路可用