dsh-connect-trae 4.4.3 → 4.4.4

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,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.4.4 (2026-10-23)
4
+
5
+ > **同价的会员分支不再被读成第二重折扣;顺手补上官方客户端渲染链路的取证。**
6
+ >
7
+ > 合并自 PR #53。真机截图比对时发现:同一个 `deepseek-v4.1-flash`,插件胶囊写「闲时 5 折」、
8
+ > 官方客户端写「会员 5 折」、详情栏又并排列出两段一模一样的 5 折——查下来不是渲染错,
9
+ > 是我们把**同一个折后价的两条资格路径**讲成了两层折扣。
10
+
11
+ ### 修复
12
+
13
+ - **不再把「同价的会员分支」说成第二重折扣**(`fix(promo)`,真机截图比对时发现)。
14
+ `deepseek-v4.1-flash` 的活动 `off_peak_member_discount_18_9` 里,`member` 与 `off_peak` 是
15
+ **同一个折后价的两条资格路径**(实测 2026-10-23:两者都是 `0.12 → 0.06, discount 50`;
16
+ 会员全天可享,非会员只在闲时窗口内可享)。旧悬停无条件引用 `member` 并写「会员价另有 5 折」,
17
+ 读起来就是 0.06 再打五折 = 0.03 —— 上游从来没有这个价。现在 `badgeOf()` 比较两条分支的
18
+ **折后价**,只有 `member.rate < 现价` 才带会员价,且文案改成给绝对数
19
+ (`会员价 0.06 积分/百万 token(5 折)` / `subscription price is 0.06 credits/Mtoken (50% off)`);
20
+ 等值时整句不出现。
21
+ **顺带**:`current` 判定出来的「闲时」徽标,若本地时钟确认某个窗口正开着,现在会把该窗口
22
+ (起止 + 时区)挂上去 —— 以前只有本地窗口算出来的徽标带时段,于是有「写着闲时 5 折、
23
+ 悬停却说不出时段」的形状。时钟与上游不一致时不补,宁可少说。
24
+ **取证**:官方客户端同一行显示「会员 5 折」、详情栏并排列出两段 5 折,是因为它读的是服务端
25
+ 下发的渲染配置(`featureOrder` + Jexl + `tag`/`tooltip.sections`),不是自己判折扣;
26
+ 链路与实测写入 `docs/PROMO_CLIENT_RENDER.md`,`docs/PROMO_BADGE.md` §3/§4 同步补注。
27
+ **测试**:`promo.spec.ts` 新增「同价会员分支不引用」「上游闲时判定补时段」「时钟不认时不补」
28
+ 三条;`card-promo.spec.tsx` 与 `model-label-slot.spec.tsx` 各新增一条悬停断言。
29
+ **验证**:`tsc` 两端静默;`vitest run` **81 文件 / 1019 条全过**(4.4.3 基线 1014 + 新增 5,
30
+ 合并后 main 上复核实测);`tsdown` 两个 build 通过,体积与 4.4.3 持平。
31
+
3
32
  ## 4.4.3 (2026-10-23)
4
33
 
5
34
  > **模型选择器里也看得见活动优惠;账号池信息架构对齐 workbuddy;顺带修一个会让已保存设置
package/lib/client.js CHANGED
@@ -490,17 +490,39 @@ window.__ModuleLoader__.load({
490
490
  if (price.beforeRate <= 0 || price.rate >= price.beforeRate) return void 0;
491
491
  return Math.round(price.rate / price.beforeRate * 100);
492
492
  }
493
+ /**
494
+ * The member price, but only when it beats the rate the badge is already showing.
495
+ *
496
+ * Two rates on the same base are two ways to reach one price: `member` quoting
497
+ * 0.06 beside a live 0.06 is not "another 5 折". Comparing the post-discount
498
+ * numbers is the only honest test — a branch with no rate cannot be shown to be
499
+ * cheaper, so it is not quoted at all.
500
+ */
501
+ function cheaperMemberOf(price, discount) {
502
+ const member = discount.member;
503
+ if (member === void 0 || member.rate === void 0) return void 0;
504
+ if (price.rate === void 0 || member.rate >= price.rate) return void 0;
505
+ const discountPercent = discountOf(member);
506
+ if (discountPercent === void 0) return void 0;
507
+ return {
508
+ rate: member.rate,
509
+ discountPercent
510
+ };
511
+ }
493
512
  function badgeOf(kind, price, discount, window) {
494
513
  const discountPercent = discountOf(price);
495
514
  if (discountPercent === void 0) return void 0;
496
- const memberDiscountPercent = discount.member === void 0 ? void 0 : discountOf(discount.member);
515
+ const member = cheaperMemberOf(price, discount);
497
516
  return {
498
517
  kind,
499
518
  discountPercent,
500
519
  percentOff: 100 - discountPercent,
501
520
  ...price.beforeRate === void 0 ? {} : { beforeRate: price.beforeRate },
502
521
  ...price.rate === void 0 ? {} : { rate: price.rate },
503
- ...memberDiscountPercent === void 0 ? {} : { memberDiscountPercent },
522
+ ...member === void 0 ? {} : {
523
+ memberDiscountPercent: member.discountPercent,
524
+ memberRate: member.rate
525
+ },
504
526
  ...window === void 0 ? {} : {
505
527
  fromClock: clockOf(window.startMinute),
506
528
  untilClock: clockOf(window.endMinute),
@@ -520,7 +542,8 @@ window.__ModuleLoader__.load({
520
542
  const current = discount.current;
521
543
  if (current !== void 0) {
522
544
  if ((current.discountType ?? "none") !== "none" && (current.beforeRate === void 0 || current.rate === void 0 || current.rate < current.beforeRate)) {
523
- const badge = badgeOf(kindOf(discount), current, discount);
545
+ const kind = kindOf(discount);
546
+ const badge = badgeOf(kind, current, discount, kind === "offPeak" ? runningWindow(discount, now, defaultTimeZone) : void 0);
524
547
  if (badge !== void 0) return badge;
525
548
  }
526
549
  }
@@ -3660,7 +3683,8 @@ window.__ModuleLoader__.load({
3660
3683
  until: badge.untilClock,
3661
3684
  zone: badge.timeZone
3662
3685
  }));
3663
- if (badge.memberDiscountPercent !== void 0) hints.push(t("row.promoHintMember", {
3686
+ if (badge.memberDiscountPercent !== void 0 && badge.memberRate !== void 0) hints.push(t("row.promoHintMember", {
3687
+ rate: String(badge.memberRate),
3664
3688
  zhe: promoZhe$1(badge.memberDiscountPercent),
3665
3689
  percent: String(100 - badge.memberDiscountPercent)
3666
3690
  }));
@@ -6273,7 +6297,7 @@ window.__ModuleLoader__.load({
6273
6297
  "row.promoOffPeak": "Off-peak {percent}% off",
6274
6298
  "row.promoHintRate": "was {before} credits/Mtoken, now {rate}",
6275
6299
  "row.promoHintWindow": "off-peak hours {from}–{until} ({zone})",
6276
- "row.promoHintMember": "subscription price is a further {percent}% off",
6300
+ "row.promoHintMember": "subscription price is {rate} credits/Mtoken ({percent}% off)",
6277
6301
  "row.modelEnabled": "Enabled",
6278
6302
  "row.discard": "Discard changes",
6279
6303
  "row.save": "Save",
@@ -6624,7 +6648,7 @@ window.__ModuleLoader__.load({
6624
6648
  "row.promoOffPeak": "闲时 {zhe} 折",
6625
6649
  "row.promoHintRate": "原价 {before} 积分/百万 token,现价 {rate}",
6626
6650
  "row.promoHintWindow": "闲时时段 {from}–{until}({zone})",
6627
- "row.promoHintMember": "会员价另有 {zhe} 折",
6651
+ "row.promoHintMember": "会员价 {rate} 积分/百万 token({zhe} 折)",
6628
6652
  "row.modelEnabled": "启用模型",
6629
6653
  "row.discard": "放弃修改",
6630
6654
  "row.save": "保存",
@@ -7041,7 +7065,8 @@ window.__ModuleLoader__.load({
7041
7065
  until: badge.untilClock,
7042
7066
  zone: badge.timeZone
7043
7067
  }));
7044
- if (badge.memberDiscountPercent !== void 0) hints.push(fillPlaceholders(copy["row.promoHintMember"], {
7068
+ if (badge.memberDiscountPercent !== void 0 && badge.memberRate !== void 0) hints.push(fillPlaceholders(copy["row.promoHintMember"], {
7069
+ rate: String(badge.memberRate),
7045
7070
  zhe: promoZhe(badge.memberDiscountPercent),
7046
7071
  percent: String(100 - badge.memberDiscountPercent)
7047
7072
  }));
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-connect-trae",
3
3
  "displayName": "DSH Connect Trae",
4
4
  "description": "把本机登录的 Trae 模型接入 DeepSeek Harness:国内版与国际版双供应商并行,提供用量/积分概览与每日签到领取。",
5
- "version": "4.4.3",
5
+ "version": "4.4.4",
6
6
  "author": "dingminhua",
7
7
  "copyright": "Copyright (c) 2026 LaoDing",
8
8
  "license": "MIT",