前言¶
在 DSH 對話裏讓模型啓動一個 dev server,常遇到的問題是:對話回合一結束、會話一關閉,服務就沒了。根因在於 pwsh 的後臺任務(jobs)綁定在 owner 會話作用域上,會話或回合結束時,dsh-jobs-local 會取消歸屬任務——服務根本活不到下一輪。
dsh-launch 針對的就是這個問題:把服務交給一個獨立的 detached broker 進程監督,使服務在對話回合結束、會話關閉、甚至 DSH 自身重啓後繼續運行。下面介紹它的機制、功能與用法。
這是什麼¶
dsh-launch 是 Khellendros97 維護的 DSH 服務管理插件,MIT 許可,當前版本 0.2.0,要求 Node >= 20。監督機制參考了 omp 的 launch daemon broker。
核心思路分三步:
1、服務由 detached broker 進程以 detached + stdio 落盤 的方式拉起,stdio 直接寫入磁盤日誌;
2、broker 只做監督——日誌增量、pid 探活、就緒檢測、崩潰退避重啓——自身空閒即退;
3、DSH 下次啓動時重新拉起 broker,並按 pid 收養仍在運行的服務。
插件是單包發佈:Service 側邊欄 tab、broker、模型工具全部在同一包內;better-sidebar 只負責承載 tab(經其擴展 API 注入,better-sidebar 側無需任何改動)。
核心功能¶
模型工具¶
service_start:啓動長駐服務,必填name+command,可選cwd/title/logo/env/readyLog/readyPort/restart,等待就緒後返回;service_stop/service_restart/service_list/service_logs:停止(整樹殺)/ 重啓 / 列舉 / 讀日誌尾。
就緒判定會先剝離 ANSI 轉義,再對端口做 IPv4/IPv6 雙棧探測。
Service tab(側邊欄)¶
側邊欄中以服務卡片展示標題、logo(可選,URL 或圖片路徑)、狀態徽標、PID、運行時長、重啓次數,支持啓動 / 停止 / 重啓 / 查看日誌。tab 可見時輪詢插件自有的 fenced /launch/api 路由。
沒有安裝 better-sidebar 時,插件以 headless 模式運行:工具可用,無 UI tab。
ctx.launch(cordis 服務)¶
供其他插件消費,提供 ping / list / start / stop / restart / describe / logs。
監督機制¶
每服務維護一個狀態機:starting→running→ready→stopping→exited/failed(開啓重啓且失敗時進入 restarting 退避)。重啓策略有 no / on-failure(默認)/ always 三種,退避爲指數遞增,從 1s 到 30s。
通信上,宿主與 broker 之間採用命名管道 NDJSON 協議 + token 認證,管道名按 runtimeDir 哈希,多部署不會衝突。
就緒檢測有兩個開關:
readyLog:輸出正則匹配,ANSI 轉義已剝離;readyPort:TCP 探測,未指定 host 時同時探127.0.0.1與::1。
start/restart 等待就緒默認 20s,上限 60s。broker 重啓後收養 starting 記錄時,會重掃日誌尾部已滾過的就緒標記,避免誤判。
Windows 上,command 字符串服務經 cmd.exe /d /c 由內置 node 啓動器(broker/launcher.cjs)執行——detached 的 cmd 會丟失批處理子進程輸出,啓動器規避了該問題;整樹停止用 taskkill /T。
安裝與啓用¶
前置條件:DSH web 環境;dsh-better-sidebar 是可選依賴(^0.11.0 || ^0.12.0),僅 UI 需要。
dsh plugin --profile web add dsh-launch
一條命令完成安裝 + 自動掛載:包內 cordis.patch.yml 會註冊進 dsh.profile.bundles。裝完先重啓 dsh web,再硬刷新瀏覽器(Cmd/Ctrl+Shift+R)。
配置¶
插件行可選 config,共有三個配置項:
- id: dsh-launch
name: dsh-launch
config:
runtimeDir: '~/.dsh/tmp/dsh-launch' # 運行時目錄,默認同左
idleGraceMs: 15000 # 無客戶端/無 presence 後的退出寬限
maxLogBytes: 8388608 # 單服務日誌輪轉閾值,8MB
運行時目錄 ~/.dsh/tmp/dsh-launch/ 下包含:broker.token、broker.pid(單實例租約)、presence/*.json(DSH 存活標記)、daemons/<name>/(元數據 + 日誌,8MB 輪轉)。
測試¶
npm test
測試分兩部分:broker 冒煙 15 項(啓動、就緒含 ANSI 與 IPv6、日誌、停止、重啓、持久化、殺 broker 後收養、收養尾部重掃)與接線 13 項(服務提供 / 工具註冊 / presence / 真實 broker 往返 / fenced 路由信封 / 圍欄拒絕 / 客戶端契約)。
安全說明¶
- 服務以運行 DSH 的同一用戶身份、脫離任何沙箱執行——這是服務存活的前提,服務等同於用戶在終端啓動的進程;
/launch/api與/launch/service-logo全部經 Host 頭信任圍欄(loopback 或trustedHosts);broker 管道僅綁定本機(命名管道 + token);- 插件卸載(HMR/禁用)不會停止服務或 broker;broker 在無 presence 且空閒 15s 後自行退出,服務繼續運行。
限制¶
- 服務名全局唯一(全機一個 broker 作用域);
- 無 PTY / 無 stdin:交互式進程請改用 better-sidebar 終端;
- broker 死亡窗口內(DSH 未運行且 broker 已退出)崩潰的服務不會自動重啓,detached 服務本身不受影響。
適用場景與注意¶
適合的場景:dev server、watcher、mock API、worker 這類需要跨回合、跨會話存活的進程。只要流程裏有「模型起了個服務,下一輪還要用」,這個插件就把服務生命週期從對話生命週期裏解耦出來。
注意兩點:插件以當前 dsh 進程權限運行,服務也以同一用戶身份、脫離沙箱執行;安裝前建議自行檢查源碼與許可證(MIT)。
結尾¶
回顧一下:dsh-launch 用一個 detached broker 進程解決後臺服務隨會話回收的問題,服務在回合結束、會話關閉、DSH 重啓後都能繼續運行,同時提供模型工具、側邊欄 UI 和跨插件 API 三套入口。DSH 的理念是「一切皆插件」,這類把基礎設施問題封裝成插件的思路,值得在搭建自己的工作流時參考。
- GitHub:https://github.com/Khellendros97/dsh-launch
- 社區目錄頁:https://www.skillhub.cn/plugins/Khellendros97/dsh-launch (社區站點,與 DeepSeek / 幻方無官方從屬關係)