前言¶
DeepSeek Harness(DSH)的插件化架構讓開發者可以按需擴展行爲。在智能體開發場景中,經常需要在多處複製內容,再一次性粘貼到當前對話草稿裏。傳統的右鍵粘貼會彈出菜單,打斷思路;手動選中再粘貼又多一步操作。下面這個插件直接接管輸入框區域的右鍵事件,把剪貼板文本追加到草稿末尾,像 cmd / PowerShell 的粘貼那樣。
插件定位¶
dsh-rightclick-paste 是 DeepSeek Harness 的一個客戶端插件,由 Eureka-KK 維護。它解決的是「在輸入框區域內快速追加剪貼板文本」的重複操作問題,不提供 UI,僅擴展右鍵行爲。
核心功能¶
- 在輸入框區域內右鍵:不彈出任何菜單,剪貼板文本直接追加到當前會話草稿末尾。
- 在輸入框以外右鍵:完全不接管,DSH 原生菜單照常顯示(複製、檢查元素等)。
- Shift + 右鍵(輸入框內):放行原生菜單,作爲逃生口。
- 命中範圍:點在內層節點 / 卡片空白處同樣算「輸入框區域內」;點在輸入卡片裏的按鈕上不接管,走原生菜單。
- 剪貼板來源不限:DSH 內複製的、其他軟件複製的、純文本都能粘。
- 追加規則:草稿爲空或以換行結尾時直接拼;否則先補一個換行再拼。剪貼板內容一字不改。
- 超長保護:單次最多粘貼 200 KB,超出部分截斷並在控制台提示。
- 與 dsh-quote-to-input 正交:前者負責「選中 → 引用」,後者負責「右鍵 → 粘貼」,兩者互不干預。
安裝與啓用¶
使用 link 方式安裝,修改代碼即時生效:
# 安裝:<插件目錄> = 本倉庫在你機器上的絕對路徑(link 方式,改代碼即時生效)
dsh plugin --profile desktop add link:<插件目錄>
# 卸載
dsh plugin --profile desktop remove dsh-rightclick-paste
DSH 開啓 HMR 時,修改 profile 清單會觸發熱重組,無需重啓 App;但需要刷新一次 GUI 才能加載新增的客戶端模塊。
驗證方式¶
- 無頭驗證(自動):
node verify-client.mjs
用假 DOM / 假 window / 假 navigator / 假 ctx 跑完整行爲矩陣:bundle 協議、框內接管並寫入正確文本、框外不接管、Shift 放行、剪貼板缺失或拋錯不崩、超長截斷、HMR 反覆加載不疊監聽器,以及一批內存紀律靜態斷言。退出碼 0 = 全綠。
-
真機驗證(手動):
-
安裝後刷新 GUI(Ctrl+R)。
- 在別處複製一段文字,在輸入框裏右鍵——應立即出現在草稿末尾,且不彈菜單。
- 在消息列表區域右鍵——原生菜單照常彈出。
- Shift + 右鍵輸入框——原生菜單照常彈出。
內存與實現設計¶
本插件按「零常駐」設計:
- 零 UI:不註冊槽位、不 require(‘react’)、不建任何 DOM,反饋只走 console。
- 零定時器 / 零觀察器:沒有 setInterval、setTimeout、requestAnimationFrame、MutationObserver。
- 單監聽器 + 可卸載:唯一的全局監聽器經 ctx.effect(…) 註冊並返回 disposer。DSH 開啓 HMR 時,缺 disposer 會導致每次熱重載疊加一份監聽器,這是真正會漲內存的地方,泄漏測試覆蓋了它。
- 零常駐狀態:剪貼板文本與草稿快照只活在單次事件調用棧裏,模塊級沒有任何可變變量。
- 日誌不含正文:只打長度({ chars: 1234 }),避免 DevTools 控制台歷史強引用正文。
- 200 KB 截斷:草稿會經 setDraft → 狀態機 → contenteditable → React state 複製多份,故設上限。
實現要點:
- 命中判定靠 DSH 自己的 DOM 錨點:[data-composer-input](Lexical 的 contenteditable 宿主)與 [data-composer-card](輸入卡片)。命中不了就退讓,絕不誤接管。
- 讀剪貼板用 navigator.clipboard.readText()。桌面端 main.js 中的 setPermissionCheckHandler / setPermissionRequestHandler 對非 media 權限一律放行,因此不會被權限攔;右鍵前必有 mousedown,transient activation 也在。
- 寫輸入框複用官方唯一寫路徑 ctx.conversation.input.for(binding.ctx).setDraft(text)(全文替換語義,所以先讀草稿再拼接)。
- 壓掉原生菜單靠渲染進程 preventDefault():Blink 只在 DOM contextmenu 未被取消時才向瀏覽器進程請求菜單,而 DSH 的菜單是主進程硬編碼的(app.asar 內 lib/main.js 的 webContents.on(‘context-menu’)),插件無法擴展它。
- 監聽器掛在冒泡階段並先查 event.defaultPrevented,頁面上別的組件仍有機會先消費事件。
適用場景與注意¶
- 適合頻繁需要在對話草稿中追加大量文本的用戶。
- 插件以當前 DSH 進程權限運行,安裝前應檢查源碼與許可證。
- 若 DSH 將來改掉 [data-composer-input] / [data-composer-card] 錨點,插件會靜默失效(既不接管也不報錯),不會干擾原生菜單,可用 verify-client.mjs 與新 GUI 一起迴歸。
- 只處理文本(readText),不處理圖片或富文本。
結尾¶
dsh-rightclick-paste 通過極簡的右鍵攔截與追加邏輯,減少重複操作,讓對話草稿的文本錄入更順暢。其「零常駐」設計也避免了內存泄漏風險。目錄頁與源碼倉庫見下:
https://www.skillhub.cn/plugins/Eureka-KK/dsh-rightclick-paste
https://github.com/Eureka-KK/dsh-rightclick-paste