dsh-pwsh-plugin:DSH 下的常駐 PowerShell 會話與 WSL bash 寫邊界

前言

在 DeepSeek Harness(DSH)裏讓智能體跑 Windows 側 PowerShell,常見有兩條路:走 bash 工具進 WSL,或走內置 pwsh 工具。前者會把命令包成 /bin/bash -c "...",外層雙引號往往在 PowerShell 看到腳本之前就把 $ 展開;後者能原樣傳遞 $ 和 here-string,但每次調用都是新進程,整條命令還要擠進 Windows 命令行,大約 32,700 字符就會觸發 spawn ENAMETOOLONG。若腳本很長、或希望變量、當前目錄、已加載模塊在多次工具調用之間保留,內置路徑都會顯得彆扭。

下面介紹社區插件 dsh-pwsh-plugin(維護者 citydirector):它在 Harness 裏註冊 pwsh_run,把腳本正文經 stdin 送進一個常駐的 PowerShell 7 進程;同一倉庫還提供 WSL 側的 llrun 墊片,在 Windows 上替換 bash 工具實現,爲 WSL 命令補上可 enforcement 的寫邊界。插件歸類爲客戶端,在 SkillHub 插件目錄 可查到條目;目錄站與 DeepSeek / 幻方無官方從屬關係,DSH 生態本身是「一切皆插件」的思路,裝什麼由你在 profile 裏選。

這是什麼

dsh-pwsh-plugin 是一個發佈在 npm 的 DSH bundle(當前 package 版本 0.2.17,MIT 許可證)。它做兩件事,且都與內置工具並存、不替換內置 pwsh:

  1. pwsh_run:腳本以 base64 走 stdin 進入常駐 pwsh 7,路上不做轉義、不受 32K 命令行上限約束;冷啓動大約 400ms 只付一次。README 記載單次實測 91,741 字符仍可執行,完整數據見倉庫 FINDINGS.md。
  2. custom-bash(僅 Windows):bundle 通過 cordis.patch.yml 插入一行,指向包內 wsl/custom-bash.mjs,圍欄使用隨包發佈的 llrun 二進制,無需手工拷貝到 /usr/local/bin。說明見 docs/llrun.md。

運行環境要求:DSH 0.2.0-rc.2 或更新(文檔寫明在 0.2.0-rc.2 與 0.2.1-rc.3 上驗過),以及本機已安裝 PowerShell 7。package.json 中 engines.dsh 爲 >=0.2.0-rc.2 <0.3.0。

核心功能

pwsh_run 與內置工具的差別

層 行爲(據 README 歸納)
bash 工具 命令包在 /bin/bash -c "..." 裏,$ 與 heredoc 易在外層被處理掉。
內置 pwsh 轉義正確,但每 call 新進程,且受 Windows 命令行長度限制。
pwsh_run 腳本正文 stdin 送入常駐會話,上述兩類問題在設計上被避開。

工具參數如下(名稱與含義以 README 爲準):

參數 必填 說明
script 是 PowerShell 腳本正文,原樣送達;不要轉義 $,不要包 pwsh -c,不要加外層引號。
workdir 否 先 Set-Location;會話有狀態,後續調用繼承目錄。無效路徑則本次不執行腳本。
timeoutMs 否 單次超時,默認 120000。

輸出規則:stdout 原樣返回;warning / verbose 帶前綴;異常帶 [script threw]。錯誤流排在 stdout 之後,stdout 與 stderr 的逐行時序不保留;需要順序時在腳本里自行 2>&1 或 *>&1。

可選配置項包括 pwshPath(默認 pwsh)、idleMs(默認 30 分鐘空閒回收)、maxSessions(默認 4)、maxOutputBytes(默認 8MB)、allowUnconfined(默認 false,沙箱策略缺席時拒絕啓動而非悄悄放開)。常駐進程在啓動時經 ctx.sandbox.confine 包進與內置 pwsh 等價的 workspace 邊界;read-only 模式不啓動 pwsh_run,文檔建議該模式下繼續用內置 pwsh。

bundle 會改 profile 什麼

安裝 bundle 後,cordis.patch.yml 會自動插入兩行,無需手改 profile:

  • id: pwsh-run — 工具本體。
  • id: custom-bash — 僅 Windows 啓用(disabled: !!js process.platform !== 'win32')。

remove 會連同包一起撤掉這兩行。bundle 不會把 Linux 上的官方 tool-bash 關掉;官方行本身已在 Windows 上 disabled。

安裝與啓用

插件以 DSH bundle 形式安裝;下列命令與路徑均來自倉庫 README,<version> 須換成 npm 上已發佈的版本號(例如目錄頁或 Plugins 頁給出的最新版)。

側欄(桌面端)

Plugins → Add plugin → 填倉庫地址 https://github.com/citydirector/dsh-pwsh-plugin,再打開開關。

命令行(desktop profile)

desktop 是保留 profile,只能用桌面安裝自帶的 dsh.cmd 管理,並設置正確的 DSH_HOME(桌面 App 使用的數據根,默認思路是 ~/.dsh 下的 profile 樹):

$dsh = '<桌面端安裝目錄>\resources\runtime\cli\bin\dsh.cmd'
$env:DSH_HOME = '<DSH_HOME>'

& $dsh plugin --profile desktop add 'dsh-pwsh-plugin@<version>'

本地開發檢出可用 file: 規格(硬鏈接檢出,改代碼即時生效;registry 規格則是拷貝):

& $dsh plugin --profile desktop add 'file:<檢出目錄>'

也可直接 npm i dsh-pwsh-plugin,效果等價於讓 DSH 解析 registry 包名。README 還提到 github:citydirector/dsh-pwsh-plugin#<tag> 仍可用,但會繞開 pnpm 的 minimumReleaseAge 等供應鏈策略。

安裝後可用非保留 profile 執行 --dump-config,應能看到 # == dsh-pwsh-plugin 以及 - id: pwsh-run。若曾手寫 - id: pwsh-run 再裝 bundle,會出現重複註冊,啓動時報 tool "pwsh_run" is already registered;切換方式時須先刪手寫行再裝 bundle。

不裝成 npm 依賴時的手寫 patch(摘錄)

- insert:
    - id: pwsh-run
      name: '<路徑>/plugin/index.mjs'
      config:
        pwshPath: 'pwsh'

plugin/ 下 index.mjs、session.mjs、session-server.ps1 三文件須同目錄存放。

安裝前建議自行瀏覽 GitHub 源碼 與 LICENSE;插件與 DSH 同進程權限運行,沙箱與組合是否完整會影響 pwsh_run 能否啓動(例如缺少 ctx.sandboxPolicy 且未設 allowUnconfined: true 時會拒絕啓動)。

典型用法

啓用 pwsh_run 後,智能體每次調用只提交 script 字段裏的 PowerShell 文本,Harness 負責送進常駐會話。下面兩步體現文檔強調的有狀態會話(變量與 workdir 跨調用保留),可在 DSH 裏分兩次調用驗證。

第一次設置工作目錄並寫入變量:

Set-Location 'C:\your\workspace'
$global:buildTag = 'demo-1'
'ok'

第二次在同一 agent 工作區再調用,腳本不必重複 Set-Location,直接讀會話裏已有的值:

$global:buildTag
Get-Location

若單次腳本很長,按 README 的設計無需再爲命令行長度做分段拼接;仍須遵守 maxOutputBytes 與 timeoutMs,輸出截斷或超時會按文檔說明報錯或重建會話。

在 Windows 上啓用 bundle 後,bash 工具會走 custom-bash + llrun 路徑,寫邊界與 SSH agent socket 探測等行爲以 docs/llrun.md 爲準;驗收腳本爲倉庫內 wsl/acceptance.sh(須在未被 custom-bash 再包一層的 WSL 裏跑)。

適用場景與注意

更適合誰

  • 經常在 DSH 裏跑較長 PowerShell 腳本、或依賴 $ / here-string 且不想和 bash -c 引號層搏鬥的 Windows 桌面用戶。
  • 需要跨多次工具調用保留 pwsh 變量、Set-Location、已 Import-Module 的模塊狀態的 agent 工作流。
  • 在 Windows + WSL 組合下,希望 bash 工具對工作區外寫入(如 /mnt/c 任意寫)有 landlock 等硬邊界時,可依賴 bundle 自帶的 llrun 路徑。

務必留意的邊界

  • read-only 沙箱模式:用內置 pwsh,不要用 pwsh_run。
  • 升級插件版本會 dispose 常駐會話,僅存在於會話內的狀態會丟失;版本更新走 DSH Plugins 頁的 updateBundle / 再次 add 'dsh-pwsh-plugin@<version>',且 profile 裏須是 registry semver 規格才便於 DSH 比對版本。
  • workspace-write 下捕獲子進程 stdio 的寫法可能失敗(README 故障表有 node.exe / 管道相關說明);需要輸出時改用文檔推薦的 Start-Process 重定向等模式。
  • npm 剛發佈後的 CDN 延遲、pnpm minimumReleaseAge 導致「更新裝到舊版」屬於供應鏈策略,不是權限錯誤。

更完整的運行時限制見 docs/runtime-notes.zh-CN.md。

結尾

dsh-pwsh-plugin 把「長腳本、少轉義、會話狀態」和「WSL bash 寫邊界」收進一個 MIT 的 DSH bundle:裝完 bundle 即可用 pwsh_run,Windows 上還可一併啓用 custom-bash。若要覈對元數據、版本與安裝入口,可看 SkillHub 目錄頁 與 GitHub 倉庫 中的 README.zh-CN.md。

羽毛球分组比赛记分
小程序二维码

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

小夜