前言¶
DeepSeek Harness(DSH)的输入框每次按键都要重算整篇投影并持久化草稿。当草稿达到几十万字时,界面会明显卡顿,严重时直接拖死。这种设计对短文本没问题,但长文本粘贴进来后,正文会与用户消息混在一起,既拖累性能,又难以定位边界。
DSH 的客户端打包在 app.asar 里,修改 core 需要改动 ElectronAsarIntegrity 哈希并重签,下一个版本就会被覆盖。因此,长文本折叠需要走插件层已有的公开通道,而不是改 core。下面介绍的就是这样一个插件:把长文本从草稿里搬走,折叠成可展开的胶囊,既减少持久化体积,又保留完整正文。
插件定位¶
- 名称:zengxiaolou/dsh-paste-chip
- 维护者:zengxiaolou
- 分类:客户端
- 核心价值:在 DSH 中将长粘贴折叠成可展开的胶囊,悬停/点击查看正文与上下文,发送时按原位展开,并接管标注浏览器、划词注释等插件写入的长文本。
核心功能¶
折叠规则¶
- 粘贴阈值:≥400 字符 或 ≥12 行 时,折叠成一张胶囊。
- 外部渠道(标注浏览器、划词注释等):不看长度,一律成胶囊。
- 单段正文上限:20 万字符;超过直接拒绝并提示改用附件(超长正文进模型上下文没有意义)。
胶囊显示与操作¶
- 胶囊显示格式:
粘贴「会议纪要:本周三…」· 1.2k 字(英文Pasted「…」· 1.2k chars)。 - 正文前缀会显示在标签中,方便区分同字数的胶囊。
- 支持整块删除、整块撤销。
- 发送时胶囊展开回完整正文;正文找不到时明确拦住发送,绝不把标签当正文发出去。
交互方式¶
- 悬停胶囊:停留 180ms 显示浮层,离开 60ms 收起。
- 点击胶囊:打开常驻预览,可点「复制全文」;右上角 ✕ / Esc / 点击外部可关闭。
- 工具行「粘贴 N」:列出每条粘贴(标签 + 失效标记),键盘 Tab 可达,点条目打开常驻预览。
悬停预览内容¶
- 显示「粘贴文本 · 12k 字 · 前 320 字」+ 正文开头。
- 提供上下文行:
…上一句结尾 40 字 ▍此处 下一句开头 40 字…。
安装与启用¶
插件以本地目录方式装进 profile。请将路径换成你自己的:
- 打开
~/.dsh/profiles/<profile>/package.json,在dependencies中添加:
"dsh-paste-chip": "link:/path/to/dsh-paste-chip"
- 在同一个
package.json的dsh.profile.bundles数组末尾添加:
"dsh-paste-chip"
- 在
~/.dsh/profiles/<profile>/cordis.patch.yml末尾添加:
- id: dsh-paste-chip
- 进入 profile 目录运行
pnpm install(需要 Node ≥22.13)。 - 重启 DSH 客户端。
插件通过 dsh.profile.bundles 顺序加载,cordis.patch.yml 提供配置与注入点。
可配置项¶
全部阈值均可配置,支持两种方式:
方式 A:cordis.patch.yml¶
- id: dsh-paste-chip
config:
collapseChars: 600 # 粘贴折叠阈值(字符)
collapseLines: 15 # 粘贴折叠阈值(行)
previewChars: 500 # 悬停预览多少字
方式 B:设置页¶
安装 @deepseek-ai/dsh-settings 后,设置页会自动出现「dsh-paste-chip」分区。
| 键 | 默认 | 范围 | 作用 |
|---|---|---|---|
collapseChars |
400 | 100–10000 | 粘贴折叠阈值(字符) |
collapseLines |
12 | 3–200 | 粘贴折叠阈值(行) |
maxChars |
200000 | 1000–2000000 | 单段正文上限,超过拒绝 |
externalMinChars |
8 | 1–200 | 外部渠道插入的兜底长度,低于它视为手打 |
warmupMs |
1200 | 0–10000 | 挂载后预热窗口,期间不接管 |
inputGraceMs |
500 | 0–3000 | 用户输入后的宽限期 |
previewChars |
320 | 80–2000 | 悬停浮层预览字数 |
contextChars |
40 | 0–200 | 悬停浮层上下文各取多少字(0 = 关闭) |
hoverDelayMs |
180 | 0–1000 | 悬停多久弹出预览 |
leaveGraceMs |
60 | 0–1000 | 移出后多久收起 |
storeMaxEntries |
12 | 1–100 | 正文最多存几条,超出淘汰最旧 |
storeMaxBytes |
2097152 | 64KB–8MB | 正文存储总字节上限 |
主动接法(可选)¶
默认采用被动接法:任何插件用 setDraft / insertText 写入长文本,差异观察器会自动识别并折叠。若需要更精确控制(原子插入、草稿里已有胶囊、不想晚一帧),可在会话槽组件中调用:
const span = props.inputActions.captureInsertion()
const result = ctx.pasteChip.insert(body, { sessionId, span, label: '注释 · 3 条' })
// result: { ok: true, ref, label } | { ok: false, reason }
失败原因包括:empty、too-long(超 20 万字)、span-required(没给 span)、no-session(会话 actx 解析不到)、bail-refused(插入被拒,正文已清理)。
预览开关事件(v0.1.22)¶
const off = ctx.get('pasteChip').watchPreview((event) => {
// { phase: 'pin', ref }
// { phase: 'unpin', ref, reason: 'close' | 'dismiss' | 'switch' | 'removed' }
})
reason 含义:
| reason | 动作 | 联动方一般该做什么 |
|---|---|---|
close |
点了卡片右上角的 ✕ | 唯一的「用户主动关闭」,可据此取消对应动作 |
dismiss |
Esc / 点浮层外部 | 收起预览而已,不要当成取消 |
switch |
点了另一枚胶囊,预览换过去 | 旧的那条只是被替换 |
removed |
外部插件调了 closePreview(ref) |
胶囊已消失,卡片收起 |
ctx.pasteChip.closePreview(ref):只收指定 ref 的常驻预览,返回 false 表示不是当前预览。
适用场景与注意¶
- 适合在 DSH 中频繁粘贴长文本、需要查看上下文后再发送的场景。
- 插件以当前 DSH 进程权限运行,安装前应检查源码与许可证。
- 插件本身不提供按条删除胶囊的 API,托盘是查看器而非草稿对象。
结语¶
这个插件通过折叠长粘贴、独立存储正文、悬停/点击查看上下文,在保持完整性的同时减轻了草稿持久化的负担,让输入框保持轻量。如需了解更多或反馈问题,可访问插件目录页与 GitHub 仓库。