# dsh-copy-document-preview 给 DeepSeek Harness 右侧边栏的**文档预览**加一个「一键复制」按钮。 官方预览标题栏只有路径、渲染器选择、换行开关和 Reload,没有任何把文档「拿出来」的动作。 这个插件在那一排加一个按钮:点一下,当前预览文件的文本就进剪贴板了。 [English](README.md) | 中文 ## 行为 - **文档预览标题栏里的复制按钮**,排在预览自带控件之后、官方「在本地打开」之后。 - **复制整个文件**,不是只复制预览已加载的那几页:插件走 harness 自己的分页文件 Remote(`remote.workspaceFiles.read`)——和预览本身用的是同一个读取器——不绕过拥有该文件的 Session。 - **二进制文件改为复制路径**:PDF、图片、Office 文档这类文件 Host 会回 `workspace-file/not-text`,此时按钮复制该文件的绝对路径并明确提示,而不是静默失败。 - **反馈清楚**:复制成功后显示两秒 ✓,失败显示 ⚠ 和具体原因,二者都会被读屏软件播报。 - **文本文件复制的是源文本**:Markdown、纯文本、代码复制的是原文,不含预览里的行号。 | 预览类型 | 进剪贴板的内容 | |---|---| | 纯文本、Markdown、代码、日志 | 文件全文 | | CSV / TSV / JSON / YAML | 文件全文 | | PDF、图片、Office(`.docx` / `.xlsx` / `.pptx`)、zip、二进制 | 文件绝对路径 | ## 安装 从 npm 仓库: ```sh dsh plugin --profile web add dsh-copy-document-preview ``` 直接从 GitHub: ```sh dsh plugin --profile web add github:shellpower96/dsh-copy-document-preview ``` 机器上没有 GitHub SSH key 时,用同一个仓库的 HTTPS 形式: ```sh dsh plugin --profile web add https://github.com/shellpower96/dsh-copy-document-preview.git#main ``` 然后重启 `dsh web`。也可以在 Plugin Market 或 Plugin Manager 里安装,会一并启用这个 bundle。 卸载: ```sh dsh plugin --profile web remove dsh-copy-document-preview ``` ## 实现 无构建步骤、无运行时依赖。浏览器半边只在文档标题栏的**增量 list 槽位** (`sidebar.right.tab.document.actions`)注册一个条目——这个槽位只追加,不替换任何官方控件。 - 槽位把文件的 `absolutePath` 交给条目;Session id、locale 函数和标准 hooks 由槽位运行时提供。 - 读取走 `remote.workspaceFiles.read(sessionId, path, { offset }, signal)`,与预览同一个 Remote, 因此沿用预览 Session 自己的权限,以及 Host 的字节/行数上限。 - 浏览器半边不 import 任何 Harness Client 包;样式只用宿主的 `--dsw-alias-*` 主题变量(自动跟随明暗主题); 所有可见文案走 client locale 服务(中英文)。 - 不在组件之外写任何 DOM,插件只拥有那一个按钮。 ## 已知边界 - 剪贴板写入用 `navigator.clipboard`,要求页面是安全上下文(`https://` 或 `http://127.0.0.1`)且处于聚焦状态, 没有 `execCommand('copy')` 降级路径。 - 超过 Host 单页上限(`maxLines`、`maxBytes`)的文件会带上 Host 自己的 `too-large` 错误; 超过 200 页的文件同样失败。 - 二进制文件只能复制路径,插件不做文本抽取。 ## 许可 MIT