cyberhunter775/dsh-plugin-file-download

資料足夠(README 完整),目錄頁爲 JS 渲染未取到正文,不影響成稿。星標、分類未標註則不寫。

call write_result_md + write_meta_json
call write_result_mdmarkdown# dsh-plugin-file-download:給 DSH 對話裏的文件加一個下載按鈕

前言

在 DSH Web 對話裏跑智能體時,模型經常要用 present 工具把生成的文件(報告、導出結果、腳本)呈現給用戶。文件卡片會顯示文件名和內容摘要,但用戶想拿到文件本體時,還是要登錄服務器、翻工作區目錄、找那個帶哈希的路徑。這個問題在讓非技術同事用對話時尤其明顯:他們不會開終端,也沒有路徑概念。

下面介紹的插件 dsh-plugin-file-download(維護者 CyberHunter775)就是專解決這個問題的:在文件卡片上直接放一個「下載」按鈕,瀏覽器點一下就能保存到本地。

這是什麼

一句話定位:爲 DSH Web 對話中呈現的文件添加下載按鈕的插件,把「在服務器上找文件」變成「點一下存本地」。

  • 維護者:CyberHunter775
  • 版本:1.0.0(來自倉庫 package.json)
  • 許可證:MIT
  • 實現:純 JavaScript,零依賴,無需構建
  • 技術背景:DSH 的理念是「一切皆插件」。插件分爲 host 側(服務端路由)和 client 側(Web 客戶端 UI)兩部分,本插件同時改了這兩側。

它解決的是交付環節的摩擦,不改變文件的產生方式,也不做文件管理,只做一件事:讓對話裏出現過的文件能被直接下載。

核心功能

按 README 列出的能力逐條說明,以下能力均已覈實,沒有加工。

1、下載按鈕出現在對話的文件卡片上。覆蓋兩類卡片:deliverables 卡片、deliverables.review 文件卡片。按鈕位置通過注入 deliverables.file.actions 和 deliverables.review.file.actions 兩個插槽實現,不覆蓋插件原有的卡片渲染。

2、流式傳輸,按 1 MiB 分塊。這樣單個大文件不會一次性讀進內存,下載過程對服務端壓力可控。

3、文件名完整保留,支持中文。通過 Content-Disposition 的 RFC 5987 編碼實現,中文文件名、帶空格和特殊字符的文件名都能正確落到本地。

4、樣式跟隨 DSH 原生主題。按鈕是幽靈按鈕(ghost button),自動適配亮色/暗色主題。

5、中英文界面。文案跟隨 DSH 的語言設置切換,對應 下載 / Download 兩種寫法,詞條放在 locale/zh.json 和 locale/en.json。

6、鑑權複用當前會話 Cookie。下載路由只允許訪問本會話日誌中出現過的文件,不能憑猜測的地址拖走工作區裏的其他文件。這裏的安全邊界是「當前登錄者 + 已呈現過的文件」。

安裝與啓用

README 給出的安裝方式是寫進 DSH profile 的依賴,支持本地路徑或 GitHub 倉庫:

# 從本地路徑安裝
dsh plugin install file:/path/to/dsh-plugin-file-download

倉庫說明裏還提到可以用 pnpm link 或 git 依賴的方式添加到 profile,沒有給出統一的 dsh plugin add github:... 命令。如果走 GitHub 方式,按 profile 的包管理器配置走 git 依賴即可,不要把本地路徑示例當成通用命令。

安裝完成後,在對話裏用 present 工具讓模型呈現文件,文件卡片上就會出現下載按鈕。插件在 package.json 裏聲明瞭 dsh.client.immediately: true 和注入目標 @deepseek-ai/dsh-client-ui-conversation,所以客戶端 UI 會在加載時自動注入,不需要額外開關。

典型用法

README 沒有給出端到端的示例腳本,下面是一個可復現的最小流程,命令均來自插件自身的標識符,沒有額外拼接。

1、準備一個 DSH profile,把插件目錄加入依賴:

dsh plugin install file:/path/to/dsh-plugin-file-download

這一步是把插件註冊進當前 profile,host 側會加載 index.js,client 側會加載 client.js。

2、啓動 DSH Web 服務(按你現有 profile 的啓動方式即可,插件本身沒有額外的啓動參數)。

3、在 Web 對話裏讓模型生成並呈現文件,例如讓它把某段分析結果寫成文件並呈現。文件卡片渲染出來後,右側會出現「下載」按鈕。

4、點擊按鈕,瀏覽器按文件名保存文件。中文文件名、超過 1 MiB 的文件都按上面功能節的方式處理。

對應的文件結構也很簡單,需要改動源碼時按文件找即可:

index.js        # host 插件:服務端路由
client.js       # web 客戶端插件:UI 按鈕
cordis.patch.yml  # Cordis 插件註冊
locale/zh.json, locale/en.json  # 界面文案

工作原理

分兩側理解會更清楚,README 也是按這個結構描述的。

Host 側(index.js)註冊 GET /plugins/file-download 路由。請求進來後,通過會話日誌接口 sessionQuery.readEvent 把 sessionId + seq + index 解析成工作區裏的文件路徑。這裏的 seq 和 index 指的是該文件在對話事件流中的出現位置,因此下載的文件不是「工作區裏隨便某個文件」,而是「這條消息裏呈現的那個文件」。解析完成後先鑑權,再以附件形式、按 1 MiB 分塊流式返回內容。

Client 側(client.js)負責 UI。它向對話渲染層注入上面提到的兩個插槽,文件卡片渲染時把下載按鈕掛到插槽位置。按鈕樣式、文案、交互都在客戶端完成,點擊後向自己的 DSH 域名發起同源請求,天然帶上會話 Cookie。

適用場景與注意

適合誰:

  • 用 DSH Web 對話做交付、要給非技術同事文件的用戶。這是最有價值的場景,省掉「開終端找路徑」這一步。
  • 在 Web 端批量產出報告、表格、腳本,希望每次生成完就能下載的人。
  • 想給 DSH 交付物卡片加自定義動作的插件開發者,可以參照它的插槽注入方式。

需要注意:

1、插件以當前 dsh 進程的權限運行。下載路由能夠讀取會話工作區裏呈現過的文件,也意味着進程能訪問的東西它都能訪問。安裝前請檢查源碼和許可證(MIT,允許在遵守聲明的前提下複製和修改)。
2、安全邊界依賴會話鑑權與 sessionId + seq + index 的路徑解析,不要把它當成獨立的文件保險箱;對外暴露 DSH 服務時,仍要保證部署層的訪問控制到位。
3、功能覆蓋範圍限於「對話裏呈現過的文件」。當前沒有看到對工作區裏未呈現文件提供列表或搜索的接口,如果需要列出全部產物,這個插件不解決。
4、插件版本爲 1.0.0,README 裏沒有列出後續路線,升級前留意倉庫提交。

結尾

這個插件的價值很集中:它不改氛圍、不造概念,只是把 DSH 交付環節裏最後一步人工操作(找路徑、開終端、取文件)收進一次點擊。對於已經在用 DSH Web 對話做交付的團隊,它是個成本很低的補充;寫插件的人也可以把它當作 host 路由 + client 插槽注入的一個緊湊範例。

  • 社區目錄頁:https://www.skillhub.cn/plugins/CyberHunter775/dsh-plugin-file-download
  • 代碼倉庫:https://github.com/CyberHunter775/dsh-plugin-file-download
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜