前言¶
在 DSH(DeepSeek Harness)Web 界面裏引用工作區文件,默認只有兩條路:手動輸入 @ 從菜單逐級挑選,或者把文件拖進輸入框。前者在大倉庫裏找深層文件很費時,後者會直接報「僅支持 PNG、JPG、WebP、GIF 格式的圖片」——除圖片外的任何文件、文件夾都不收。
dsh-paste-names 補的就是這個缺口:粘貼非圖片文件或文件夾時,解析成 DSH 原生 @path 文件引用;拖放時,插入絕對路徑文本。下面介紹它的功能、原理與安裝方式。
這是什麼¶
dsh-paste-names 是一個 DSH Web 端插件,當前版本 1.4.3,MIT 許可證,倉庫歸屬 GitHub 的 PaoMoXML/dsh-paste-names。它解決的問題很具體:把「僅支持圖片」的報錯替換爲可用的文件引用。
插件分兩半協作:
- 瀏覽器半(
lib/client.js):在 document 捕獲階段攔截輸入框的paste事件與全局dragenter/dragover/drop事件,先於 DSH 自帶處理。會話 id 通過目標元素沿 React fiber 上溯取得。 - 宿主半(
lib/index.js):註冊GET /plugins/dsh-paste-names/resolve深度解析路由,負責按 basename 反查文件。
核心功能¶
- 粘貼非圖片文件/文件夾:解析爲 DSH 原生 @ 文件引用,與手動 @ 選擇等價;
- 拖放(v1.3.0 新增):拖入工作區內文件/文件夾時插入絕對路徑文本,多條目以空格分隔;
- 多候選人工選擇器(v1.4.0 新增):工作區內存在多個同名匹配時彈出選擇器,人工確認後再插入;
- 截圖與 png / jpg / webp / gif 不干預,走 DSH 原生圖片附件流程;純文本也不干預;
- 末位 @ 引用不補尾隨空格(v1.3.0 行爲):保持 token 未閉合,喚出 DSH 原生 @ 菜單,首選即精確匹配,一次回車即可升級爲原生 chip。
典型用法¶
粘貼¶
| 粘貼內容 | 結果 |
|---|---|
| 工作區內的文件 | @相對/路徑/文件名 |
| 工作區內的目錄 | @目錄/(帶尾斜槓) |
| 含空格的路徑 | @"my docs/readme.md" 引號語法 |
| 解析失敗(工作區外 / 無匹配 / 超時) | 回退插入純文件名 |
多條目粘貼以空格分隔插入。
拖放¶
| 拖入內容 | 結果 |
|---|---|
| 工作區內的文件 | 插入絕對路徑文本,如 C:\repo\src\index.js |
| 工作區內的文件夾 | 絕對路徑 + 尾分隔符,如 C:\repo\docs\ |
| 含空格的路徑 | 整體加引號:"C:\my docs\a.txt" |
| 解析失敗(工作區外 / 無會話) | 回退插入純文件名 |
拖到輸入框上插在光標處,拖到界面其他位置追加到末尾。注意兩點:瀏覽器拖放事件出於安全限制不暴露源文件絕對路徑,插件按 basename 反查會話工作區後拼接路徑,因此拖放只對會話工作區內的條目有效;且插入的是絕對路徑文本,不是 @ 引用。
多候選選擇¶
粘貼/拖放的條目在工作區內存在多個同名匹配時,不再自動取最短路徑,而是彈出輕量選擇器:
- 每個多匹配條目一組候選(每組 ≤20 條,最短路徑優先,默認選中首選);
- 點擊候選改選,點「插入所選」一次性插入全部條目;
- 按 Esc 或取消則放棄本次插入,不寫入任何內容。
唯一匹配的條目不參與選擇器,仍直接插入。選擇器跟隨系統深淺色主題,定位在輸入框下方(視口不足時移到上方)。
工作原理¶
路徑解析分兩級,多條目共享:
- 快查:DSH 自帶
remote.fileReferences@ 搜索索引,毫秒級返回,但索引有 10,000 條 BFS 截斷,大倉庫深層文件覆蓋不到; - 深度兜底:宿主半用
node:fs按 basename 全量掃描會話 cwd,上限 400,000 條 / 4 秒,實測約 1 秒掃完 78k 條目。
批量接口(v1.3.0):全部未命中條目打包成一次請求,客戶端按每批 40 條分塊防 URL 超長,宿主半隻掃一次。
深掃結果以「basename → 路徑」倒排索引按工作區根緩存:
- 30s TTL + stale-while-revalidate:過期後請求立即返回舊索引(毫秒級),後臺異步重建;只有每個根的首次請求才等待完整掃描;
- 同一根的併發構建去重,只跑一次 BFS;
- LRU 最多緩存 8 個工作區根,防止多會話場景內存無界增長。
resolve 路由的請求與響應格式:
GET /plugins/dsh-paste-names/resolve?session=<id>&n=<name>&d=<0|1>&n=<name>&d=<0|1>...
→ { ok: true, root: "<abs cwd>", results: [{ name, dir, matches: [{ path, kind }, ...] }, ...] }
兼容舊單條形式 name=<basename>&dir=<0|1>;root=1 且不帶 n= 可免掃描直接取根(供拖放拼接絕對路徑);失敗返回 { ok: false, error: "..." }。
安裝與啓用¶
推薦用 dsh plugin add 安裝。包的 package.json 聲明瞭 dsh.bundle.patch,dsh plugin add 會自動接線:
dsh plugin --profile web add git+https://github.com/PaoMoXML/dsh-paste-names.git
也可以手動安裝:
- 克隆倉庫到 profile 的插件目錄:
git clone https://github.com/PaoMoXML/dsh-paste-names.git ~/.dsh/profiles/web/plugins/dsh-paste-names
- 在
~/.dsh/profiles/web/package.json的dependencies里加一行,然後在該目錄執行pnpm install:
"dsh-paste-names": "link:plugins/dsh-paste-names"
- 在
~/.dsh/profiles/web/cordis.patch.yml末尾追加:
- insert:
- id: paste-names
name: dsh-paste-names
- 重啓
dsh web並硬刷新頁面(Ctrl+Shift+R)。
插件自帶 22 個迴歸測試(node:test,無外部依賴),覆蓋路由契約、併發 BFS、粘貼歸一與選擇器交互,可在倉庫目錄下運行:
npm test
適用場景與注意¶
適合在 DSH Web 端頻繁引用工作區文件的人:大倉庫深層文件、同名文件多需要人工挑選、習慣拖放操作的場景都能覆蓋。使用前留意幾點:
- 拖放只對會話工作區內的條目有效,且插入的是絕對路徑文本,不是 @ 引用;
- 深度解析每個工作區根首次掃描約 1 秒(按倉庫規模浮動),之後 30s 內爲毫秒級緩存命中,過期後臺重建不阻塞;
- 深掃排除
.git/node_modules/target,如需增刪改lib/index.js的EXCLUDED與lib/client.js的EXCLUDED_SEGS; - 插件以當前 dsh 進程權限運行,安裝前建議檢查源碼與許可證(本項目爲 MIT)。
結尾¶
dsh-paste-names 用一個很小的切入點改善了 DSH Web 端的日常體驗:非圖片文件從「報錯」變成可用的 @ 引用或路徑文本,路徑解析有索引快查加深掃兜底,多同名場景交給人工確認。DSH 的理念是「一切皆插件」,這類補足默認行爲短板的插件正是這套機制的典型用法。
項目主頁:https://github.com/PaoMoXML/dsh-paste-names
社區目錄頁:https://www.skillhub.cn/plugins/PaoMoXML/dsh-paste-names (社區目錄爲獨立站點,與 DeepSeek / 幻方無官方從屬關係)