dsh-staging-hunter:把 DSH 桌面端留在夜間版灰度第一批

前言

DSH(DeepSeek Harness)桌面端通過 electron-updater 的 staging 機制控制 nightly 版的放量比例:官方 feed 裏的 stagingPercentage(0–100)決定多少人會收到新版。技術上,一臺機器是否入圈,取決於它本地 .updaterId 文件中 UUID 的確定性桶值。這意味着有些機器的桶值天生偏後,放量比例不夠大就永遠收不到更新。

dsh-staging-hunter 解決這個問題:它把 .updaterId 釘在一個目標桶值(默認 1%),並在文件被應用改回隨機值時自動修正。維護者是 ChenXu233,MIT 許可,客戶端類插件。

這是什麼

一句話:一個 DSH 桌面端插件,用來固定 electron-updater 的 staging 身份,讓本機穩定落在夜間版灰度的第一批。

它不改安裝包來源,也不跳過簽名校驗。改的只是本地一個“我是誰”的標籤。

工作方式:釘住 .updaterId 的低位桶值

先看 DSH 桌面端判斷本機是否入圈的原始邏輯(位於 app.asar -> node_modules/electron-updater/out/AppUpdater.js):

stagingPercentage = parseInt(updateInfo.stagingPercentage, 10) / 100
const val = UUID.parse(stagingUserId).readUint32BE(12)
const percentage = val / 0xffffffff
return percentage < stagingPercentage   // 嚴格小於

關鍵點有兩個:

  • 桶值是 UUID 的確定性哈希,取自 UUID 第 12–15 字節。一臺機器一旦有 .updaterId,就永遠落在固定桶位。
  • 這是嚴格小於比較。只要 stagingPercentage 大於本機桶值,本機就在圈內。

因此把桶值壓低即可穩定入圈。插件的行爲(按 README):

  1. 啓動時讀 .updaterId;若桶值已低於上限,就沿用現有身份,不換 UUID。
  2. 否則生成一個合法 v4 UUID,把 bytes[12..15] 精確寫成目標桶值,備份原文件後寫回。
  3. 把釘住的 UUID 存進 .staging-hunter.json(sidecar),保證跨啓動身份穩定。
  4. 用 fs.watch 加上定時巡檢守着文件:被應用改回隨機值時立刻改回來。
  5. 插件卸載時自動關閉 watcher 與定時器。

安裝與啓用

從 npm 安裝(推薦):

dsh plugin add dsh-staging-hunter

按提示批准後重啓 DSH,插件會自動挑一個低位桶 UUID 並開始守護。

也可以從源碼或手工掛進 profile,倉庫不會自動寫你的 profile。兩種方式:

作爲 bundle 包,先把倉庫放進 profile 的 node_modules(Windows 用目錄聯接,避免觸發 pnpm 重裝):

cmd //c mklink /J "%USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-staging-hunter" "E:\git\dsh-staging-hunter"

然後在 ~/.dsh/profiles/desktop/package.json 的 dependencies 與 dsh.profile.bundles 裏各加一行 "dsh-staging-hunter"。

或者直接寫進 profile 的補丁層,在 ~/.dsh/profiles/desktop/cordis.patch.yml 追加:

- insert:
    - id: dsh-staging-hunter
      name: 'dsh-staging-hunter'
      config:
        targetPercentage: 1

改完重啓 DSH 桌面端,啓動日誌裏應出現:

[staging-hunter] pinned updaterId (startup) -> <uuid>  bucket=1.000000%
[staging-hunter] watching ...\.updaterId  ceiling=1%  pinnedBucket=1.000000%

日誌出現這兩條,說明身份已釘住且守護已啓動。

配置項

可選配置如下,不配置時使用默認值:

鍵 默認 說明
enabled true 總開關
targetPercentage 1 桶值上限(%)。桶值低於它即視爲在第一批
uuid '' 釘死的 UUID;留空自動挑選/生成
updaterIdPath '' .updaterId 路徑覆蓋;留空自動探測
checkIntervalMs 60000 巡檢間隔;0 表示只靠 fs.watch

典型用法

默認即裝即用:部署後重啓 DSH 桌面端,再從啓動日誌確認插件已完成初始化。日誌裏第一條是啓動時釘住 updaterId 的結果,第二條說明守護目標與上限已生效。

如果機器上的 .updaterId 路徑不在默認探測範圍內,用 updaterIdPath 指過去;如果要換一個自備的 UUID,填 uuid,留空則插件自動生成。甲乙雙方如需只在文件變化時響應,可把 checkIntervalMs 設爲 0,完全交給 fs.watch。

適用場景與注意事項

適合想穩定跟 nightly 版、且機器因桶值偏高長期收不到新版的 DSH 桌面端用戶。

需要注意幾點:

  • 完整性不受影響。插件只改本地身份標籤,安裝包仍從官方地址下載,並按 feed 裏的 sha512 與安裝器 publisherName 驗籤。
  • 需要重啓。AppUpdater 用 Lazy 緩存 stagingUserIdPromise,寫回的值在下一次啓動的更新檢查中才生效。
  • nightly 本身有風險,會穩定收到 rc 版本,可能遇到崩潰或破壞性變更。
  • 行爲變化:舊行爲是“不在圈內就停在當前版本”,裝插件後會持續跟進最新 nightly。
  • 插件以當前 DSH 進程權限運行,安裝前應檢查源碼與許可證。許可證爲 MIT,倉庫公開可查。README 標註兼容 dshReleases: 0.2.1-rc.5。

結尾

dsh-staging-hunter 做的事很窄:理解 electron-updater staging 的哈希分桶,然後用一個持久化的低位 UUID 加文件守護把本機固定在第一批。適合明確想跟 nightly 的人,不想跟的話不必裝。

目錄頁:https://www.skillhub.cn/plugins/ChenXu233/dsh-staging-hunter
GitHub:https://github.com/ChenXu233/dsh-staging-hunter

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

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

小夜