DeepSeek Harness plugin

dsh-input-file-ref

输入框文件引用插件:在 DeepSeek Harness Web GUI 输入框里像 Kimicode/Cursor 那样,输入『@』弹出可搜索、可逐级下钻的文件选择面板,选中后把『@相对路径 』回填进输入框(保留 @、末尾一个空格),让模型按路径读取该文件。

Jump to install

Source facts

Repository
AFAP/dsh-input-file-ref
Latest update
Aug 16, 2026
Category
Tools & Capabilities
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/AFAP/dsh-input-file-ref
Plugin: dsh-input-file-ref
Author: AFAP

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer3 files
README.mdSource · read only

输入框文件引用插件 · Input File Reference

<div align="center"> <b>中文</b> · <a href="README.en.md">English</a> </div>

> 在会话输入框输入 @,像 Kimicode / Claude Code / Cursor 一样弹出当前工作目录的文件选择面板,选中后把 @相对路径 回填进输入框,模型即可按路径读取该文件内容。 > 为 DeepSeek Harness Web GUI 输入框新增一个"文件"@ 引用源:可搜索、可逐级下钻、与输入框同宽的选择面板,回填保留 @ 并自带末尾空格(自动停止再次触发选择)。

![License: MIT](LICENSE)

---

1. 它解决了什么问题

dsh 输入框已有 @ 触发管线(dsh-client-ui-input-trigger),但只支持技能(skill)和子代理(subagent)两类引用源。想引用工作目录里的某个文件时,没有对应的 @ 源。

本插件新增一个可搜索、可逐级下钻的文件选择面板替换默认窄菜单,数据由宿主半部提供:

dsh-input-file-ref (node half, lib/index.js — 零外部依赖,仅 node 内置)
  GET /api/input-file-list?sessionId=…&dir=<rel>     — 浏览模式:单层列目录
  GET /api/input-file-list?sessionId=…&query=<text>  — 搜索模式:递归 + 排除忽略目录
    ├─ 定位会话日志($DSH_HOME/sessions 目录树)
    ├─ 读日志首条 session 记录 → 得到会话 cwd(绝不信任客户端传来的路径)
    └─ 目录/文件相对路径 + 大小 + mtime(不读取文件内容)
          │
          ▼  (浏览器 fetch,同源)
  文件选择面板 (client half, conversation.input.overlay) ── 顶部搜索栏 + 逐级下钻
    ├─ 与输入框同宽;默认只列 50 条,输入更多关键字显示更多
    ├─ 文件夹可一级级进入(含 .git / node_modules / target;搜索会排除它们)
    └─ 选中 → 保留 @ 并回填全路径(末尾一空格)──发送──► 模型读取该文件

只读:本插件不修改任何文件。宿主半部只读取会话日志头部与文件系统元信息(路径/大小/mtime),不读、不写、不删除任何文件内容。

2. 功能特性

  • ✅ 输入 @ 弹出与输入框同宽的选择面板,顶部带搜索栏。
  • ✅ 顶部搜索栏:输入关键字即时递归搜索文件(大小写不敏感子串匹配;继续输入显示更多结果)。
  • 逐级下钻文件夹:点文件夹一层层进入;.gitnode_modulestarget 等目录支持一级级往下选,但不出现在搜索结果里(性能更好)。
  • ✅ 文件行显示相对全路径,过长时中间用 省略
  • ✅ 默认只展示 50 条;输入更多关键字后逐步放宽到 100 / 200 / 500,减轻展示压力。
  • ✅ 键盘(↑/↓/Enter/Esc)与鼠标均可选择。
  • ✅ 选中后,保留 @ 并把文件相对全路径以普通文本回填到输入框(末尾一个空格,示例 @src/main.ts ,可直接编辑、删除、连续引用多个文件)。末尾空格让 @ 不再触发选择,可继续正常输入。
  • ✅ 发送后,消息中带有所引用的相对路径文本,模型可用自己的 fs 工具读取(沙箱以会话 cwd 为根)。
  • ✅ 未选择工作目录的会话:面板显示提示,不崩溃。
  • ✅ 与现有 @ 技能/子代理引用共存。
  • ✅ 中英双语界面文案,跟随界面语言。
  • ✅ 只读、零外部依赖、浏览器信任围栏(防 DNS 重绑定 / 跨站)。

MVP 暂不支持:不内联文件内容到消息;不做文件预览/语法高亮;不做多选批量。

效果预览

快速筛选文件(搜索 + 50 条上限,输入更多显示更多)选中文件回填(@相对路径 保留 @ + 末尾空格)
![快速筛选文件](screenshot/picker-filter.png)![选中文件回填](screenshot/picker-backfill.png)

3. 目录结构

dsh-input-file-ref/           # 仓库根 = npm 包根
├── package.json              # dsh.bundle.patch + dsh.client(浏览器端声明)+ exports["./client"]
├── cordis.patch.yml          # 组合行:inject webRuntime + trustedHosts 配置
├── LICENSE                   # MIT
├── .gitignore
└── lib/
    ├── index.js              # 宿主半部:/api/input-file-list(浏览 dir / 搜索 query)+ cwd 解析(零依赖)
    └── client.js             # 浏览器 bundle:'@' 文件源 + 自定义文件选择面板(insert + codec 路径)

4. 快速开始

一键安装(GitHub):

dsh plugin --profile web add github:AFAP/dsh-input-file-ref

然后重启 dsh web 生效。

> 安装后插件位于 $DSH_HOME\profiles\web\node_modules\dsh-input-file-ref(pnpm 从 GitHub 克隆),与源码仓库位置无关。

升级:

dsh plugin --profile web update dsh-input-file-ref

卸载:

dsh plugin --profile web remove dsh-input-file-ref

从源码目录手动安装(等价验证用)

dsh plugin --profile web add "D:\path\to\dsh-input-file-ref"

验证是否加载成功

新建/打开一个已选定工作目录的会话 → 在输入框输入 @ → 出现"文件"分组的文件列表即可。

5. 使用

1. 选定工作目录:会话需要有工作目录(cwd)。 2. 在输入框输入 @ → 弹出与输入框同宽的文件选择面板。 3. 顶层 = 浏览当前目录:直接看到当前目录的文件与子文件夹;点文件夹可逐级进入(.gitnode_modulestarget 等也会显示,可一级级往下选)。 4. 顶部搜索栏(也可直接在输入框 @ 后继续输入):输入关键字即时递归搜索整个 cwd;默认只显示 50 条,多输入几个字符会显示更多(逐步放宽到 100 / 200 / 500)。 5. 返回上级:当前进入某文件夹时,列表顶部有"↑ 上级目录",或按 Backspace 返回。 6. 用 ↑/↓ + Enter(或鼠标点击 📄 文件行)选择文件 → 保留 @ 并把文件相对全路径以普通文本回填进输入框(末尾一个空格),例如 @src/main.ts 。 7. 发送后,消息中带有所引用的相对路径,模型可用 fs 工具按该路径读取内容。 8. 删除/修改:回填的是普通文本,直接当作普通文字编辑或删除即可;末尾空格会让 @ 停止触发选择;可连续引用多个文件(每次输入空格 + @ 重新打开选择)。

未选择工作目录的会话:输入 @ 时面板显示"当前会话没有工作目录"提示,不会崩溃。搜索时 .gitnode_modulestarget 等目录里的文件不会出现(但可以逐级进入选择)。

6. API 速查

# 浏览模式:列出 dir(子路径,""=cwd)下的单层目录与文件
GET /api/input-file-list?sessionId=<sessionId>[&dir=<relative-dir>]

# 搜索模式:递归搜索整个 cwd(排除 .git/node_modules/target 等忽略目录)
GET /api/input-file-list?sessionId=<sessionId>...&query=<text>
  • 需要浏览器信任围栏通过(loopback / trustedHosts + 同源校验),否则 403
  • 非法/未知 sessionId 返回 404(错误,而非任意路径内容)。
  • 缺失 sessionId 返回 400
  • 非法 dir(含 ..、绝对路径、反斜杠、盘符)返回 400;目录不存在返回 404

浏览模式响应示例(dir=src):

{
  "mode": "browse",
  "cwd": "D:/workspace/MyProject",
  "dir": "src",
  "noCwd": false,
  "truncated": false,
  "dirs": ["util"],
  "files": [{ "path": "src/main.ts", "size": 2384, "mtime": 1719300000000 }]
}

搜索模式响应示例(query=main):

{
  "mode": "search",
  "cwd": "D:/workspace/MyProject",
  "noCwd": false,
  "truncated": false,
  "files": [{ "path": "src/main.ts", "size": 2384, "mtime": 1719300000000 }]
}

无工作目录的会话:

{ "noCwd": true, "files": [] }

7. 配置项

默认值说明
trustedHosts来自 webRuntime(loopback + LAN + --trusted-host浏览器信任围栏的非回环授权主机列表。
ignore.gitnode_modulestarget.venv 等(见下)搜索模式下跳过的目录名列表(浏览下钻仍可进入)。默认忽略 .gitnode_modules.venvvenv__pycache__.next.nuxtdistbuildtarget.idea.vscode.DS_Store

> ignore 可在组合层覆盖:在 cordis.patch.ymlconfig 下追加即可(默认已内置,通常无需改动)。

8. 日志与排错

现象排查方向
输入 @ 无反应或无文件面板确认 dsh web 已重启、插件是否加载;技能/子代理的 @ 分组是否仍在(共存正常)。
面板一直"正在加载…"打开开发者工具 Network,检查 /api/input-file-list 状态;403=信任围栏拦截、404=会话未找到。
面板提示"当前会话没有工作目录"该会话未设置 cwd;请先选择工作目录。
搜索结果不全 / 找不到某些文件它们可能在 .git/node_modules/target 等忽略目录里;请用浏览模式一级级进入选择。
只显示了 50 条这是默认上限;输入更多关键字即可显示更多结果。

9. 安全与合规(务必阅读)

  • 只读:本插件不修改、不删除任何文件;宿主只读取会话日志头部与文件系统元信息,不读取文件内容。
  • 路径红线:cwd 由会话持久化头部解析(会话创建时的绝对路径),绝不信任客户端传来的任意路径sessionId 在拼路径前做单段转义,杜绝目录穿越。
  • 浏览器信任围栏/api/input-file-list 仅接受 loopback 或声明 trustedHosts 的同源请求,拒绝 sec-fetch-site: cross-site 与 Origin 不同的请求,防 DNS 重绑定与跨站。
  • 信息最小化:仅返回相对路径、文件名、大小、mtime;不返回绝对路径,不返回文件内容。
  • 会话定位仅限本机:文件列表只服务本机会话日志,不对外暴露任意目录浏览能力。
  • repo 不携带私密信息:无密钥、无本机绝对路径(文档用占位符 <your-project>)。

10. FAQ

  • Q:插件会读取文件内容吗? A:不会。宿主只列元信息;选中的相对路径以文本回填,模型在收到后用自己的 fs 工具读取内容(沙箱以会话 cwd 为根)。
  • Q:可以引用多个文件吗? A:可以。重复打开 @ 面板选择,每次回填一个保留 @ 的相对路径(末尾一空格),可连续引用多个。
  • Q:搜索时找不到 .gitnode_modulestarget 里的文件? A:这些忽略目录默认不进搜索结果(性能考虑)。请在浏览模式下点击文件夹一层层进入,即可看到并选中它们里面的文件。

11. 开发与构建

纯 JS 无构建步骤(无需 GitHub Actions workflow)。分层:

  • lib/index.js:宿主半部,零外部依赖(仅 node: 内置),因此无论以 git / registry / file: / link: 哪种方式安装都不会出现模块解析失败。
  • lib/client.js:浏览器 bundle(经典脚本,window.__ModuleLoader__.load),注册 @ 文件引用源 + 自定义文件选择面板(conversation.input.overlay)。

12. 相关文档

  • 输入框引用契约:@deepseek-ai/dsh-client-ui-input-trigger/lib/types/types.d.ts
  • 参照实现:技能 /@deepseek-ai/dsh-client-ui-skill、子代理 @@deepseek-ai/dsh-client-ui-subagent、exact 路由范例 dsh-token-usage

13. License

MIT © AFAP