dsh-workbuddy-xdpool 1.7.4 → 1.7.5
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 +59 -0
- package/lib/client.js +165 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,65 @@
|
|
|
4
4
|
|
|
5
5
|
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
6
6
|
|
|
7
|
+
## 1.7.5 — 模型列表会告诉你「现在用哪个不花钱」
|
|
8
|
+
|
|
9
|
+
> Hy4 preview 晚上 23 点到早上 8 点免费,Hy3 一直在免费期 —— 现在卡片上直接看得出来。
|
|
10
|
+
|
|
11
|
+
**你会看到**:模型列表里,**当前免费的排在最上面**并带标记:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
[免费] hy3 x0.00
|
|
15
|
+
auto
|
|
16
|
+
(23:00 起免费 · 活动至 10-31) hy4-preview x0.29
|
|
17
|
+
hy3-x x0.05
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
到了晚上 23 点,同一行会变成:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
[免费至 08:00 · 活动至 10-31] hy4-preview x0.29
|
|
24
|
+
[免费] hy3 x0.00
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**为什么需要专门做**:因为**上游接口不说这件事**。我拉了真实的国内版接口逐字段核对:
|
|
28
|
+
|
|
29
|
+
| 信息 | 上游提供吗 |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Hy3 限免 | ✅ 提供 —— `credits: "x0.00"`,倍率本身就是 0,我们一直在正确显示 |
|
|
32
|
+
| Hy4 preview **夜间**限免 | ❌ **不提供** —— 倍率恒为 `x0.29`,**没有任何时段字段** |
|
|
33
|
+
| Hy4 preview **新用户 14 天**额度 | ❌ **不提供** —— 积分包里也没有这类条目 |
|
|
34
|
+
|
|
35
|
+
所以夜间限免这条规则,只能由插件自己带。我把它写成一张**规则表**(`src/promo.ts`),包含「哪个平台、哪些 id 前缀、哪些小时、有效期到哪天」。
|
|
36
|
+
|
|
37
|
+
**几个刻意的设计**:
|
|
38
|
+
|
|
39
|
+
- **规则区分平台**。这是**国内版活动**,所以规则里带 `region: 'cn'`,**国际版完全不受影响** —— 国际版的 `hy4-preview-f` 显示「免费」是因为**上游倍率真的是 0**(客观事实),不是我们套了活动规则;
|
|
40
|
+
- **免费状态是「此刻」的,不是模型固有属性**。所以同一天里 `hy4-preview` 的标记会变 —— 这才是真实情况;
|
|
41
|
+
- **窗口外只给一个低调的虚线提示**(`23:00 起免费`),**不给「免费」徽章**。因为它此刻**确实要花积分**,标成免费会让你花错钱;
|
|
42
|
+
- **只有「此刻免费」的才置顶**。窗口外的模型不置顶,否则就是把一个要花钱的模型举到最前面,误导性更强;
|
|
43
|
+
- **标出活动截止日**(`活动至 10-31`)。方便你安排什么时候用 —— 而且活动一旦延期,改日期就能看到,不用翻更新日志;
|
|
44
|
+
- **规则带过期日期**,到 10 月 31 日之后**自动失效**,不需要有人记得来删代码;
|
|
45
|
+
- **`hy4-preview` 用前缀匹配**,因为上游有 `hy4-preview` 和 `hy4-preview-x` 两个 id,是同一款产品。
|
|
46
|
+
|
|
47
|
+
### 关于「新用户 14 天免费额度」——明确没做
|
|
48
|
+
|
|
49
|
+
你提到「新用户没用过 Hy4 preview,还能免费 14 天,要区分出来」。**这个我做不到,而且硬做会更糟**:
|
|
50
|
+
|
|
51
|
+
上游**完全不记录**「这个账户有没有用过 Hy4 preview」—— 模型目录里没有、积分包里也没有(我实测过,44 个积分包里没有一个试用额度条目)。
|
|
52
|
+
|
|
53
|
+
唯一能猜的办法是「插件自己记住第一次调用的时间」。但这有个致命问题:**它只知道「用本插件之后」的历史**。你之前要是在官方客户端用过 Hy4 preview,插件照样会以为你是新用户,然后给你标一个**假的「免费」** —— 而你会因此放心去用,结果**扣了积分**。
|
|
54
|
+
|
|
55
|
+
**给你一个假的「免费」,比不给你标记更糟**,因为它直接改变你的花钱决定。所以这条留白,不做推测。
|
|
56
|
+
|
|
57
|
+
如果你确实需要,可行的做法是**你自己确认**:卡片上显示的是客观事实(倍率 + 夜间窗口),你清楚自己是不是新用户,看一眼就知道该不该用。
|
|
58
|
+
|
|
59
|
+
### 验证
|
|
60
|
+
|
|
61
|
+
- 类型检查全绿,测试 **297 项全绿**(+19)。
|
|
62
|
+
- 新增 `tests/promo.test.ts`:23:00–08:00 窗口内/外的判定、跨午夜(23 点在窗口内、8 点不在)、窗口关闭时间(`免费至 08:00`)、下次开启时间(`23:00 起免费`)、同族 id(`hy4-preview` 与 `hy4-preview-x`)、零倍率模型全天免费且不误入夜间规则、**到期自动失效**(10/31 有效、11/1 失效)、**免费置顶只认「此刻」免费**、**活动截止日随状态带出**、**国际版不受活动影响**(但零倍率模型在两边都算免费)。
|
|
63
|
+
- **反向验证**:清空夜间小时 → 7 项变红;删掉过期日期 → 2 项变红;**移除平台过滤 → 「国际版不受影响」变红**。确认测试真的能抓住这三类缺陷。
|
|
64
|
+
- 用**两个平台的真实清单**(国内版 16 个 / 国际版 24 个)跑卡片渲染逻辑,在 12:00 与 23:30 核对:国内版 `hy4-preview` 正确显示活动徽章与截止日,**国际版完全不受活动规则影响**。
|
|
65
|
+
|
|
7
66
|
## 1.7.4 — 装在中文文件夹里的 WorkBuddy,终于找得到了
|
|
8
67
|
|
|
9
68
|
> 「腾讯」两个字,让插件整整看不见一个装好、登录着、正在运行的 WorkBuddy。
|
package/lib/client.js
CHANGED
|
@@ -273,6 +273,12 @@ window.__ModuleLoader__.load({
|
|
|
273
273
|
.dsm-workbuddy-xdpool-model-id{color:var(--dsw-alias-label-tertiary,#999);font-size:11px;line-height:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
274
274
|
.dsm-workbuddy-xdpool-model-meta{display:flex;align-items:center;gap:8px;flex-wrap:wrap;color:var(--dsw-alias-label-tertiary,#999);font-size:11px;line-height:16px}
|
|
275
275
|
.dsm-workbuddy-xdpool-model-meta-tag{padding:1px 8px;border-radius:999px;font-size:11px;line-height:16px;background:rgba(174,179,187,.11);color:var(--dsw-alias-label-secondary,#c6c9d0)}
|
|
276
|
+
/* "free from HH:00": quieter than the badge on purpose — the model costs
|
|
277
|
+
credits right now, so it must not read as a promo the user can spend against. */
|
|
278
|
+
.dsm-workbuddy-xdpool-model-meta-later{padding:1px 8px;border-radius:999px;font-size:11px;line-height:16px;border:1px dashed color-mix(in oklab, var(--dsw-alias-label-dimmed,#9aa0a8) 55%, transparent);color:var(--dsw-alias-label-tertiary,#9aa0a8)}
|
|
279
|
+
/* "活动至 10-31": the campaign's end date. Muted — it is context for planning,
|
|
280
|
+
not a claim about the current price. */
|
|
281
|
+
.dsm-workbuddy-xdpool-model-meta-promo{color:var(--dsw-alias-label-tertiary,#9aa0a8);font-size:11px;line-height:16px;opacity:.85}
|
|
276
282
|
.dsm-workbuddy-xdpool-model-cap{color:var(--dsw-alias-label-tertiary,#999);font-size:11px;line-height:16px;font-variant-numeric:tabular-nums}
|
|
277
283
|
/* Model row: checkbox + image toggle + context-budget radios. */
|
|
278
284
|
.dsm-workbuddy-xdpool-model-off{opacity:.55}
|
|
@@ -366,6 +372,104 @@ window.__ModuleLoader__.load({
|
|
|
366
372
|
.dsm-workbuddy-xdpool-reserve-note-ok{color:var(--dsw-alias-state-success-primary,#22a06b)}
|
|
367
373
|
.dsm-workbuddy-xdpool-reserve-note-bad{color:var(--dsw-alias-state-error-primary,#ef4444);font-weight:600}
|
|
368
374
|
`.trim();
|
|
375
|
+
//#endregion
|
|
376
|
+
//#region src/promo.ts
|
|
377
|
+
/**
|
|
378
|
+
* Promotions in force.
|
|
379
|
+
*
|
|
380
|
+
* Source: the WorkBuddy announcement extending Hy3's free tier and
|
|
381
|
+
* Hy4-preview's night window to **2026-10-31**. Hy3 needs no entry here (its
|
|
382
|
+
* CN price is already zero upstream); only Hy4-preview's time window does,
|
|
383
|
+
* because the gateway charges for it around the clock.
|
|
384
|
+
*
|
|
385
|
+
* When a promotion is extended or a new one starts, edit this table. When one
|
|
386
|
+
* ends, either delete the row or let `until` lapse — both stop the badge.
|
|
387
|
+
*/
|
|
388
|
+
const PROMO_RULES = [{
|
|
389
|
+
idPrefix: "hy4-preview",
|
|
390
|
+
region: "cn",
|
|
391
|
+
hours: [
|
|
392
|
+
23,
|
|
393
|
+
0,
|
|
394
|
+
1,
|
|
395
|
+
2,
|
|
396
|
+
3,
|
|
397
|
+
4,
|
|
398
|
+
5,
|
|
399
|
+
6,
|
|
400
|
+
7
|
|
401
|
+
],
|
|
402
|
+
until: "2026-10-31",
|
|
403
|
+
label: "night"
|
|
404
|
+
}];
|
|
405
|
+
/** `YYYY-MM-DD` for a Date in LOCAL time (the promotions are announced locally). */
|
|
406
|
+
function localDayKey(date) {
|
|
407
|
+
const p = (n) => String(n).padStart(2, "0");
|
|
408
|
+
return `${date.getFullYear()}-${p(date.getMonth() + 1)}-${p(date.getDate())}`;
|
|
409
|
+
}
|
|
410
|
+
/** Whether a rule is still in force on `date`. */
|
|
411
|
+
function ruleActive(rule, date) {
|
|
412
|
+
return localDayKey(date) <= rule.until;
|
|
413
|
+
}
|
|
414
|
+
/** The first hour the window reopens, searching forward from `hour`. */
|
|
415
|
+
function nextWindowHour(rule, hour) {
|
|
416
|
+
for (let step = 1; step <= 24; step += 1) {
|
|
417
|
+
const candidate = (hour + step) % 24;
|
|
418
|
+
if (rule.hours.includes(candidate)) return candidate;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/** The hour the CURRENT window closes, searching forward from `hour`. */
|
|
422
|
+
function windowEndHour(rule, hour) {
|
|
423
|
+
for (let step = 1; step <= 24; step += 1) {
|
|
424
|
+
const candidate = (hour + step) % 24;
|
|
425
|
+
if (!rule.hours.includes(candidate)) return candidate;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* The promotion status of one model at `now`, for one region.
|
|
430
|
+
*
|
|
431
|
+
* `now` is injected so the behaviour is testable without freezing the clock —
|
|
432
|
+
* a time-dependent badge that can only be tested by waiting is a badge nobody
|
|
433
|
+
* tests. `region` is required for the same reason the rules carry one: these
|
|
434
|
+
* campaigns are regional, and applying a domestic rule to the international
|
|
435
|
+
* roster would invent a discount that gateway does not offer.
|
|
436
|
+
*/
|
|
437
|
+
function promoStatusFor(model, now = /* @__PURE__ */ new Date(), region = "cn") {
|
|
438
|
+
if (model.multiplier === 0) return { kind: "free" };
|
|
439
|
+
for (const rule of PROMO_RULES) {
|
|
440
|
+
if (rule.region !== region) continue;
|
|
441
|
+
if (!model.id.startsWith(rule.idPrefix)) continue;
|
|
442
|
+
if (!ruleActive(rule, now)) continue;
|
|
443
|
+
const hour = now.getHours();
|
|
444
|
+
if (rule.hours.includes(hour)) {
|
|
445
|
+
const untilHour = windowEndHour(rule, hour);
|
|
446
|
+
return {
|
|
447
|
+
kind: "night",
|
|
448
|
+
label: rule.label,
|
|
449
|
+
untilHour: untilHour ?? hour,
|
|
450
|
+
promoUntil: rule.until
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
const nextHour = nextWindowHour(rule, hour);
|
|
454
|
+
if (nextHour !== void 0) return {
|
|
455
|
+
kind: "night-later",
|
|
456
|
+
label: rule.label,
|
|
457
|
+
nextHour,
|
|
458
|
+
promoUntil: rule.until
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Whether a model is free RIGHT NOW, for sorting.
|
|
464
|
+
*
|
|
465
|
+
* Only the two "currently free" kinds count. `night-later` deliberately does
|
|
466
|
+
* NOT sort to the top: it costs credits at this moment, and floating a
|
|
467
|
+
* credit-priced model above cheaper ones would misrepresent the list.
|
|
468
|
+
*/
|
|
469
|
+
function isFreeNow(model, now = /* @__PURE__ */ new Date(), region = "cn") {
|
|
470
|
+
const status = promoStatusFor(model, now, region);
|
|
471
|
+
return status?.kind === "free" || status?.kind === "night";
|
|
472
|
+
}
|
|
369
473
|
//#endregion
|
|
370
474
|
//#region src/client/PoolCard.tsx
|
|
371
475
|
/**
|
|
@@ -546,17 +650,23 @@ window.__ModuleLoader__.load({
|
|
|
546
650
|
/**
|
|
547
651
|
* The promo badge for one model, or undefined when it has none.
|
|
548
652
|
*
|
|
549
|
-
*
|
|
550
|
-
* sends a literal `free` tag: the global roster marks its zero-cost models
|
|
551
|
-
* (`hy3`, `hy4-preview-f`, `deepseek-v4.1-flash`) as `credits: "x0.00"`, so
|
|
552
|
-
* waiting for a tag meant the badge NEVER appeared — including on models that
|
|
553
|
-
* genuinely cost nothing.
|
|
653
|
+
* Two sources, because the gateway models one of them and not the other:
|
|
554
654
|
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
655
|
+
* - `free` comes from the CREDIT MULTIPLIER. Neither gateway ever sends a
|
|
656
|
+
* literal `free` tag, but it does price its free models at `credits: "x0.00"`
|
|
657
|
+
* (CN `hy3`), so the multiplier is the honest signal.
|
|
658
|
+
* - the NIGHT window comes from {@link promoStatusFor}, because the gateway
|
|
659
|
+
* charges `x0.29` for `hy4-preview` around the clock and has no field for a
|
|
660
|
+
* time-of-day rule. See that module for why the 14-day newcomer allowance is
|
|
661
|
+
* deliberately not modelled.
|
|
662
|
+
*
|
|
663
|
+
* `region` is threaded through because the campaigns are REGIONAL: the
|
|
664
|
+
* Hy3 / Hy4-preview extension is a domestic promotion, so a global roster must
|
|
665
|
+
* not pick up a discount that gateway does not offer.
|
|
557
666
|
*/
|
|
558
|
-
function tagFor(model) {
|
|
667
|
+
function tagFor(model, now, region) {
|
|
559
668
|
const tags = model.tags ?? [];
|
|
669
|
+
if (promoStatusFor(model, now, region)?.kind === "night") return "night";
|
|
560
670
|
if (tags.includes("free") || model.multiplier === 0) return "free";
|
|
561
671
|
if (tags.includes("limited-free")) return "limited";
|
|
562
672
|
if (tags.includes("night-discount")) return "night";
|
|
@@ -837,6 +947,17 @@ window.__ModuleLoader__.load({
|
|
|
837
947
|
const modelsEditable = settingsWritable;
|
|
838
948
|
const modelsDirty = draft !== void 0 && status !== void 0 && draftIsDirty(status, draft);
|
|
839
949
|
const enabledCount = Object.values(modelDraft).filter((entry) => entry.enabled).length;
|
|
950
|
+
/**
|
|
951
|
+
* One clock reading per render, shared by the sort and every row.
|
|
952
|
+
*
|
|
953
|
+
* Taken once so the list cannot disagree with itself: calling `new Date()`
|
|
954
|
+
* per row would let a model be "free" for the badge and "not free" for the
|
|
955
|
+
* sort if the window boundary happened to fall between two rows.
|
|
956
|
+
*
|
|
957
|
+
* A promotion boundary is not a re-render trigger — the card refreshes on its
|
|
958
|
+
* own poll, which is frequent enough for a badge that changes twice a day.
|
|
959
|
+
*/
|
|
960
|
+
const now = /* @__PURE__ */ new Date();
|
|
840
961
|
const toggleModel = (id) => {
|
|
841
962
|
if (status === void 0) return;
|
|
842
963
|
const base = draft ?? draftFromStatus(status);
|
|
@@ -1510,8 +1631,9 @@ window.__ModuleLoader__.load({
|
|
|
1510
1631
|
})]
|
|
1511
1632
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1512
1633
|
className: "dsm-workbuddy-xdpool-model-list",
|
|
1513
|
-
children: status?.models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
1634
|
+
children: [...status?.models ?? []].sort((a, b) => Number(isFreeNow(b, now, activeRegion)) - Number(isFreeNow(a, now, activeRegion))).map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
1514
1635
|
model,
|
|
1636
|
+
region: activeRegion,
|
|
1515
1637
|
t,
|
|
1516
1638
|
draft: modelDraft[model.id] ?? {
|
|
1517
1639
|
enabled: model.enabled,
|
|
@@ -1865,9 +1987,26 @@ window.__ModuleLoader__.load({
|
|
|
1865
1987
|
* context radios stay disabled rather than pretending an edit took hold. The
|
|
1866
1988
|
* draft lives in the parent, so this component only ever reports intent.
|
|
1867
1989
|
*/
|
|
1868
|
-
function ModelRow({ model, t, draft, editable, onToggle, onToggleImage, onBudget }) {
|
|
1869
|
-
const
|
|
1870
|
-
const
|
|
1990
|
+
function ModelRow({ model, region, t, draft, editable, onToggle, onToggleImage, onBudget }) {
|
|
1991
|
+
const now = /* @__PURE__ */ new Date();
|
|
1992
|
+
const tag = tagFor(model, now, region);
|
|
1993
|
+
const promo = promoStatusFor(model, now, region);
|
|
1994
|
+
const tagText = tag === "free" ? t?.("row.free") ?? "free" : tag === "limited" ? t?.("row.limitedFree") ?? "limited free" : tag === "night" ? t?.("row.nightFreeNow", { time: `${String(promo?.kind === "night" ? promo.untilHour : 0).padStart(2, "0")}:00` }) ?? "free until 08:00" : null;
|
|
1995
|
+
/**
|
|
1996
|
+
* The "cheaper later" hint: the model is on a promotion but the window is
|
|
1997
|
+
* closed. Deliberately NOT a "free" badge — it costs credits at this moment,
|
|
1998
|
+
* and telling the user otherwise would change what they spend.
|
|
1999
|
+
*/
|
|
2000
|
+
const laterHint = promo?.kind === "night-later" ? t?.("row.nightFreeLater", { time: `${String(promo.nextHour).padStart(2, "0")}:00` }) ?? `free from ${String(promo.nextHour).padStart(2, "0")}:00` : null;
|
|
2001
|
+
/**
|
|
2002
|
+
* How long the campaign itself runs, e.g. "活动至 10-31".
|
|
2003
|
+
*
|
|
2004
|
+
* Shown on both the free and the not-yet-free row, because the useful question
|
|
2005
|
+
* is not only "is it free now" but "until when is this offer good at all" —
|
|
2006
|
+
* an extension changes that date, and a user planning around the promotion
|
|
2007
|
+
* needs it visible rather than buried in a changelog.
|
|
2008
|
+
*/
|
|
2009
|
+
const promoUntil = promo === void 0 || promo.kind === "free" ? null : t?.("row.promoUntil", { date: promo.promoUntil.slice(5).replace("-", "-") }) ?? `promo until ${promo.promoUntil}`;
|
|
1871
2010
|
const native = model.nativeContextWindow;
|
|
1872
2011
|
const capped = native > DEFAULT_CONTEXT_BUDGET;
|
|
1873
2012
|
const currentBudget = draft.budget ?? native;
|
|
@@ -1939,6 +2078,14 @@ window.__ModuleLoader__.load({
|
|
|
1939
2078
|
className: "dsm-workbuddy-xdpool-model-meta-tag",
|
|
1940
2079
|
children: tagText
|
|
1941
2080
|
}),
|
|
2081
|
+
laterHint === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2082
|
+
className: "dsm-workbuddy-xdpool-model-meta-later",
|
|
2083
|
+
children: laterHint
|
|
2084
|
+
}),
|
|
2085
|
+
promoUntil === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2086
|
+
className: "dsm-workbuddy-xdpool-model-meta-promo",
|
|
2087
|
+
children: promoUntil
|
|
2088
|
+
}),
|
|
1942
2089
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1943
2090
|
className: "dsm-workbuddy-xdpool-model-cap",
|
|
1944
2091
|
children: t?.("row.modelOutput", { size: formatCapacity(model.maxOutputTokens) }) ?? `out ${formatCapacity(model.maxOutputTokens)}`
|
|
@@ -2094,6 +2241,9 @@ window.__ModuleLoader__.load({
|
|
|
2094
2241
|
"row.free": "free",
|
|
2095
2242
|
"row.limitedFree": "limited free",
|
|
2096
2243
|
"row.nightDiscount": "night",
|
|
2244
|
+
"row.nightFreeNow": "free until {time}",
|
|
2245
|
+
"row.nightFreeLater": "free from {time}",
|
|
2246
|
+
"row.promoUntil": "promo to {date}",
|
|
2097
2247
|
"row.imageCapable": "image input",
|
|
2098
2248
|
"row.rate": "{rate}x credits",
|
|
2099
2249
|
"row.accountsRescan": "Detect accounts again",
|
|
@@ -2239,6 +2389,9 @@ window.__ModuleLoader__.load({
|
|
|
2239
2389
|
"row.free": "免费",
|
|
2240
2390
|
"row.limitedFree": "限量免费",
|
|
2241
2391
|
"row.nightDiscount": "夜间",
|
|
2392
|
+
"row.nightFreeNow": "免费至 {time}",
|
|
2393
|
+
"row.nightFreeLater": "{time} 起免费",
|
|
2394
|
+
"row.promoUntil": "活动至 {date}",
|
|
2242
2395
|
"row.imageCapable": "图片输入",
|
|
2243
2396
|
"row.rate": "{rate}x 积分",
|
|
2244
2397
|
"row.accountsRescan": "重新检测账号",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-workbuddy-xdpool",
|
|
3
3
|
"displayName": "DSH WorkBuddy XD Pool",
|
|
4
4
|
"description": "Merge every locally signed-in WorkBuddy account into DeepSeek Harness as one auto-failing-over model pool (multi-account rotation, live credits, daily check-in and model catalog).",
|
|
5
|
-
"version": "1.7.
|
|
5
|
+
"version": "1.7.5",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "XDTrees",
|
|
8
8
|
"homepage": "https://github.com/XDTrees/dsh-workbuddy-xdpool#readme",
|