dsh-at-file

438Star17Fork0Issue0Watching

为 DSH Web 端增加 Codex 风格的 `@` 文件选择器:选择路径后只向模型注入存在性引用,不读取文件内容;内置文件过滤与按工作区隔离的设置项。

机审证据安装命令仓库已核验dsh-plugin Topic许可证READMEAI 百科
语言
JavaScript
License
MIT
分支
main
dshdsh-plugin

安装

$ dsh plugin --profile web add github:omdsh-dev/dsh-at-file

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

对话式安装

帮我安装 DeepSeek Harness 插件 omdsh-dev/dsh-at-file:先查看仓库 https://github.com/omdsh-dev/dsh-at-file.git 确认安全性,然后执行安装命令并验证插件加载成功。

把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。

一句话定位

为 DeepSeek Harness 的 Web 端输入框加上 Codex 风格的 @ 文件选择器:选中或手动输入路径后,插件只把"路径 + 类型"这一行引用消息追加到模型输入,文件内容始终由 agent 用自己的工具读取,不会通过本插件泄露给模型。

核心能力

  • 在 Web 输入框敲 @ 弹出工作区文件 / 目录选择器,支持纯文本关键词匹配、按 / 分段匹配前缀与紧凑排序
  • 把选中或手输的 @path 在 agent 每轮 step 开始前校验存在性,校验通过后注入 <workspace-reference path="…" kind="file|directory" /> 这条只含路径和类型的引用消息
  • 在 Settings → File mentions 提供启用开关、Global / Workspace 两层文件名过滤规则(Exact 与 Regex,支持区分大小写)与粘贴文本策略,全部通过插件自己的 atFile/updateSettings 端点持久化
  • 选择器支持 ArrowRight 进入目录、跨 pane 文件夹浏览;点击引用栏里的路径会走 Harness 的 host.openPath 端点用系统方式打开
  • 默认索引自动跳过 .gitnode_modulesbuilddist__pycache__、Xcode / Unity / Unreal 等 60+ 个常见产物目录与 desktop.ini / Thumbs.db / .DS_Store 等系统元数据文件

技术实现

  • 语言: TypeScript(ESM);同一 package 内同时打包 host half 与 client half,client half 由 DSH web 服务器作为 /plugins/dsh-at-file/client.js 单文件下发
  • 关键依赖: zod(运行时唯一依赖,用于 wire codec 校验);@deepseek-ai/cordis(插件容器)、@deepseek-ai/dsh-typert-protocol + @deepseek-ai/dsh-typert-registry(强类型 endpoint 注册)、@deepseek-ai/dsh-agent + @deepseek-ai/dsh-llm(pre-step 钩子与 UserMessage 构造)
  • 架构模式: 双半宿主插件。host half 用 Cordis 装载 AtFileRuntime@Remote 装饰) + ctx.typert.register(TYPERT_MANIFEST) 走严格注册表声明 wire endpoint,并通过 agent/pre-step 事件在每个 agent 作用域里挂上 mentionPreStep 钩子;client half 用 ctx.remote.$mount 挂载同名 Remote、inputTriggers.registerSource 注册 @ 触发器、ctx.slots.register 注册 dock + 文件夹导航 + 设置面板 section
  • 入口文件: 宿主 src/index.ts(导出 apply / Config),客户端 src/client/index.ts(导出 apply / inject),挂载声明在 cordis.patch.yml + package.json#dsh.bundle.patch + package.json#dsh.client.inject

适用场景

当你希望让 DSH agent 操作当前工作区里的具体文件,但不希望把整个文件内容提前塞进 prompt——例如"重写 src/runtime.ts 的第 30 行附近"或"看下 docs/spec.pdf 是否覆盖异常流程"——只需在输入框里写一段带 @path 的文字,agent 就会看到一行存在性引用,再按需读取。另一个典型场景是用插件的设置页统一管理"哪些文件名不该出现在 @ 菜单里",把 *.lock / *.min.js 等干扰项在 Global 里一次性屏蔽。

前置依赖与兼容性

依赖最低版本说明
DeepSeek Harness (DSH)未声明package.json:51-66 全部 @deepseek-ai/dsh-*@deepseek-ai/cordispeerDependencies: * / ^4.0.1-rc.1,未给出最低 DSH 版本号;建议按当前 DSH 主线使用
Node.js未声明仓库没有 engines 字段,@types/node 锁在 ^24.0.0package.json:131),请按 DSH 自身要求选用
平台macOS / Windows / Linux仅使用 node:fs / node:fs/promises / node:path,无原生模块
原生模块package.json:115-117 运行时只依赖 zod,无 native binding

安装方式

dsh plugin --profile web add github:omdsh-dev/dsh-at-file

配置项

宿主侧配置(写在 ~/.dsh/profiles/web/cordis.patch.yml

配置类型说明默认值
maxIndexedFilesnumber单次工作区索引最多收录的文件 / 目录条目数;超额立即停止并返回 truncated=true5000
ignoreDirsstring[]索引时按 basename 跳过的目录;设为 [] 则索引所有目录内置 60+ 个 .git / node_modules / build

用户偏好(在 DSH 设置 → File mentions 面板里改,通过 atFile/updateSettings 持久化)

偏好类型说明默认值
启用 at-fileboolean关闭后 @ 选择器、引用栏、pre-step 注入全部停用true
忽略粘贴文本中的 @boolean关闭后从外部粘贴的 @路径 会和手输一样被识别true
Global 文件过滤Exact / Regex 规则列表所有工作区共享的 basename 过滤;旧版字符串规则会被视作不区分大小写的 Exact 规则内置 desktop.ini / Thumbs.db / .DS_Store
Workspace 文件过滤Exact / Regex 规则列表仅对当前工作区生效的附加规则,每个工作区独立保存

常见问题

Q: 粘贴进来的 @路径 会被识别吗?

A: 默认不会。客户端在粘贴时用 U+2060 不可见字符给 @ 打标记,Host 在 scanMentions 里识别到带标记的 token 就跳过;同时 Settings 里的 ignorePastedMentions 默认开启,双重保险。需要在外部复制的 @路径 上也走选择器流程,把"忽略粘贴文本中的 @"关掉即可(src/paste.ts:7 / src/mention.ts:42-55)。

Q: 插件会把文件内容发送给模型吗?

A: 不会。mentionPreStep 只做两件事:在用户消息里扫 @path、对每个 token 走 stat 确认存在并判定文件还是目录,然后把 <workspace-reference path="…" kind="…" /> 这一行追加到 prompt。文件字节从不进入 wire、从不离开 Host;模型要读文件,靠的是当前 agent 会话里挂的 read / read_image 等工具(src/mention.ts:1-8)。

Q: 我能引用工作区之外的文件吗?

A: 不能。resolveMentionpath.relative(cwd, absolute) 判定越界:.. 或以 .. 开头的结果一律丢弃;isAbsolute(token) 也直接拒掉。手输一个 /etc/passwd 这样的绝对路径,结果就是 prompt 里看到一段普通的 @/etc/passwd 文字,不会被转成引用(src/mention.ts:64-81)。

Q: 选择器里怎么过滤文件?

A: 打开 Settings → File mentions:Global 列表是所有工作区共享的基底,Workspace 列表是当前工作区的附加规则;每条规则独立选 Exact / Regex 与是否区分大小写,Regex 写错保存前会被前端拒绝,Host 的 schema 也会再次拒绝(src/contract.ts:66-79 / README.md:60-66)。

Q: 大工作区索引会不会卡?

A: indexWorkspaceopendir 流式逐条读取(不一次性 readdir),不跟随 symlink,命中 maxIndexedFiles 立刻停并把 truncated 标志置位。默认 5000 上限 + 30 秒 session 缓存已经够大多数项目;超大仓库可在 cordis.patch.yml 里把上限调到 10000 以上(src/files.ts:99-158)。

Q: PDF 怎么办?

A: 选择器把 PDF 当成普通路径条目;模型是否能读 PDF 取决于当前会话的 agent 工具集——DSH 提供 read 处理 UTF-8 文本、read_image 处理支持的图片,PDF / Word 等需要会话里挂对应工具,插件自身不读取文件内容(README.md:98)。

Q: 怎么升级?

A: 重跑同一条 dsh plugin --profile web add … 命令,然后重启 dsh web;lib/ 已提交到仓库,profile 安装无需触发构建脚本(README.md:46-49)。

Q: 缓存什么时候清?

A: 客户端按 session 缓存 30 秒(INDEX_TTL_MS),Host 端按 cwd 缓存;过滤规则变化或连接 reset 会立刻清缓存(src/client/source.ts:34 / src/client/index.ts:157-161)。

上手难度

入门 — 单条 dsh plugin add + 硬刷新浏览器即可使用;进阶在于按团队习惯在 Settings 里维护 Global / Workspace 过滤规则,以及在 cordis.patch.yml 里调 maxIndexedFiles 上限。

已知问题与限制

  • 索引条目数硬上限:maxIndexedFiles 默认 5000,超额立刻停止并返回 truncated=true;超限之外的合法路径需要手输才会被引用(src/files.ts:124-128 / src/index.ts:52)
  • 符号链接一律跳过:walk 不跟随 symlinked 目录,避免链接循环;软链文件本身也不入索引(src/files.ts:130-133)
  • 默认排除目录覆盖广:60+ 个内置 basename 包含主流 IDE、构建工具、依赖缓存的产物目录;如需索引 node_modules 等,必须把 ignoreDirs 显式设为 [](src/defaults.ts:4-65)
  • @path token 不允许包含空白或另一个 @/@[^\s@]+/g 决定边界,超长路径或带空格的 Windows 短名不会被自动识别(src/mention.ts:34)
  • 粘贴文本默认不识别:复制自其他应用的 @路径 不会出现选择器,需要在设置里关掉"忽略粘贴文本中的 @"(src/paste.ts:7 / README.md:25)
  • 文件读取完全依赖 agent 工具:插件不读取文件,也不保证 PDF / Office 等格式有处理能力,需要会话自带对应工具(README.md:98)
  • 节点 / DSH 版本未在 package.json 声明:engines 字段缺失,DSH 的所有 @deepseek-ai/* peerDependencies 走 *,需自己保证 DSH 与之兼容(package.json:51-66)

收录徽章

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-at-file)

把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。

返回插件目录