dsh-console-sentinel:把跑完的控制台窗口從任務欄收走

前言

在 DSH 裏跑長時間自動化任務時,任務欄經常會堆上一排 PowerShell / Python 黑窗口:Fluent 無人值守任務、批量腳本、WMI 拉起的脫離進程各佔一個。這時的問題不是「沒有輸出」,而是分不清哪些還在跑、哪些已經用完,於是誰也不敢隨手關——誤關正在計算的窗口,代價比多看幾個窗口大得多。

dsh-console-sentinel 處理的就是這件事:追蹤這些控制台窗口,區分「在忙」和「用完了」,把用完的隱藏掉。進程不殺、日誌不動、輸出不丟,窗口之後還能叫回來。

這是什麼

dsh-console-sentinel 是維護者 loyalchiiina 開發並維護的 DeepSeek Harness(DSH)插件,社區目錄裏歸在 admin-security 分類,許可證爲 MIT。

一句話定位:Windows 上的控制台窗口哨兵——自動隱藏(或關閉)空閒的 AI / 腳本控制台窗口。它只操作窗口,不干預進程,因此適合「任務還在跑、界面不需要留」的無人值守場景。僅限 Windows 平臺。

工作原理

插件按固定節奏輪詢控制台窗口,每一輪做四件事:

  1. 枚舉窗口。用內嵌的零依賴 Windows PowerShell 探針(user32 + ntdll P/Invoke)按窗口類找出三類控制台:CASCADIA_HOSTING_WINDOW_CLASS(Windows Terminal)、ConsoleWindowClass(傳統 conhost)、PseudoConsoleWindow(ConPTY 僞控制台)。
  2. 來源歸類。優先看父進程:父進程是 WmiPrvSE.exe → wmi-detached(WMI 拉起的脫離任務,無人值守 Fluent 計算通常這樣啓動);父進程是 DSH Desktop.exe → dsh-host;父進程已退出 → orphaned。父鏈說明不了問題時改看控制台標題:腳本啓動的控制台標題默認是被啓動程序的路徑(...\python.exe),交互式手開的控制台是提示符式標題(Windows PowerShell),歸爲 script-console。
  3. 判定空閒。每輪採樣進程的累計 CPU 時間,低於 cpuThresholdPct(默認 1%)且持續 idleThresholdSec(默認 60 秒)即判定「用完了」。單次後臺 CPU 抖動不會重置空閒時鐘,由 spikeTolerance(默認 2)控制。
  4. 執行動作。對管理範圍內「用完了」的窗口執行 autoAction(默認 hide,即 SW_HIDE,進程繼續跑);close 則發送 WM_CLOSE。前臺窗口永不自動處理(guardForeground)。

探針的父進程 PID 用 NtQueryInformationProcess 取得,而不是 CIM(Get-CimInstance Win32_Process)——參考機實測 39 秒 vs 24 毫秒(13 個進程),單次完整探針約 350 毫秒。這解釋了爲什麼插件堅持自己內嵌探針。

安裝與啓用

安裝命令來自項目 README:

dsh plugin --profile <name> add dsh-console-sentinel

這是一個 Bundle 插件(dsh.bundle.patch):安裝後進入 profile bundle 棧,重啓 DSH 後生效。patch 行在其他平臺標記爲 disabled,apply() 運行時也會再守一次平臺限制。

運行要求:Node ^22.19.0 || >=24.0.0;peer 依賴 @deepseek-ai/cordis >=4.0.2、@deepseek-ai/dsh-tools >=0.1.5-rc.2、@deepseek-ai/schemastery >=3.18.0;當前版本 0.3.0。

模型可見的工具

插件提供 5 個工具,模型可以直接調用:

  • console_windows_list —— 列出所有被追蹤的控制台窗口及其空閒狀態和來源歸類。先用它看現場。
  • console_window_action —— 對單個窗口執行 hide / show / minimize / restore / close,用 hwnd 或 pid 定位。hide 無損;close 可能丟失未保存輸出。對前臺窗口操作需傳 force。
  • console_windows_sweep —— 一次性對所有空閒且在範圍內的窗口執行動作。跑完一批 Fluent 任務後清任務欄很好用。
  • desktop_windows_cleanup —— 一鍵關閉其他窗口:關閉桌面除前臺、自身、系統外殼和受保護進程以外的所有應用窗口。dryRun 先出計劃;protected / keepTitle / keepPid 可臨時加固保護。
  • sentinel_whitelist —— 管理持久化豁免白名單,list / add / remove / reset,kind=process(按映像名,如 code.exe)或 kind=title(按標題子串)。白名單同時作用於自動隱藏/關閉與一鍵關閉窗口,落盤到 ~/.dsh/console-sentinel/whitelist.json。

設置面板

從 0.3.0 起,插件在 DSH「設置」頁註冊「控制台哨兵」分區(客戶端 bundle lib/client.js),不記工具名也能操作:

  • 概覽:總窗口 / 空殼 PowerShell / 可見空殼 / 已隱藏 計數,外加「隱藏可見空殼」。
  • 任務欄窗口清理:預演 / 一鍵關閉其他窗口(前臺、系統進程、白名單自動跳過)。
  • 控制台窗口:逐行顯示進程名 / 標題 / hwnd / pid / CPU / 空閒秒數 / 子進程數,行內可直接隱藏 / 顯示 / 關閉。
  • 豁免白名單:進程名與標題關鍵字標籤式增刪、清空,即時落盤。

面板通過宿主路由 /dsh-console-sentinel/* 取數,客戶端 fetch 根相對路徑,桌面端自動帶 capability header,不使用 iframe。改 lib/client.js 後按 Ctrl+Shift+R 硬刷新;改宿主側(lib/index.js / package.json)需要完全退出 DSH 再啓動。

配置

配置寫在 cordis.yml 裏,常用鍵如下:

鍵 默認值 含義
enabled true 總開關
scanIntervalSec 10 掃描 + CPU 採樣間隔
idleThresholdSec 60 持續低 CPU 多少秒算「用完了」
cpuThresholdPct 1 CPU 低於此值算空閒
autoAction hide none | hide | close
probeTimeoutMs 20000 探針硬超時
spikeTolerance 2 連續多少次「忙」採樣才重置空閒時鐘
guardForeground true 永不自動處理前臺窗口
scope.wmiDetached true 管理 WMI 拉起的脫離控制台
scope.dshHost true 管理宿主派生的控制台
scope.orphaned false 管理父進程已退出的控制台
scope.scriptConsole true 管理標題是腳本可執行文件路徑的控制台(Windows Terminal 承載的腳本會話)
scope.excludeTitles [] 標題 substring 黑名單
scope.emptyConsole true 把「沒有任何工作子進程」的解釋器控制台(PowerShell/Python/cmd 只剩 conhost)判爲空殼,無論父鏈如何都納入管理。這是安全清理殘留空 PowerShell 的開關,不必打開整個 orphaned(後者會誤傷 mpiexec/fl2610/在跑的計算)
emptyConsoleAction hide 對空殼控制台的動作:none | hide | close;獨立於 autoAction,自動動作關閉也能單獨生效
whitelist.processes [] 豁免進程映像名(如 code.exe),永不自動處理/一鍵關閉
whitelist.titles [] 豁免標題子串,永不自動處理/一鍵關閉

例如把空閒判定放寬到 90 秒,並讓標題含 keep-alive 的窗口不受管:

- id: dsh-console-sentinel
  config:
    idleThresholdSec: 90
    scope:
      excludeTitles:
        - keep-alive

典型用法

1、先用 console_windows_list 看當前有哪些窗口、各自着急不忙、來源是哪一類。
2、對單個用完的窗口用 console_window_action hide(用 hwnd 或 pid 定位);需要它回到前臺時再 action show。
3、跑完一批 Fluent 任務後,用 console_windows_sweep 一次性收走所有空閒窗口。
4、平時想讓某個進程(例如 code.exe)或某個標題關鍵字永不被動,調用 sentinel_whitelist add;臨時用桌面右下角的窗口清理時,區域外進程也由 desktop_windows_cleanup 的 protected / keepTitle / keepPid 再兜一層。

真實窗口狀態不可回放,README 只給了上述操作序列,未附截圖或端到端日誌,實際結果建議在自己的機器上先跑一次 console_windows_list 確認歸類是否符合預期。

安全性與適用場景

動作本身是剋制的:

  • hide 只調用 ShowWindow(SW_HIDE),進程、日誌、輸出一概不動;console_window_action 的 show 可隨時恢復(用 SW_SHOWNORMAL——實測 SW_SHOW 無法恢復被隱藏的 Windows Terminal 窗口)。
  • close 發送 WM_CLOSE(優雅關閉,和點 X 一樣),但可能丟失未保存狀態,因此從不是默認動作。
  • 自動動作絕不觸碰:前臺窗口、手動打開的控制台(manual 來源)、標題命中黑名單或白名單的窗口,以及 HARD_PROTECTED_PROCESSES 裏的系統/計算進程(explorer、taskmgr、dsh desktop、fl2610/cx2610/mpiexec/smpd/fluent 等)。
  • 每個動作都發 console-sentinel/action 事件並寫日誌。

適用場景:長期無人值守跑腳本、需要保留後臺計算但不想留窗口的自動化流程,以及「清理任務欄」這個收尾動作。不適合需要窗口一直可見的交互式調試——那種情況應該直接把 autoAction 設爲 none,或用白名單固定住窗口。

需要說明的是,插件以當前 dsh 進程的權限運行,能枚舉和操作的是這個權限範圍內可見的窗口;安裝前建議先檢查源碼與許可證(MIT),確定 scope.* 幾個開關和 HARD_PROTECTED_PROCESSES 列表符合你的環境。

工程結構與測試

lib/index.js   Cordis 插件:配置、掃描調度、工具
lib/logic.js   純臺賬/空閒狀態機(單測覆蓋)
lib/probe.js   內嵌 PowerShell 探針 + 窗口動作
tests/         僅 node 的迴歸測試,不需要真實 Windows

node tests/logic.test.mjs —— 24 項斷言,覆蓋來源歸類、空閒累積、忙碌脈衝重置、範圍守衛、臺賬 GC、排序。也就是說核心判定邏輯可以在非 Windows 機器上回歸。

結尾

dsh-console-sentinel 的價值不在「又多了一個窗口管理工具」,而在於它把「這個窗口還在忙嗎」這個問題固化成 CPU + 父鏈 + 標題的三方判定,並用 hide 而不是 kill 來做清理,給了無人值守流程一個不冒數據風險的收尾方式。

  • 目錄頁:https://www.skillhub.cn/plugins/loyalchiiina/dsh-console-sentinel
  • GitHub:https://github.com/loyalchiiina/dsh-console-sentinel
羽毛球分组比赛记分
小程序二维码

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

小夜