DeepSeek Harness plugin

dsh-file-mention

Codex-style @file/@folder mentions for the DSH web composer: workspace file/folder picker menu, plain-text colored mention tokens via the platform lexicon scan, and a nested-git-aware file index.

Jump to install

Source facts

Repository
sunshaobei/dsh-file-mention
Latest update
Aug 18, 2026
Category
UI Enhancements
GitHub stars
0

Install

Start with a prompt that asks an agent to read the 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 read the page and repository first.

Do not install anything yet. Read this DeepSeek Harness plugin and explain what it does, which files, networks, or credentials it can access, and how to install and remove it.

Plugin page: https://deepseekplugins.org/plugins/sunshaobei/dsh-file-mention
GitHub: https://github.com/sunshaobei/dsh-file-mention
Plugin: dsh-file-mention
Author: sunshaobei
Install command: dsh plugin --profile web add github:sunshaobei/dsh-file-mention

Do not run the install command until I confirm.

Check the source files

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

File explorer2 files
README.mdSource · read only

dsh-file-mention

Codex 式 @ 文件引用,DeepSeek Harness (DSH) Web 插件。

三个能力,全部挂在官方扩展点上,不改动 DSH 任何内置包。输入框的 ↑/↓ 输入历史 已拆分为独立插件 [dsh-input-history](../dsh-input-history)(发送落库 localStorage 全局环、同步召回),本插件不再包含历史逻辑:

功能说明
@ 文件/文件夹提及输入框敲 @ 弹出工作区文件与文件夹菜单(git 索引优先、嵌套 git 仓库递归展开、fzf 风格模糊过滤);菜单行显示文件名/文件夹名主标题(文件夹带 /)+ 全路径小字副标题,宽度与输入框一致;选中插入纯文本 @token 相对路径 ——token 整体着色(无胶囊宽度上限),路径明文随行,模型零搜索直达文件;文件夹引用注入 kind="directory"
token/胶囊点击预览点击输入框内的着色 token 或会话气泡里的灰色胶囊,直接在右侧 better-sidebar 编辑器打开该文件预览(未安装时回退系统默认打开方式);pick 的 token 精确解析,手输 token 在 stem 唯一时也可解析
菜单样式覆盖注入一段 scoped CSS(:has([data-source="file"])),只影响文件组菜单:满宽 + 两行布局;其他 trigger 菜单(斜杠命令、子代理)保持内建尺寸

安装

dsh plugin --profile web add /path/to/dsh-file-mention

dsh.bundle.patch 声明会让 CLI 自动把本包追加进 profile 的 bundles(宿主半随之挂载)。然后重启 DSH 桌面应用并刷新页面。零运行时依赖,无 peer / 构建要求。

卸载:dsh plugin --profile web remove dsh-file-mention

开发迭代:改完代码运行 scripts/deploy.sh(同步 lib 到 profile 安装目录)后重启。

架构

┌ composer (ui-conversation, 不改) ─────────────────────────────┐
│ @ 触发 → inputTriggers 管线 → 本插件 source "file"            │
│   candidates: host files.index + dirs 合并模糊评分              │
│               行 = name(文件名/文件夹名,文件夹带 /)           │
│                    + description(全路径副标题)                 │
│   onPick    → insert-text → "@token rel/path "(无占位/无胶囊)│
│   lexicon   → 文件 + 文件夹全部可着色 token → 平台 scanTextRefs │
│   subscribeLexicon → 索引落定后通知管线重扫(着色及时生效)    │
│   发送      → 草稿即文本,chip-free 跳过序列化直落 sink       │
│ token/胶囊点击(捕获)→ pick 登记 / 唯一 stem 反解 → 绝对路径   │
│   → betterSidebar.openFile → 回退 workspaces.openPath          │
│ 菜单 CSS    → :has([data-source="file"]) 满宽 + 两行行布局    │
└──────────────────────────────────────────────────────────────┘
                       │ /file-mention/api (POST JSON, 浏览器信任围栏)
┌ host 半 ────────────┴────────────────────────────────────────┐
│ files.index  git ls-files --cached --others --exclude-standard │
│              嵌套 git 仓库条目(dir/)递归展开(同上限/深度界)  │
│              目录 roll = 文件祖先推导 + 嵌入式仓库 dir/ 条目    │
│              (失败/非 git → opendir walk 兜底,含空目录,     │
│                TTL 10s 缓存)                                  │
│ files.read   遗留接口(纯文本模式不再调用;保留供测试覆盖)    │
└──────────────────────────────────────────────────────────────┘
  • 客户端 bundle 以 window.__ModuleLoader__.load 约定注册,不 require 任何模块(纯逻辑,无 React),规避 externals 漂移,无需打包器。
  • 菜单渲染、键盘仲裁、IME 守卫、纯文本装饰(mark.textRef 着色)、气泡 refChip 投影全部由 DSH 内建管线承担。
  • @subagent@cordis 两个 @ 源共存(组名 file,order 2)。

引用格式(宿主侧注入,dsh-at-file 同款)

选中文件插入干净纯文本提及 @token (token = 去扩展名文件名);发送后的处理全部在宿主侧 agent/pre-step 边界完成:

  • 宿主扫描发出的用户消息里的 @token,按「pick 注册(精确)→ 索引唯一 stem」解析,stat 校验存在后,注入一条独立的引用消息给模型:
<workspace-reference path="lbk-flutter-common/modules/fiat/lib/screens/otc/home/otc_home_tab_page.dart" kind="file" />
  • 文件夹同样可引用:目录与文件共享同一索引与 token 语法(src/app/@app),选中或手输命中后注入 <workspace-reference path="lib/" kind="directory" />(目录 path 保留尾部 /);token/胶囊点击预览对目录走系统打开方式(跳过 better-sidebar 编辑器)
  • 输入框、草稿、用户气泡永远干净——只显示着色 token,路径不出现在任何用户可见文本里
  • 模型直接从引用消息拿精确路径,零搜索
  • 菜单 pick 时客户端通过 mentions.registertoken → 相对路径 精确映射登记到宿主(歧义 stem 也能精确解析);手输 token 靠全工作区唯一 stem 兜底
  • 注入消息的 source 为 at-file-mention(与 dsh-at-file 相同形状),不进入输入历史
  • token 语法 @[\w-]+:点文件(.gitignore)与多点名(archive.tar.gz)插入 @basename 但不着色、不注入引用
  • 手动键入 @token (token 命中 lexicon)同样着色;唯一 stem 的手输 token 发送时同样被注入引用
  • token/胶囊点击预览:pick 的 token 按 pick 时登记的绝对路径打开;手输/气泡 token 在 stem 唯一时反解打开;歧义 stem 点击不动作

已知限制

  • 非 git 目录靠默认忽略表兜底(node_modules/dist/build/隐藏目录等),不解析 .gitignore 本身;隐藏目录与忽略目录(node_modules 等)既不出现在文件也不出现在文件夹菜单
  • git 路径下目录由文件祖先推导:不含任何已跟踪文件的空目录不会出现(git 本身不跟踪空目录);walk 兜底路径下空目录可见
  • 索引上限 200000 文件(truncated 截断,目录 roll 同界);文件/文件夹新建后最长 10s + 重开菜单可见
  • 含空格的路径无法靠键入 query 命中(触发 token 遇空白终止,Codex 同款约束),仍可从菜单点选
  • 手输/气泡胶囊的点击解析依赖 stem 唯一:歧义 stem 不动作(pick 的 token 不受影响,pick 时已精确登记);文件夹与文件同名 stem 同样视为歧义
  • 菜单行 React key 含文件名:同名文件并列时开发构建会有 duplicate-key 告警(按索引 pick,功能不受影响)
  • 菜单 CSS 用结构选择器([role=option] span 顺序)而非平台哈希类:平台 MenuView 大改时覆盖规则失配,退回内建单行样式(无害降级)
  • 点击命中依赖 DOM 结构约定(data-composer-cardmark[data-decoration]span[data-ref-chip]),DSH 前端大版本变更时需适配

测试

node --test test/host.test.js test/client.test.js

27 个用例:目录遍历/深度/上限、嵌套仓库展开、目录 roll 推导、路径围栏、信任围栏(loopback/trusted/cross-site/origin)、读取(截断/二进制/越界)、路由分发、模糊评分(含目录行)、token/stem 派生(含目录尾部斜杠)、mention 扫描/引用形式(file + directory)/pre-step 注入/pick 注册校验、joinPath、命中测试、API 封包。(↑/↓ 输入历史相关用例已随拆分迁移至 dsh-input-history。)