# dsh-file-mention — 文件路径引用 DSH(DeepSeek Harness)Web GUI 插件:在输入框里用 `@`(或 `/file` 命令)模糊搜索 会话工作区(cwd)下的文件路径,pick 后插入 `@相对路径` 引用随消息发出。 Agent 自带本地文件工具,按路径自行读取或操作(查、改、测试、移动)—— **不把文件内容灌进上下文**(引用自读语义,与内容注入型插件不同)。 ## 用法 **@ 内联触发**(推荐): 1. 输入 `@` 即弹出工作区**浅层条目**菜单(开头或空格后输入 `@` 触发, 与 TUI 惯例一致);继续输入路径片段(如 `@src/butt`)自然过滤; 2. 候选菜单「file」分组列出匹配的**文件与目录**(最多 20 条,带路径副标题); 3. 键盘选中后按 **Enter 或 Tab 补全**当前高亮项(鼠标点击同样生效)。 补全遵循文件系统惯例:文件补全为 `@file `(空格结束);目录补全为 `@dir/`——**确认空目录**才补空格结束,**有子内容(或未确认)则不加空格**, 光标停在斜杠后继续输入子路径浏览;想提前结束目录浏览,手动输一个 空格即可(token 遇空白断开)。 **/file 命令**(`@` 触发异常的备用入口): 1. 输入 `/file` 后**直接接路径片段**(如 `/fileAGENTS`,无空格——harness 的 trigger 检测在 token 含空格时失效); 2. pick 后同样插入 `@相对路径 `。 示例:`请修复 @src/main.go 里的空指针` → agent 按 `src/main.go` 定位并操作。 ## 功能特性 - **附件条 dock**:composer 上方实时显示 draft 中所有 `@路径` 引用 (📁/📄 图标 + 去重),`×` 精确删除该引用(引用自读语义下点击打开由 agent 按路径自行完成); - **引用装饰(lexicon)**:纯单词形态的文件名(如 `LICENSE`/`Makefile`)在被 引用时由管线高亮装饰,与其他引用(技能/命令)同视觉;含 `.`/`/` 的路径 引用受管线 token 语法(`[@/][\w-]+`)限制不参与装饰(官方机制,如实降级); - **空查询浅层菜单**:只输入 `@` 也弹出工作区顶层条目(BFS 遍历天然浅层 优先),无需先想路径片段; - **warm 预热**:打开会话即后台预热该工作区的索引(官方 warm 钩子),输入 `@` 时几乎零延迟弹菜单(命中服务端 30s 缓存),无 1.5s 首查等待; - **搜索排名**:子序列模糊匹配(打错中间字母也能命中)+ basename 命中加权 + 浅层优先(深度轻微惩罚);同等匹配质量下目录略优先; - **目录候选**:目录与文件同列(📁/📄 图标区分),pick 目录插入 `@dir/ ` 尾斜杠引用;目录按"是否有子内容"决定补全后是否自动加空格(空目录加, 有子内容不加、允许继续浏览); - **延迟策略**:服务端 BFS 遍历 + 30s 内存缓存 + 快照文件兜底 (`~/.dsh/storages/file-mention/.json`)+ 1.5s 预算部分返回 + 启动 3s 预暖;打字连发即时命中缓存; - **新文件秒级可见**:缓存命中时比对该 root 的 mtime——缓存建立后有增删 立即重扫(创建/删除文件无需等 30s 窗口); - **fetch 不互相 abort**:击键产生的过时信号只丢弃对应结果,在途请求继续 存活(避免打字快于首查时菜单永远收不到结果); - **目录副标题**:候选行显示条目所在目录(ui-input-trigger 管线原生渲染)。 ## 配置(环境变量,均可选) | 变量 | 默认 | 说明 | |---|---|---| | `FILE_MENTION_ALLOWED_ROOTS` | 不启用 | 逗号分隔的允许搜索根目录(绝对路径)。**设置后才启用白名单**,白名单外的 root 返回 400;不设置则放行(与 `host.listDirectory` 的浏览暴露面一致) | | `FILE_MENTION_IGNORE_DIRS` | 内置剪枝表 | 追加剪枝目录 basename,逗号分隔 | | `FILE_MENTION_MAX_FILES` | `600000` | 单次遍历收集文件数上限 | ## 安装 ```sh dsh plugin --profile web add github:Seryta/dsh-file-mention ``` 安装后重启 `dsh web` 并刷新页面。纯手写 JS,零构建、零第三方依赖。 ## 与同类插件的差异 | 项目 | 发送时行为 | 本插件的取舍 | |---|---|---| | [dsh-at-file](https://github.com/omdsh-dev/dsh-at-file) | 内容注入(host 在 pre-step 读文件并注入 `` 内容) | 本插件只插路径引用、agent 用工具自读:省 token、agent 可操作文件、host 不读文件内容;代价是模型需自行决定读哪些文件 | | [dsh-wikilink](https://github.com/zhaoscsc/dsh-wikilink) | `[[wikilink]]` 笔记内容注入 | 场景不同(笔记 vs 文件路径) | ## 已知限制 - 符号链接不跟随;不返回文件大小。 - token 语法与 harness 触发检测一致:引用路径不能含空格(含空格的文件名 无法通过输入完整路径选中)。 - 插入的是路径引用而非文件内容——agent 需要读文件时会自己调 read 工具 (这也是"操作文件"的必需信息)。超大/二进制文件不在菜单里做任何预览。 - 端点 `GET /plugins/dsh-file-mention/api/search?root=&q=&limit=` 仅暴露 路径列表(不读内容),与现有目录选择器的信息暴露面一致。 ## License MIT