dsh-connect-workbuddy 5.6.1 → 5.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.6.2 (2026-10-23)
4
+
5
+ > 补丁版本:修 5.6.0/5.6.1 里「折后价读不出来」的原因。**请求路径、provider 路由、计费与凭据一律未变。**
6
+
7
+ ### Fixes
8
+
9
+ - **真实促销的 `displayMode` 是 `strikethrough`,只认 `replace` 等于把折扣全丢了(#120,第二次报告)**
10
+ - **症状**:徽标亮着,价格不动。模型行显示 `DeepSeek-V4.1-Flash · x0.11` 配「夜间折扣」。
11
+ - **查证方式**:直接把国内区 `/v3/config` 的 8 条 `modelPromotions` 原文 dump 出来逐条比对,而不是继续照着此前文档里的样例推断(样例只出现过 `replace`)。
12
+ - **真实数据**(2026-10-23 实测,8 条):
13
+ | id | 标签 | `discount` | `displayMode` |
14
+ | --- | --- | --- | --- |
15
+ | `glm-52-night-discount-202607` | 夜间折扣 | `"0.50x"` | **`strikethrough`** |
16
+ | `hy4-night-discount-daytime-badge-202609` | 夜间免费 | `"0.00x"` | **`strikethrough`** |
17
+ | `step-5-discount-daytime-badge-202610` | 独家限免 | `"0.00x"` | **`strikethrough`** |
18
+ | `hy3-free-trial-202608` | 限时免费 | `"0x"` | `replace` |
19
+ | `glm-52-…-daytime-badge`、`hy4-…-badge`、`ds-discount-daytime-badge-202608`、`space-bunny-discount-202610` | — | 无 | — |
20
+ - **根因**:原实现把 `displayMode` 硬写成 `'replace'`(唯一的样例来源),解析时把 `strikethrough` 当成未知值丢弃,判定时也只放行 `replace`。于是**八条里三条带价格的折扣一条都不生效**,只有 hy3 的 `replace` 能过。
21
+ - **修法**:两种观测到的拼写都认。语义上它们都是「折后价才是实付价」,区别只在客户端是否同时把原价划掉——本插件每行只画一个数字,所以两者等价处理。**仍不认没标 `displayMode` 的 `discount`**:字段缺失不说明该怎么读那个数,猜成 `replace` 就是凭猜改价。
22
+ - **顺带确认不是 bug 的一条**:`ds-discount-daytime-badge-202608`(`deepseek-v4.1-flash` / `deepseek-v4-pro`)的 `discount` 就是 **`null`**,时段 `0:00→23:59` 几乎全天。所以这两个模型「徽标亮着但价格是目录价」是**上游没给折后价**,不是插件漏读。这条单独写了测试钉住:没有数字就**不能**编一个。
23
+ - **测试**:`tests/issue120-promo-discount.spec.ts` 增至 14 条,新增四条用的是**真实原文**(不是样例形状)——`strikethrough` 生效(`0.50x` → 0.50)、`0.00x` 免费算作 0 而不是「没有」、**only-badge 条目(deepseek 那条)徽标有、价格不动**、仍拒绝没有 `displayMode` 的折扣。原「未知 displayMode」那条改成用一个真正不存在的值,避免把已观测值钉成未知。
24
+
3
25
  ## 5.6.1 (2026-10-23)
4
26
 
5
27
  > 补丁版本:修 5.6.0 自己引入的一处显示回退。**请求路径、provider 路由、计费与凭据一律未变。**
package/lib/bin.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { C as defaultDesktopAuthCandidates, L as WorkBuddyUpstreamClient, M as workbuddyOwnAuthPath, Mt as hostPeersInfo, a as readHostHeartbeat, b as WorkBuddyCredentialStore, c as WORKBUDDY_CONNECT_VERSION, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, k as legacyWorkbuddyOwnAuthPath, l as piAiRuntimeInfo, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS, vt as WORKBUDDY_APP_EXECUTABLE_ENV, w as defaultDesktopAuthDirs, wt as findWorkbuddyAppExecutableWithSource, y as WORKBUDDY_AUTH_FILE_ENV } from "./host-heartbeat-CEYnXXF3.js";
2
+ import { C as defaultDesktopAuthCandidates, L as WorkBuddyUpstreamClient, M as workbuddyOwnAuthPath, Mt as hostPeersInfo, a as readHostHeartbeat, b as WorkBuddyCredentialStore, c as WORKBUDDY_CONNECT_VERSION, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, k as legacyWorkbuddyOwnAuthPath, l as piAiRuntimeInfo, o as workbuddyHostHeartbeatPath, r as isHeartbeatProcessAlive, u as FALLBACK_WORKBUDDY_MODELS, vt as WORKBUDDY_APP_EXECUTABLE_ENV, w as defaultDesktopAuthDirs, wt as findWorkbuddyAppExecutableWithSource, y as WORKBUDDY_AUTH_FILE_ENV } from "./host-heartbeat-DWoUWD70.js";
3
3
  import { realpathSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/bin.ts
package/lib/client.js CHANGED
@@ -2083,7 +2083,7 @@ window.__ModuleLoader__.load({
2083
2083
  for (const promo of sorted) {
2084
2084
  const discount = promo.discount;
2085
2085
  if (discount === void 0 || discount.multiplier === void 0) continue;
2086
- if (discount.displayMode !== "replace") continue;
2086
+ if (discount.displayMode !== "replace" && discount.displayMode !== "strikethrough") continue;
2087
2087
  if (!promoActiveAt(promo, nowMs)) continue;
2088
2088
  return discount.multiplier;
2089
2089
  }
@@ -1570,7 +1570,7 @@ function parseDiscount(value) {
1570
1570
  const fromString = multiplierOfCredits(raw["discountedCredits"]);
1571
1571
  const fromFactor = typeof raw["factor"] === "number" && Number.isFinite(raw["factor"]) && raw["factor"] >= 0 ? raw["factor"] : void 0;
1572
1572
  const multiplier = fromString ?? fromFactor;
1573
- const displayMode = raw["displayMode"] === "replace" ? "replace" : void 0;
1573
+ const displayMode = raw["displayMode"] === "replace" || raw["displayMode"] === "strikethrough" ? raw["displayMode"] : void 0;
1574
1574
  if (multiplier === void 0 && displayMode === void 0) return void 0;
1575
1575
  return {
1576
1576
  ...multiplier === void 0 ? {} : { multiplier },
@@ -6121,7 +6121,7 @@ function generationOf(version) {
6121
6121
  //#endregion
6122
6122
  //#region src/version.ts
6123
6123
  /** The npm package version this build was produced from. */
6124
- const WORKBUDDY_CONNECT_VERSION = "5.6.1";
6124
+ const WORKBUDDY_CONNECT_VERSION = "5.6.2";
6125
6125
  //#endregion
6126
6126
  //#region src/host-heartbeat.ts
6127
6127
  /**
package/lib/index.d.ts CHANGED
@@ -792,11 +792,30 @@ interface WorkBuddyPromoDiscount {
792
792
  */
793
793
  multiplier?: number;
794
794
  /**
795
- * The upstream's display instruction. `'replace'` means "show this instead of
796
- * the normal multiplier"; anything else is not yet observed, so it is not
797
- * acted on.
798
- */
799
- displayMode?: 'replace';
795
+ * The upstream's display instruction — how the discounted figure relates to
796
+ * the catalog one. BOTH spellings below are observed on the live CN feed
797
+ * (2026-10-23, eight entries dumped from `/v3/config`):
798
+ *
799
+ * `'replace'` — show the discounted figure INSTEAD of the normal one.
800
+ * Used by `hy3-free-trial-202608` (`"0x"`).
801
+ * `'strikethrough'` — the upstream's own client strike out the normal price
802
+ * and print the discounted one. Used by
803
+ * `glm-52-night-discount-202607` (`"0.50x"`),
804
+ * `hy4-night-discount-daytime-badge-202609` (`"0.00x"`)
805
+ * and `step-5-discount-daytime-badge-202610`.
806
+ *
807
+ * An earlier version accepted only `'replace'`, which silently dropped every
808
+ * real CN discount except the hy3 trial — the price never moved while the
809
+ * badge was lit (issue #120, second report). Both modes mean "the discounted
810
+ * figure is what you pay"; they differ only in whether the old figure is also
811
+ * shown on screen, which this plugin does not do either way (one number per
812
+ * row), so both are honoured identically here.
813
+ *
814
+ * `undefined` means the entry carries a discount the upstream did not label.
815
+ * That is NOT acted on: the field's absence says nothing about how to read
816
+ * the figure, and guessing "replace" would change a price on a guess.
817
+ */
818
+ displayMode?: 'replace' | 'strikethrough';
800
819
  }
801
820
  /** The upstream's explanatory copy for the badge. */
802
821
  interface WorkBuddyPromoHover {
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as prepareChatBody, A as parseWorkBuddyAuth, At as readAtRestKey, B as declaredTools, C as defaultDesktopAuthCandidates, Ct as findWorkbuddyAppExecutable, D as isEncryptedCredentialError, Dt as macosBundleExecutable, E as hasEncryptedCredentialFields, Et as isWorkbuddyBundle, F as WORKBUDDY_FALLBACK_SYSTEM_PROMPT, Ft as writeFileAtomic, G as isFirstMessageGateBody, H as isContextTooLongBody, I as WorkBuddyCredentialRejectedError, J as openingEvidenceOfBody, K as knownRegionOf, L as WorkBuddyUpstreamClient, M as workbuddyOwnAuthPath, N as CONTEXT_OVERFLOW_MARKER, Nt as resolveDshHome, O as isVaultAccountId, Ot as macosNestedAppBundles, P as CREDENTIAL_REJECTED_CODE, Pt as withFileLock, Q as perturbChannelFingerprints, R as channelGateMemberOf, S as authFileName, St as fetchAtRestKeyPayload, T as defaultDesktopAuthPath, Tt as isEncryptedFieldWrapper, U as isConversationIdGateBody, V as forceNeutralHead, W as isCredentialRejectedError, X as parseReasoning, Y as parseCreditMultiplier, Z as parseUpstreamModel, _ as ENCRYPTED_CREDENTIAL_CODE, _t as nativeModalityOf, a as readHostHeartbeat, at as lastRefusalFor, b as WorkBuddyCredentialStore, bt as deriveAtRestKey, c as WORKBUDDY_CONNECT_VERSION, ct as recordRefusal, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, dt as WorkBuddyImageError, et as regionOf, f as WorkBuddyCatalog, ft as pickImageModel, g as withoutRouters, gt as imageDefaultFor, h as fallbackModelsFor, ht as NATIVE_MODALITY_BY_MODEL_ID, i as processStartTimeMs, it as defaultOffModelIds, j as workbuddyAccountId, jt as workbuddyAppExecutableCandidates, k as legacyWorkbuddyOwnAuthPath, kt as openEncryptedField, l as piAiRuntimeInfo, lt as withEffectiveOff, m as deriveCatalog, mt as queueNoticeText, n as clearHostHeartbeat, nt as attachBusyLevels, o as workbuddyHostHeartbeatPath, ot as offDefaultFor, p as applyContextBudgets, pt as parseQueueAnswer, q as modelIdOfBody, r as isHeartbeatProcessAlive, rt as REFUSES_OFF_MODEL_IDS, s as writeHostHeartbeat, st as offRefused, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, tt as requestEvidenceOf, u as FALLBACK_WORKBUDDY_MODELS, ut as DEFAULT_IMAGE_SIZE, v as WORKBUDDY_AUTH_FILENAME, vt as WORKBUDDY_APP_EXECUTABLE_ENV, w as defaultDesktopAuthDirs, x as WorkBuddyEncryptedCredentialError, xt as deriveAtRestKeyId, y as WORKBUDDY_AUTH_FILE_ENV, yt as clearAtRestKeyCache, z as classifyUpstreamError } from "./host-heartbeat-CEYnXXF3.js";
1
+ import { $ as prepareChatBody, A as parseWorkBuddyAuth, At as readAtRestKey, B as declaredTools, C as defaultDesktopAuthCandidates, Ct as findWorkbuddyAppExecutable, D as isEncryptedCredentialError, Dt as macosBundleExecutable, E as hasEncryptedCredentialFields, Et as isWorkbuddyBundle, F as WORKBUDDY_FALLBACK_SYSTEM_PROMPT, Ft as writeFileAtomic, G as isFirstMessageGateBody, H as isContextTooLongBody, I as WorkBuddyCredentialRejectedError, J as openingEvidenceOfBody, K as knownRegionOf, L as WorkBuddyUpstreamClient, M as workbuddyOwnAuthPath, N as CONTEXT_OVERFLOW_MARKER, Nt as resolveDshHome, O as isVaultAccountId, Ot as macosNestedAppBundles, P as CREDENTIAL_REJECTED_CODE, Pt as withFileLock, Q as perturbChannelFingerprints, R as channelGateMemberOf, S as authFileName, St as fetchAtRestKeyPayload, T as defaultDesktopAuthPath, Tt as isEncryptedFieldWrapper, U as isConversationIdGateBody, V as forceNeutralHead, W as isCredentialRejectedError, X as parseReasoning, Y as parseCreditMultiplier, Z as parseUpstreamModel, _ as ENCRYPTED_CREDENTIAL_CODE, _t as nativeModalityOf, a as readHostHeartbeat, at as lastRefusalFor, b as WorkBuddyCredentialStore, bt as deriveAtRestKey, c as WORKBUDDY_CONNECT_VERSION, ct as recordRefusal, d as FALLBACK_WORKBUDDY_MODELS_GLOBAL, dt as WorkBuddyImageError, et as regionOf, f as WorkBuddyCatalog, ft as pickImageModel, g as withoutRouters, gt as imageDefaultFor, h as fallbackModelsFor, ht as NATIVE_MODALITY_BY_MODEL_ID, i as processStartTimeMs, it as defaultOffModelIds, j as workbuddyAccountId, jt as workbuddyAppExecutableCandidates, k as legacyWorkbuddyOwnAuthPath, kt as openEncryptedField, l as piAiRuntimeInfo, lt as withEffectiveOff, m as deriveCatalog, mt as queueNoticeText, n as clearHostHeartbeat, nt as attachBusyLevels, o as workbuddyHostHeartbeatPath, ot as offDefaultFor, p as applyContextBudgets, pt as parseQueueAnswer, q as modelIdOfBody, r as isHeartbeatProcessAlive, rt as REFUSES_OFF_MODEL_IDS, s as writeHostHeartbeat, st as offRefused, t as WORKBUDDY_HOST_HEARTBEAT_FILENAME, tt as requestEvidenceOf, u as FALLBACK_WORKBUDDY_MODELS, ut as DEFAULT_IMAGE_SIZE, v as WORKBUDDY_AUTH_FILENAME, vt as WORKBUDDY_APP_EXECUTABLE_ENV, w as defaultDesktopAuthDirs, x as WorkBuddyEncryptedCredentialError, xt as deriveAtRestKeyId, y as WORKBUDDY_AUTH_FILE_ENV, yt as clearAtRestKeyCache, z as classifyUpstreamError } from "./host-heartbeat-DWoUWD70.js";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { appendFile, mkdir, open, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
4
4
  import { randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-connect-workbuddy",
3
3
  "displayName": "DSH Connect WorkBuddy",
4
4
  "description": "把本机登录的 WorkBuddy 模型(国内版与国际版)接入 DeepSeek Harness:每次刷新按上游目录自动读取每个模型的积分倍率,支持逐模型图片输入开关、多账号切换与账号池自动换号,并提供每日签到、卡片与输入框里的胶囊积分读数等只读积分概览。",
5
- "version": "5.6.1",
5
+ "version": "5.6.2",
6
6
  "author": "dingminhua",
7
7
  "copyright": "Copyright (c) 2026 LaoDing",
8
8
  "license": "MIT",