前言¶
DeepSeek Harness(DSH)桌面版在本機用明文 HTTP 監聽時,每次啓動會綁定新的臨時端口,會話 Cookie 的名字會隨 host:port 變化而不斷新增,舊條目又不會被上游回收。重啓次數一多,啓動握手會把整個 Cookie jar 打進請求頭,撞上 Node 默認約 16 KB 的 max-http-header-size,界面表現爲 desktop welcome: Web authentication failed,彈窗卻建議重裝或禁用插件——兩者都不對症。
下面介紹社區插件 dsh-cookie-janitor(維護者 dududreamer,分類:客戶端)。它不做「一鍵清空 jar」,而是在每次簽發新會話 Cookie 時,把同批請求裏其餘 dsh-auth-* 名字用 Max-Age=0 收斂掉,讓桌面殼在故障復發前回到「每次啓動只淨增一條有效 Cookie」的穩態。
這是什麼¶
dsh-cookie-janitor 是 DSH 的 Cordis 客戶端插件(npm 包名 dsh-cookie-janitor,版本 1.0.0,MIT 許可證)。它掛載在連接層的授權握手與已認證 API 響應路徑上,針對本機 127.0.0.1 下因端口隨機化而堆積的 dsh-auth-<hash> Cookie 做收斂,避免啓動時 Cookie 頭過大導致 431 Request Header Fields Too Large,進而被宿主報成 Web 認證失敗。
插件以當前 DSH 進程權限運行;安裝前請自行閱讀 GitHub 倉庫 源碼與許可證。社區目錄頁:skillhub.cn/plugins/dududreamer/dsh-cookie-janitor(獨立站點,與 DeepSeek / 幻方無官方從屬關係)。
故障形態與根因(簡要)¶
桌面版啓動參數使用 --port 0,requestAudience() 對明文 HTTP 返回的 authority 含端口;Cookie 名稱爲 dsh-auth- 加 base64url(sha256(authority)),且未按端口隔離,也沒有上游 cookies.remove 邏輯。每啓動一次多一條、舊條保留 30 天,實測約在約第 72 條 Cookie 對時越界——只有啓動握手那一發 credentials: "include" 會帶上整 jar,故形態固定爲「啓動即失敗」,運行期反而正常。
HTTPS 部署下 authority 通常不含端口,一般不會堆積;該插件主要面向本機明文 HTTP 場景。
核心功能¶
經 README 與 package.json 描述,插件能力可歸納爲:
- 授權握手收斂:在
connection.authorizeIndex/connection.authorizeConnect響應中,以本次set-cookie要簽發的名字爲保留項,對其餘請求裏出現的全部dsh-auth-*追加刪除指令(Max-Age=0),且刪除行排在有效set-cookie之前,同名字後者覆蓋前者,避免誤刪當前會話。 - 運行期 API 收斂:在
connection/requestwaterfall 裏,用base64url(sha256(host))推算當前 Cookie 名;僅當該名確實出現在請求頭時才清理其它dsh-auth-*,否則跳過——失敗模式是「不動手」,代碼路徑裏沒有整 jar 清空。 - 可觀測日誌:默認把動作追加到系統臨時目錄下的
dsh-cookie-janitor.log;設環境變量DSH_COOKIE_JANITOR_LOG=off可關閉。
安裝與啓用¶
官方說明要求 DeepSeek Harness 桌面版,且能寫入 $DSH_HOME(默認 ~/.dsh)與當前 profile 目錄。DSH 生態裏擴展以本地插件 + profile 補丁層掛載爲主;沒有 dsh plugin add github:... 一類一鍵命令,需按倉庫 README 手動放置並鏈接。
1. 放入 local-plugins¶
倉庫 README 給出的獲取與拷貝方式如下(需本機已安裝 git):
git clone https://github.com/dududreamer/dsh-cookie-janitor.git
mkdir -p "$DSH_HOME/local-plugins"
cp -r dsh-cookie-janitor "$DSH_HOME/local-plugins/"
Windows PowerShell:
git clone https://github.com/dududreamer/dsh-cookie-janitor.git
New-Item -ItemType Directory -Force "$env:USERPROFILE\.dsh\local-plugins" | Out-Null
Copy-Item .\dsh-cookie-janitor "$env:USERPROFILE\.dsh\local-plugins\" -Recurse
2. 鏈接進 profile 的 node_modules¶
Windows(Junction):
$scope = "$env:USERPROFILE\.dsh\profiles\desktop\node_modules"
New-Item -ItemType Junction -Path "$scope\dsh-cookie-janitor" `
-Target "$env:USERPROFILE\.dsh\local-plugins\dsh-cookie-janitor"
macOS / Linux:
ln -s "$DSH_HOME/local-plugins/dsh-cookie-janitor" \
"$DSH_HOME/profiles/desktop/node_modules/dsh-cookie-janitor"
3. 在 profile 補丁層激活¶
編輯 $DSH_HOME/profiles/desktop/cordis.patch.yml,在末尾追加:
- insert:
- id: dsh-cookie-janitor
name: dsh-cookie-janitor
config: {}
在 profile 的 package.json 中聲明依賴,避免後續 pnpm install 清掉鏈接:
"dependencies": {
"dsh-cookie-janitor": "file:../../local-plugins/dsh-cookie-janitor"
}
4. 生效¶
若 profile 爲 patchReload: live,改完補丁層可熱加載,無需爲了「試插件」再重啓桌面殼——而反覆重啓恰恰是觸發 Cookie 堆積的條件之一。
驗證與典型日誌¶
插件不寫 UI,驗證應看日誌而非 Network/Cookies 文件體積(SQLite 頁回收後文件可能延遲縮小)。日誌路徑爲 <tmpdir>/dsh-cookie-janitor.log,README 示例:
2026-11-01T09:11:18.656Z apply loaded (pid 37868)
2026-11-01T09:11:19.676Z authorize: collapsing 39 stale cookie(s), keeping the one being issued
2026-11-01T09:11:30.173Z apply loaded (pid 14520)
2026-11-01T09:11:31.120Z authorize: collapsing 1 stale cookie(s), keeping the one being issued
第一次可能清掉數十條歷史條目;穩態後每次啓動通常只清 1 條陳舊項,與 README 描述一致。
回滾¶
任選一步即可停用:
- 刪除
cordis.patch.yml末尾的dsh-cookie-janitorinsert 段; - 刪除 profile 下
node_modules/dsh-cookie-janitor鏈接。
手動刪掉 Network/Cookies 只能臨時救場一次,不裝插件時故障仍會隨重啓復發。
適用場景與注意¶
適合:已在桌面版遇到 desktop welcome: Web authentication failed、且根因是本機明文 HTTP 下 dsh-auth-* 堆積的用戶,在 upstream 修正端口進 Cookie 名或增加 prune 之前,需要本機可用的收斂方案。
不必裝:HTTPS 部署或從未出現啓動即認證失敗的情況。
邊界:上游若更改 Cookie 命名算法,waterfall 側會因算出的名字不在請求頭而靜默停手,屆時需同步插件邏輯;授權側仍依賴響應自帶的 set-cookie 名字。更完整的證據鏈見倉庫 docs/root-cause.md。
結尾¶
dsh-cookie-janitor 用「收斂而非清空」的方式,把端口隨機化帶來的 dsh-auth-* 堆疊壓回單條有效會話,避免 Node 請求頭預算在啓動握手處被耗盡。目錄頁:https://www.skillhub.cn/plugins/dududreamer/dsh-cookie-janitor;源碼與安裝細節:https://github.com/dududreamer/dsh-cookie-janitor。