dsh-utf8-output:修復 Windows 下 DSH 子進程中文亂碼

前言

在 Windows 上用 DeepSeek Harness(DSH)跑 cmd.exe、powershell.exe 或常見本地命令時,agent 看到的 stdout/stderr 裏中文經常變成一串 � 或亂字符。錯誤信息、路徑、日誌都不可讀,排查會偏離真實輸出。問題來自子進程按系統 OEM 代碼頁(簡體中文多爲 GBK/CP936)寫字節,而 DSH 子進程服務卻一律用 UTF-8 解碼。本文介紹社區插件 dsh-utf8-output(維護者 TLEWA,分類:客戶端):在不改內核的前提下,從保留的原始字節重新解碼後再交給上層。

這是什麼

dsh-utf8-output 是 DSH 的 cordis 插件,掛到 subprocess 服務上,包裝 spawn(),對 OutputCollector 的 readFrom() / finalize() 做重解碼。目標用戶是 Windows 上使用 DSH 桌面版(profile desktop)、需要正確閱讀子進程中文輸出的開發者。許可證爲 MIT;npm 當前版本爲 0.1.1(見 package.json)。

亂碼從哪來

@deepseek-ai/dsh-subprocess-local 對 stdout/stderr 原始字節使用 Buffer#toString("utf8")。Windows 上子進程普遍按 OEM 代碼頁輸出,例如簡體中文 936 / GBK,繁體 950 / Big5,日文 932 / CP932。非法 UTF-8 會被替換成 U+FFFD(�),信息不可逆丟失,agent 只能看到亂碼;這與 bash 工具或命令寫法無關。

README 中的對比例子:亂碼時類似 ����λ�� ��:1 �ַ�: 134;安裝插件後同一輸出爲 所在位置 行:1 字符: 134。

本插件只實現簡體中文相關代碼頁:936 / GBK / GB18030 / CP936。950、932、949 沒有對應解碼器,這些語言輸出仍保持內核原樣(可能仍是亂碼),不會用 GB18030 去猜解以免錯字。

核心功能

接入方式

  1. apply(ctx) 取得 subprocess 服務並包裝 spawn()。
  2. 每個 handle 的 handle.collected.stdout / .stderr 保留原始字節的 OutputCollector。
  3. 替換上述 collector 的 readFrom() 與 finalize(),從原始字節重新解碼後交給上層。

不改命令、參數、退出碼、超時和 spillPath;純 UTF-8 / ASCII 在第 1 步判據下原樣返回。覆蓋所有走 subprocess 的調用(如 ops_bash、bash、pwsh 等)。重複加載、apply() 冪等;dispose 會還原 spawn。非 Windows 平臺 apply() 直接返回,不安裝補丁。

解碼順序

步驟 判據 結果
1 嚴格 UTF-8(fatal: true)能解 原樣返回
2 僅窗口首/尾截斷(≤3 字節殘片),其餘爲乾淨 UTF-8 寬容 UTF-8(邊緣可保留一個 U+FFFD)
3 按 GB18030 嚴格可解(必要時跳過 1–3 字節重新對齊) 按 GBK 解碼
4 都不成立 原樣返回,不比內核更差

第 2 步針對 collector 內存尾部窗口邊界截斷字符的場景,避免把大段正常中文誤判爲非 UTF-8。

安裝與啓用

要求:

  • DSH 0.2.0 或更新;
  • 內核 OutputCollector 暴露 snapshot()(0.2.x 桌面版),或早期構建的 chunks / total 字段。

插件以當前 DSH 進程權限運行;安裝前請自行查看 GitHub 倉庫 源碼與 MIT 許可證。

從 npm 安裝(推薦)

  1. 側邊欄 插件 → 安裝插件,輸入:
   dsh-utf8-output
  1. 重啓 DSH(host 插件在 profile 啓動時加載)。

命令行等價寫法:

dsh plugin --profile desktop add dsh-utf8-output

從 GitHub 安裝

https://github.com/TLEWA/dsh-utf8-output

固定到標籤:

dsh plugin --profile desktop add github:TLEWA/dsh-utf8-output#v0.1.0

從源碼安裝

git clone https://github.com/TLEWA/dsh-utf8-output.git
cd dsh-utf8-output
npm test
dsh plugin --profile desktop add .

經過上面的步驟並重啓後,無需額外配置項;子進程輸出解碼即由插件接管。

典型用法

沒有單獨的配置文件或開關。安裝並重啓後,在 Windows 上通過 DSH 執行會走 subprocess 的命令即可驗證:例如 PowerShell 報錯信息、含中文路徑的 dir 輸出,應與系統控制台語義一致,而不再是滿屏 �。

開發與自測可在克隆倉庫後執行:

npm test    # node test/run.mjs
npm run check

測試覆蓋解碼判定(UTF-8 截斷、GBK 錯位等)以及 spawn 包裝、冪等性與舊內核回退邏輯(見 README「開發與測試」)。

適用場景與注意

適合: Windows + 簡體中文 OEM 代碼頁(GBK/CP936)環境下的 DSH 用戶;依賴 agent 閱讀本地命令 stderr/stdout 的場景。

已知限制(摘自 README):

  • GBK 字節序列若恰好是合法 UTF-8,會按 UTF-8 解(概率極低)。
  • 窗口首字節截斷且殘片自成合法字符時,可能出現頭部錯字;插件不用啓發式猜解。
  • 混合 UTF-8 與 GBK 按整體判斷,不分段嗅探;UTF-16/UTF-32 不處理。
  • Big5、CP932、CP949 無解碼器。
  • 超大輸出高頻輪詢時,讀取成本仍可能偏高(窗口約 2.8KB,單次約 10µs 量級,但複雜場景仍爲 O(n²) 量級行爲)。

DSH 生態主張「一切皆插件」;SkillHub 目錄頁 爲社區收錄,與 DeepSeek / 幻方無官方從屬關係。

結尾

dsh-utf8-output 在字節進入 agent 之前,用 GB18030/GBK 路徑重解 Windows OEM 中文輸出,並儘量保持 UTF-8 輸出不變。若你在 Windows 上被 DSH 子進程亂碼拖慢排障,可按上文 npm 或 GitHub 方式安裝後重啓驗證。

  • 目錄頁:https://www.skillhub.cn/plugins/TLEWA/dsh-utf8-output
  • 源碼與文檔:https://github.com/TLEWA/dsh-utf8-output
羽毛球分组比赛记分
小程序二维码

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

小夜