# DSH 附件插件使用指南 ## 1. 安装 不需要 dshx。默认走官方 `dsh`: ```sh dsh plugin --profile web add github:aa2246740/dsh-dragndrop-attachments ``` 然后重启这个 DSH Host,刷新页面。输入框保持 DSH 原样;点击原生 `+`,菜单里同时出现原命令和“文件和文件夹”,即安装成功。 ## 2. 添加附件 以下三种入口等价: - 从 Finder 把一个或多个文件、文件夹或混合内容拖到 DSH 页面任意位置;页面会出现“拖到这里,自动处理图片、文件和文件夹”。 - 复制文件或截图,在输入框附近直接粘贴。 - 点击输入框左下角 DSH 原生 `+`,选择“文件和文件夹”,再选择“选择文件”或“选择文件夹”;它和命令共用同一菜单。 非图片文件会显示卡片、大小、状态、预览和移除按钮。图片会进入 DSH 原生图片缩略图区域。大图被自动缩放时会显示绿色提示,例如 `4096×3072→1823×1367`。 文件夹是提交时刻的不可变快照,不会继续读取 Finder 的实时路径。卡片显示文件夹名、文件数和目录数;模型以 `read_folder_entry` 读取文本/代码,或以 `query_folder_document` 按相对路径查询其中的 DOCX、XLSX、PPTX、CSV。支持的拖放/现代目录选择会保留空目录;旧 `webkitdirectory` 兜底会明确提示空目录无法报告。 Finder 拖进网页后,浏览器只提供文件名、类型、大小和字节,不会把原始绝对路径暴露给网页。这是浏览器安全边界,不是附件丢失。插件会立即建立唯一 `attachment_id` 并保存受控快照;模型先调用 `list_attachments`,再用 `read_attachment` 读取该 ID,不需要也不允许到工作区猜同名文件。 ## 3. 最有效的提问方式 通常直接说需求即可。需要可审计结果时,可明确要求模型调用附件工具并返回定位符。 Word: ```text 请搜索附件里的“北京分行”,读取命中的完整表格,并在答案中给出文件名和语义路径。 ``` Excel: ```text 请读取“汇总”工作表 A1:D20,列出公式、已保存值和没有缓存结果的公式单元格。 ``` PowerPoint: ```text 请逐页概括这个 PPT,并同时检查演讲者备注;每条结论标明页码。 ``` CSV: ```text 请读取 CSV 的 A1:F100,确认引号字段中的逗号和换行没有被拆列。 ``` Markdown/代码: ```text 先用 read_attachment 读取这个附件,再搜索“认证失败”,只读取命中位置附近的行并给出行号。 ``` ZIP: ```text 请先列出 ZIP 目录,再搜索“认证失败”;用准确条目路径读取命中代码的 1-120 行,并给出 ZIP 内路径和行号。 ``` 文件夹: ```text 请先列出“经营材料”文件夹目录,再搜索“认证失败”;读取 docs/README.md 的命中行,并查询 reports/月报.xlsx 的 汇总!A1:F20。 ``` ## 4. 草稿、移除和会话恢复 - 尚未发送:点击卡片“移除”会同时删除草稿引用和当前会话中的未提交引用。 - 已发送:卡片与该条用户消息绑定,对话中紧随其后显示可展开的 `📎` 附件上下文回执;页面刷新后模型仍可通过 `list_attachments` 找到。 - 发送失败:没有持久用户消息就不会消费卡片,附件仍留在输入区等待重试。 - 不同会话:引用表按 DSH session id 隔离;其他会话不能用附件 ID 越权读取。 - 相同文件:底层字节按 SHA-256 去重,但每一次选择都有独立附件 ID、卡片、显示名和消息绑定,不会互相覆盖。 - 相同文件夹快照:底层快照可复用;每一次拖入仍是独立卡片,即使根名和内容都完全相同。 - 当前轮优先:发送时生成的回执包含精确附件 ID;这一轮的 `list_attachments` 不会混入旧轮附件。下一条没有附件的用户消息会正常恢复会话级清单。 ## 5. 常见错误 | 提示 | 处理 | | --- | --- | | 不支持的附件类型 | 改用支持格式;`.doc/.xls/.ppt` 请另存为现代 Office 格式 | | 文件扩展名与内容不一致 | 用原应用重新保存,避免只改扩展名 | | 文档损坏 | 在 Office 中打开并“另存为”后重试 | | 文档已加密 | 先移除打开密码或保护 | | 单文件超过 50 MiB | 拆分文件;图片通常不受此非图片上限影响,但仍受浏览器可解码内存约束 | | 会话超过 20 个或 1 GiB | 分到新会话,或先移除未提交附件 | | 文本编码不支持 | 普通文本保存为 UTF-8;CSV 也支持 GB18030 | | Office 解析超时/资源上限 | 拆分工作簿、文档或演示文稿;超大数据优先使用 CSV | | ZIP 路径不安全/压缩比或解压总量超限 | 重新打包,移除 `..`/绝对路径和异常高压缩条目;必要时拆成多个 ZIP | | ZIP 条目不是可读文本 | 模型仍可看到目录和大小;请单独上传需要解析的 Office/图片/二进制文件 | | 文件夹快照目录与声明不一致 | 重新拖放该文件夹;不要手工修改传输中的内容 | ## 6. 安装排障 - `+` 菜单没有“文件和文件夹”:确认已 `dsh plugin --profile web add github:aa2246740/dsh-dragndrop-attachments`,然后重启 Host 并刷新页面。输入框上方不应再有独立附件按钮。 - 提示重复 Loader id:profile 里不要再留一份 `cordis.patch.yml` 的 `dsh-dragndrop-attachments` 行,也不要同时用 bundle 和 patch 挂两份。 - OfficeCLI 校验失败:不要继续运行未知二进制,重新取得完整发布包并核对 SHA-256。 ## 7. 数据位置 默认目录: ```text ~/.dsh/dragndrop-attachments/v1/ sessions/ # 按会话哈希保存引用 store/v1/ # 内容寻址对象与解析索引 archives/ # ZIP 内容寻址原文件 tmp/uploads/ # 上传中的临时分块,提交或取消后清理 ``` 早期私有预览版使用 `~/.dsh/codex-attachments/v1`。新插件发现该目录且新目录尚不存在时会继续读取旧存储;这是有意保留的数据兼容行为。 可在 Cordis 插件配置中设置 `dataDir` 或 `officeCliPath`。修改存储位置前先备份旧目录;不要在两个正在运行的 Host 之间共享同一个可写数据目录。 ## 8. 验收清单 - 拖入大于 2000 px 的图片,看到自动优化提示和原生图片缩略图;发送后模型能描述图片。 - 拖入 DOCX,模型能用 `search_attachment` + `read_document_path` 返回表格及语义路径。 - 拖入 XLSX,模型能用 `read_spreadsheet_range` 返回公式状态。 - 拖入 PPTX,模型能用 `read_slide` 返回正文和备注。 - 拖入带引号换行的 CSV,字段不被拆坏。 - 拖入 ZIP,模型能用 `get_attachment_outline` 看目录、`search_attachment` 跨文本搜索、`read_archive_entry` 按准确路径和行范围读取;路径穿越/压缩炸弹样本被拒绝。 - 拖入含空目录、Markdown、DOCX、XLSX、PPTX、CSV 的文件夹,确认卡片没有 `.zip` 名称;模型能以文件夹相对路径检索文本与 Office 内容。 - 发送附件后刷新页面,再问一次附件内容,模型仍能读取。 - 在含有无关项目文件的工作区拖入 Markdown,只输入“看看有啥值得优化的地方”;确认对话出现对应 `📎` 回执,模型先调用附件工具且回答引用该 Markdown,而不是扫描其他项目。 - 同时拖入两个 Markdown,再逐个拖入两个 Markdown;每次都确认卡片数量完整,发送后回执与 `list_attachments` 返回相同数量和文件名。 - 把两个同名但内容不同的 Markdown 拖入同一轮;确认 `read_attachment` 按两个不同 ID 返回各自内容,且没有 `block_0` 错误。 - 在附件轮要求分析文件;确认日志中没有用 `bash/find/grep/read_file` 搜索附件名或 `/Users`、`/tmp` 等广域路径。 - Harness 仓库执行 `git status --porcelain=v1 --untracked-files=no` 没有插件造成的 tracked diff。