前言¶
DSH 桌面版(DeepSeek Harness 的 Electron 殼)沒有「重啓」這個動作:打包版菜單裏找不到重啓項,托盤菜單在 Windows 上只有「打開應用」和「退出」,渲染進程的 dshDesktop API 裏也沒有重啓方法。更麻煩的是窗口幾何從不落盤——主進程的 createWindow() 把尺寸寫死成 1280×820,所以正常退出再開,窗口一定回到默認尺寸。順帶還有一個容易踩的坑:點窗口的關閉按鈕並沒有退出應用,主進程只是 preventDefault 加 hide,把窗口收進托盤。
下面介紹的 dsh-plugin-restart-desktop 就是對着這個缺口做的:由 railgun20001 維護,MIT 許可,當前版本 1.0.0,從 npm 發佈。它提供一個側欄入口,單擊即重啓,重啓後保留窗口的位置、大小、最大化狀態和所在顯示器,可選地把重啓那一刻真正被打斷的會話自動接上。插件沒有設置頁,全部行爲由宿主側開關控制,且只支持 Windows 桌面版。
這是什麼¶
一句話定位:DSH 桌面版的一鍵重啓插件,解決「重啓丟窗口位置」和「重啓後要手動找回被打斷的會話」這兩件事。
它值得說明的一點是,這不是把官方隱藏功能挖出來,而是官方確實沒有留通道。README 裏給出的依據是解包 app.asar 讀主進程源碼的結論:完整 IPC 只有 shutdown / quit-inspection / update-tasks 等有限幾項,沒有重啓相關接口。因此插件的做法是自己派一個分離的 helper 進程,由它結束 Electron 主進程、等端口釋放、拉起新實例,再把窗口逐像素還原。
核心功能¶
下面是已覈實的能力,全部來自插件 README。
- 保留窗口幾何。 重啓時捕獲窗口的正常矩形(
rcNormalPosition)、showCmd(常規/最小化/最大化)和所在顯示器,重啓後用SetWindowPos加ShowWindow放回去,並讀回實際值(含顯示器、wanted/actual/onTarget等字段)寫進日誌和結果文件。最大化窗口按「先放回原矩形、再最大化」的順序處理,避免被拉回主屏;最小化同理。 - 單擊即重啓。 唯一入口是側欄底部賬號行右側的刷新圖標按鈕。單擊直接排程重啓,沒有二次確認,宿主守衛(有任務在跑、插件正在安裝)也不要求再點一次,只在按鈕懸停提示裏說明會打斷它們。
- 自動續接被打斷的會話。 宿主在排程那一刻取實況,把當時正在生成或正在跑工具的會話逐個恢復成活 Agent,並各注入一條純事實的恢復消息。它會主動排除空閒會話、歷史會話和掛後臺任務的會話。
- 提供一條斜槓命令兜底。
/restart-desktop同樣單擊即重啓,這條路上的宿主側警告仍需/restart-desktop --force越過。 - 不猜 DOM。 賬號行按鈕靠觀察官方已寫死的
data-signed-out與aria-haspopup="menu"特徵識別,判據裏不含哈希類名;認不出來時回落到官方給第三方插件的動作座位sidebar.footer.action,功能不會憑空消失。
安裝與啓用¶
從 npm 安裝,官方命令如下。注意這是 DSH 的 plugin_manager 調用,不是普通的包管理器命令。
plugin_manager(action: "install_bundle", target: "dsh-plugin-restart-desktop")
也可以把插件直接寫進 profile,bundles 與 dependencies 兩處都要有:
// ~/.dsh/profiles/desktop/package.json
"dsh": { "profile": { "bundles": [ /* … */ "dsh-plugin-restart-desktop" ] } },
"dependencies": { "dsh-plugin-restart-desktop": "^1.0.0" }
開發本倉庫時用 link: 指向本地目錄,改完代碼立即生效:
plugin_manager(action: "install_bundle", target: "link:C:\work\my\dsh\plugins\dsh-plugin-restart-desktop")
安裝後 DSH 的 HMR 會當場把宿主半和客戶端半掛上,一般不需要重啓;如果入口沒出現,刷新一次頁面即可。package.json 的 engines.dsh 要求 >=0.2.0-rc.1,作者本機實測於 0.2.1-rc.5。
典型用法¶
裝好之後沒有額外的上手步驟,直接點入口。
點側欄底部賬號行右側的刷新圖標,一次點擊即排程重啓。窗口的位置、大小、最大化狀態與所在顯示器保留,當時真正在跑的會話被逐個接上,頁面隨後斷開,應用重啓並回到原來的樣子。
插件沒有設置頁,界面開關一個都不提供。兩個宿主側行爲開關有默認值(都是開),需要時改插件 config 或宿主側設置文件:
// ~/.dsh/profiles/desktop/package.json 裏本插件那一行的 config
{ "geometry": true, "resume": true } // 還原窗口幾何 / 自動續接被打斷的會話
宿主側設置文件 ~/.dsh/restart-desktop/settings.json 優先級高於 config;也可以直接往插件路由改:POST /dsh-plugin-restart-desktop/api/settings?geometry=0&resume=0。
排障時可以在瀏覽器控制台裏看這些:
__DSH_RESTART_DESKTOP__.status() // 宿主狀態快照
__DSH_RESTART_DESKTOP__.button() // 賬號行按鈕的注入狀態(found / injected / lastReason)
__DSH_RESTART_DESKTOP__.sweep() // 立刻重掃一次賬號行
__DSH_RESTART_DESKTOP__.action() // 按鈕此刻的動作狀態
宿主側的交接記錄落在 ~/.dsh/restart-desktop/,保留最近 20 組 handoff-*.json、restart-*.log、restart-*.result.json、restart-*.geometry.json。幾何結果文件裏還能看到窗口到底落在哪塊屏。
適用場景與注意¶
適合這兩類工作場景:
- 在 Windows 上以桌面版做日常會話,希望重啓(裝依賴、升版本、改配置)時窗口布局不被打斷。
- 會話裏掛着長任務,重啓後不想讓歷史上下文中斷、需要自動接回。
需要說清楚的邊界,主要是插件本身的行爲邊界,不是 bug:
- 正在跑的那一輪一定會斷,不會自動續跑;自動恢復注入的是一份事實報告,不是重放那一輪。
- 正在被工具寫入的文件可能停在半路,插件不做回滾。
- 後臺任務、子 Agent、teammate 都會被殺掉,定時任務在應用關閉期間不會觸發;被殺的後臺任務不會換來恢復消息,需要的話重啓後自己再拉起。
- 只支持 Windows 桌面版,能力探測不通過會明確拒絕。
另外,插件以當前 DSH 進程的權限運行,可結束主進程、拉起新實例、讀寫會話狀態。安裝前建議先讀一遍 README、lib/ 下的源碼與 cordis.patch.yml,確認許可證爲 MIT 後再啓用;cordis.patch.yml 屬於宿主側補丁,屬於改動宿主行爲的一類安裝,值得單獨評估。
結尾¶
這個插件的價值很具體:把官方沒有留通道的重啓動作補齊,並且把「窗口幾何不落盤」這個隱性損失解決掉。它不追求大體量的設置項,靠宿主側兩個開關和一個分離 helper 把鏈路走完,邊界也寫在 README 裏,方便按自己的工作方式判斷是否啓用。
目錄頁:https://www.skillhub.cn/plugins/railgun20001/dsh-plugin-restart-desktop
倉庫:https://github.com/railgun20001/dsh-plugin-restart-desktop