kdczyz-dsh-model 1.2.2-beta → 1.2.4-beta

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.
@@ -273,21 +273,12 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
273
273
  .wotr-credit-region-title{font-size:11px;font-weight:600;color:var(--dsw-alias-label-primary)}
274
274
  .wotr-credit-region-sub{font-size:11px;color:var(--dsw-alias-label-secondary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
275
275
  .wotr-credit-row{margin-top:6px;padding:8px;border:.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:6px}
276
- .wotr-credit-row[data-off="1"]{opacity:.55}
277
276
  .wotr-credit-row[data-serving="1"]{border-color:var(--dsw-alias-label-primary)}
278
277
  .wotr-credit-row-top{display:flex;align-items:baseline;gap:8px;justify-content:space-between}
279
278
  .wotr-credit-row-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-primary);font-weight:600}
280
279
  .wotr-credit-row-credits{flex:none;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary)}
281
280
  .wotr-credit-row-foot{display:flex;align-items:center;justify-content:space-between;gap:8px}
282
281
  .wotr-credit-tags{display:flex;align-items:center;gap:4px;flex-wrap:wrap;min-width:0}
283
- /* 启停开关:本页自绘(不引 primitives 的 Switch),配色沿用本文件
284
- 既有的 token 组合 —— 开 = label-primary 底 + bg-layer-1 滑块,
285
- 与 .wbc-btn-primary 同一套对比关系,深浅色主题下都不会糊。 */
286
- .wotr-credit-switch{position:relative;flex:none;width:30px;height:16px;padding:0;border:none;border-radius:8px;background:var(--dsw-alias-bg-layer-3,rgba(127,127,127,.35));cursor:pointer;transition:background .12s ease-out}
287
- .wotr-credit-switch::after{content:'';position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--dsw-alias-label-secondary,#888);transition:transform .12s ease-out,background .12s ease-out}
288
- .wotr-credit-switch[data-on="1"]{background:var(--dsw-alias-label-primary,#4c8dff)}
289
- .wotr-credit-switch[data-on="1"]::after{transform:translateX(14px);background:var(--dsw-alias-bg-layer-1,#fff)}
290
- .wotr-credit-switch:disabled{opacity:.5;cursor:default}
291
282
  .wotr-credit-foot{margin-top:10px;padding-top:8px;border-top:.5px solid var(--dsw-alias-border-l2);font-size:11px;line-height:16px}
292
283
  .wotr-credit-note{margin-top:6px;font-size:11px;line-height:16px;color:var(--dsw-alias-label-primary)}
293
284
  .wotr-credit-err{margin-top:6px;font-size:11px;line-height:16px;color:var(--dsw-alias-label-error,#e5484d)}
@@ -645,7 +636,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
645
636
  const ignored = asArray(status?.ignored);
646
637
  const selection = status?.selection ?? {};
647
638
  const automation = status?.automation;
648
- const usable = accounts.filter((a) => a.disabled !== true).length;
649
639
  const automationOn = automation?.enabled === true;
650
640
 
651
641
  const draft = draftByRegion[region];
@@ -696,17 +686,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
696
686
  }
697
687
  };
698
688
 
699
- // —— 账号启停 ——
700
- const onToggleDisabled = (accountId, disabled) => {
701
- if (!writable) return;
702
- return run(accountId, () =>
703
- fetchJson(`${POOL_API}/accounts/disabled`, {
704
- method: 'POST',
705
- headers: { 'Content-Type': 'application/json' },
706
- body: JSON.stringify({ accountId, disabled }),
707
- }), disabled ? '已停用该账号' : '已重新启用该账号');
708
- };
709
-
710
689
  // —— 移出池子 / 恢复 ——
711
690
  const onIgnore = (accountId, ignoredNext) => {
712
691
  return run(`ignore-${accountId}`, () =>
@@ -1042,7 +1021,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
1042
1021
  : jsx(StatsRow, {
1043
1022
  items: [
1044
1023
  { label: '账号', value: fmtNum(accounts.length), sub: '个已登录' },
1045
- { label: '可用', value: fmtNum(usable), sub: '未被停用' },
1046
1024
  {
1047
1025
  label: '当前使用',
1048
1026
  value: currentName,
@@ -1082,12 +1060,11 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
1082
1060
  AccountCard,
1083
1061
  {
1084
1062
  name: a.nickname || a.label || a.id,
1085
- dim: a.disabled === true || (currentId !== '' && isCurrent !== true),
1063
+ dim: (currentId !== '' && isCurrent !== true),
1086
1064
  tags: [
1087
1065
  isCurrent
1088
1066
  ? { text: '当前使用', cls: 'wbc-tag wbc-tag-on' }
1089
1067
  : { text: '备用', cls: 'wbc-tag' },
1090
- a.disabled === true ? { text: '已停用', cls: 'wbc-tag' } : null,
1091
1068
  ],
1092
1069
  rows: [
1093
1070
  /**
@@ -1116,9 +1093,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
1116
1093
  CardActions,
1117
1094
  {
1118
1095
  locked: !writable,
1119
- disabled: a.disabled === true,
1120
- saving: busy === a.id,
1121
- onToggleDisabled: (next) => onToggleDisabled(a.id, next),
1122
1096
  onRemove: () => onIgnore(a.id, true),
1123
1097
  removeBusy: busy === `ignore-${a.id}`,
1124
1098
  },
@@ -1713,19 +1687,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
1713
1687
  }
1714
1688
  };
1715
1689
 
1716
- const [savingPool, setSavingPool] = useState(null);
1717
-
1718
- const onToggleDisabled = (accountId, disabled) => {
1719
- setSavingPool(accountId);
1720
- const currentIds = asArray(traeRegionSlotOf(scopeObj?.getSnapshot?.().value, region).disabledAccountIds);
1721
- const next = disabled
1722
- ? [...new Set([...currentIds, accountId])]
1723
- : currentIds.filter((id) => id !== accountId);
1724
- writePoolField({ disabledAccountIds: next }, (readBack) =>
1725
- JSON.stringify(traeRegionSlotOf(readBack, region).disabledAccountIds ?? []) === JSON.stringify(next),
1726
- disabled ? '已停用该账号' : '已重新启用该账号')
1727
- .finally(() => setSavingPool(null));
1728
- };
1729
1690
 
1730
1691
  /** 供应商开关:只改 enabled,其余字段原样保留(关掉不丢勾选) */
1731
1692
  const [togglingRegion, setTogglingRegion] = useState(null);
@@ -1830,10 +1791,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
1830
1791
  .filter((pool) => !accounts.some((account) => String(account.id) === String(pool.id)))
1831
1792
  .map((pool) => ({ account: null, pool })),
1832
1793
  ];
1833
- const traeUsable =
1834
- poolAccounts.length === 0
1835
- ? accounts.length
1836
- : poolAccounts.filter((a) => a.disabled !== true).length;
1837
1794
  const checkinText =
1838
1795
  usage?.checkin?.checkedIn === true
1839
1796
  ? '今日已签到'
@@ -1958,7 +1915,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
1958
1915
  ? jsx(StatsRow, {
1959
1916
  items: [
1960
1917
  { label: '账号', value: fmtNum(accounts.length), sub: '个已登录' },
1961
- { label: '可用', value: fmtNum(traeUsable), sub: '未被停用' },
1962
1918
  {
1963
1919
  label: '当前使用',
1964
1920
  value: usage.accountName ?? current?.accountName ?? '–',
@@ -2003,7 +1959,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
2003
1959
  isCurrent
2004
1960
  ? { text: '当前使用', cls: 'wbc-tag wbc-tag-on' }
2005
1961
  : { text: '备用', cls: 'wbc-tag' },
2006
- pool?.disabled === true ? { text: '已停用', cls: 'wbc-tag' } : null,
2007
1962
  ],
2008
1963
  // 余额来自 /usage 的逐账号 credits,号池状态来自 pool 段,
2009
1964
  // 两张表按 id 对齐后拼成同一张卡。
@@ -2018,16 +1973,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
2018
1973
  : null,
2019
1974
  ],
2020
1975
  extra: [
2021
- jsx(
2022
- CardActions,
2023
- {
2024
- locked: !writable || pool === null || pool === undefined,
2025
- disabled: pool?.disabled === true,
2026
- saving: savingPool === id,
2027
- onToggleDisabled: (next) => onToggleDisabled(id, next),
2028
- },
2029
- 'actions',
2030
- ),
2031
1976
  /* 卡片最后一行:与 XD Pool 页同款的两按钮排 —— 左边「切换
2032
1977
  * 到此账号」(**当前那张不给**:它已经是当前了),右边
2033
1978
  * 「签到」。签到这个按钮是**每张卡都有**的:它签的是卡片
@@ -2475,26 +2420,18 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
2475
2420
  * 账号卡里的控件行:三个配置页同一套。
2476
2421
  *
2477
2422
  * 完全手动语义(本 fork):账号之间没有分配策略 / 轮换 / 冷却,卡上的操作
2478
- * 只剩两件**手动管理**的事 ——
2423
+ * 只剩一件**手动管理**的事 ——
2479
2424
  *
2480
- * 「停用 / 启用」:写 `disabledAccountIds`,停用的账号不会被取号;
2481
2425
  * 「移出池子」:只在传了 `onRemove` 时渲染(Trae 半边没有「移出」概念,
2482
2426
  * 不给它硬塞一个按不动的按钮)。
2483
2427
  *
2484
- * 早先这里的「参与轮换」勾选与「保留额度」输入已随分配策略一并删除。
2428
+ * 早先这里的「参与轮换」勾选 / 「保留额度」输入 / 「停用」按钮都已按完全手动
2429
+ * 语义删除 —— 停用不影响任何请求(取号只认手动选中的那一个)。
2485
2430
  */
2486
- function CardActions({ locked, disabled, onToggleDisabled, saving, onRemove, removeBusy }) {
2431
+ function CardActions({ locked, onRemove, removeBusy }) {
2487
2432
  return jsxs('div', {
2488
2433
  className: 'wbc-bar',
2489
2434
  children: [
2490
- jsx('button', {
2491
- type: 'button',
2492
- className: 'wbc-btn',
2493
- title: disabled === true ? '恢复这个账号参与取号' : '停用后取号不再选中它(请求失败时请手动切换)',
2494
- disabled: locked === true || saving === true,
2495
- onClick: () => onToggleDisabled(disabled !== true),
2496
- children: disabled === true ? '启用' : '停用',
2497
- }),
2498
2435
  jsx('div', { className: 'wbc-spacer' }),
2499
2436
  typeof onRemove !== 'function'
2500
2437
  ? null
@@ -2969,7 +2906,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
2969
2906
  creditsAtMs,
2970
2907
  onRefresh,
2971
2908
  onAddAccount,
2972
- onToggle,
2973
2909
  onRemove,
2974
2910
  onSelect,
2975
2911
  /**
@@ -2985,7 +2921,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
2985
2921
  checkinNote,
2986
2922
  }) {
2987
2923
  const accounts = asArray(status?.accounts);
2988
- const usable = accounts.filter((a) => a.disabled !== true).length;
2989
2924
  /**
2990
2925
  * 「当前使用」的那一个 —— 请求就固定用它。
2991
2926
  *
@@ -3168,7 +3103,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
3168
3103
  ? jsx(StatsRow, {
3169
3104
  items: [
3170
3105
  { label: '账号', value: fmtNum(accounts.length), sub: '个已入池' },
3171
- { label: '可用', value: fmtNum(usable), sub: '未被停用' },
3172
3106
  {
3173
3107
  // 「当前使用」是谁:这是本页最该一眼看到的一件事 —— 请求就打在
3174
3108
  // 它身上。它这一轮的余额(真正在扣的那份)与全池合计退到 sub,
@@ -3208,13 +3142,12 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
3208
3142
  name: a.label ?? a.id,
3209
3143
  // 完全手动:只有「当前使用」那张是亮的,其余卡片压暗。
3210
3144
  // 不可用(停用)也压暗 —— 具体原因由标签说明。
3211
- dim: a.disabled === true || isSelected !== true,
3145
+ dim: isSelected !== true,
3212
3146
  tags: [
3213
3147
  isServing ? { text: '本次调用', cls: 'wbc-tag wbc-tag-on' } : null,
3214
3148
  isSelected
3215
3149
  ? { text: '当前使用', cls: isServing ? 'wbc-tag' : 'wbc-tag wbc-tag-on' }
3216
3150
  : { text: '备用', cls: 'wbc-tag' },
3217
- a.disabled === true ? { text: '已停用', cls: 'wbc-tag' } : null,
3218
3151
  expired ? { text: '令牌已过期', cls: 'wbc-tag wbc-tag-warn' } : null,
3219
3152
  ],
3220
3153
  rows: [
@@ -3245,9 +3178,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
3245
3178
  CardActions,
3246
3179
  {
3247
3180
  locked,
3248
- disabled: a.disabled === true,
3249
- onToggleDisabled: (next) => onToggle(a.id, next),
3250
- saving: busy === true,
3251
3181
  onRemove: () => onRemove(a.id),
3252
3182
  removeBusy: busy === true,
3253
3183
  },
@@ -3867,7 +3797,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
3867
3797
  fullName: name || id,
3868
3798
  credits:
3869
3799
  typeof raw?.credits === 'number' && Number.isFinite(raw.credits) ? raw.credits : undefined,
3870
- disabled: raw?.disabled === true,
3871
3800
  expired: raw?.expired === true,
3872
3801
  pinned: raw?.pinned === true,
3873
3802
  serving: raw?.serving === true,
@@ -3886,7 +3815,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
3886
3815
  id: a.id,
3887
3816
  name: a.nickname ?? a.label ?? '',
3888
3817
  credits: accountCreditsOf(a),
3889
- disabled: a.disabled,
3890
3818
  pinned: pinned !== '' && a.id === pinned,
3891
3819
  serving: serving !== '' && a.id === serving,
3892
3820
  error: a.creditsError,
@@ -3960,7 +3888,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
3960
3888
  credits: isServing
3961
3889
  ? (accountCreditsOf(serving, 'qoder') ?? accountCreditsOf(a, 'qoder'))
3962
3890
  : accountCreditsOf(a, 'qoder'),
3963
- disabled: a.disabled,
3964
3891
  expired: a.expired,
3965
3892
  pinned: typeof a.id === 'string' && a.id !== '' && a.id === pinned,
3966
3893
  serving: isServing,
@@ -4045,8 +3972,8 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
4045
3972
  * 就地改缓存里的行(写完之后的即时反馈)。
4046
3973
  *
4047
3974
  * 刻意**不**为了这一次改动再打一遍状态接口 —— 那个接口每个账号都会触发一次
4048
- * 计费调用。写路径本身已经做过读回确认(见 setAccountDisabledRemote /
4049
- * selectAccountRemote),所以就地改动是有依据的;下一次打开卡片或点「刷新」
3975
+ * 计费调用。写路径本身已经做过读回确认(见 selectAccountRemote),
3976
+ * 所以就地改动是有依据的;下一次打开卡片或点「刷新」
4050
3977
  * 会用真实快照把它对齐。
4051
3978
  */
4052
3979
  function patchCreditRows(family, match, patch) {
@@ -4059,81 +3986,11 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
4059
3986
  });
4060
3987
  }
4061
3988
 
4062
- /** 停用名单的加减:**只动这一个 id**,其余原样带过 */
4063
- function mergeDisabledIds(ids, accountId, disabled) {
4064
- const current = asArray(ids).filter((id) => typeof id === 'string' && id !== '');
4065
- return disabled
4066
- ? [...new Set([...current, accountId])]
4067
- : current.filter((id) => id !== accountId);
4068
- }
4069
-
4070
- /** 两份停用名单是否等价(读回确认用;顺序无关) */
4071
- function sameIdSet(a, b) {
4072
- const left = asArray(a).filter((id) => typeof id === 'string' && id !== '');
4073
- const right = asArray(b).filter((id) => typeof id === 'string' && id !== '');
4074
- if (left.length !== right.length) return false;
4075
- const set = new Set(left);
4076
- return right.every((id) => set.has(id));
4077
- }
4078
-
4079
3989
  /** 该平台设置作用域(拿不到就是 null,调用方按只读处理) */
4080
3990
  function creditScopeOf(family) {
4081
3991
  return poolScopeOf(family === 'qoder' ? qoderSettings : traeSettings);
4082
3992
  }
4083
3993
 
4084
- /**
4085
- * 停用 / 启用一个账号 —— 三家写法不同,语义是同一条。
4086
- *
4087
- * WorkBuddy:走路由 `POST /accounts/disabled`。**不要**在这里自己拼
4088
- * `disabledAccountIds` 写设置:国内版与国际版共用**同一份**设置文档
4089
- * (两个 provider 用同一个 settingsNs、`settingsPath: []`),只按当前区域的
4090
- * 行拼出来的列表会把另一个区域的停用项整段抹掉。路由在服务端按整份设置合并
4091
- * (`setAccountDisabled` 读 `current().disabledAccountIds` 再加减一个 id)。
4092
- *
4093
- * Trae / Qoder:没有可用的写路由(Trae 的 `/pool/account` 只改进程内的池,
4094
- * 下一次设置同步就被覆盖回去),所以写设置字段 —— 但**从当前设置文档里读旧值
4095
- * 再合并**,而不是从行里拼。
4096
- */
4097
- async function setAccountDisabledRemote(family, region, accountId, disabled) {
4098
- if (typeof accountId !== 'string' || accountId === '') throw new Error('缺少账号 id');
4099
- const want = disabled === true;
4100
- if (family === 'wb') {
4101
- await fetchJson(`${POOL_API}/accounts/disabled`, {
4102
- method: 'POST',
4103
- headers: { 'Content-Type': 'application/json' },
4104
- body: JSON.stringify({ accountId, disabled: want }),
4105
- });
4106
- return;
4107
- }
4108
- const scope = creditScopeOf(family);
4109
- const who = family === 'qoder' ? 'qoder' : 'trae';
4110
- if (scope === undefined || scope === null) {
4111
- throw new Error(`${who}: 拿不到设置作用域,无法保存(配置页同一处也只读)`);
4112
- }
4113
- if (!poolWritable(scope)) throw new Error(`${who}: 设置当前不可写`);
4114
- if (family === 'qoder') {
4115
- const currentIds = asArray(unwrapVolatileDeep(scope.getSnapshot?.().value)?.disabledAccountIds);
4116
- const next = mergeDisabledIds(currentIds, accountId, want);
4117
- await writeSettingsField(
4118
- scope,
4119
- 'disabledAccountIds',
4120
- next,
4121
- (doc) => sameIdSet(doc?.disabledAccountIds, next),
4122
- 'qoder',
4123
- );
4124
- return;
4125
- }
4126
- const value = scope.getSnapshot?.().value;
4127
- const next = mergeDisabledIds(traeRegionSlotOf(value, region).disabledAccountIds, accountId, want);
4128
- const slot = { ...traeRegionSlotOf(value, region), disabledAccountIds: next };
4129
- await writeTraeField(
4130
- scope,
4131
- 'regions',
4132
- nextRegionSlots(regionsMapOf(value), region, slot),
4133
- (readBack) => sameIdSet(traeRegionSlotOf(readBack, region).disabledAccountIds, next),
4134
- );
4135
- }
4136
-
4137
3994
  /**
4138
3995
  * 把某个账号设成「当前账号」。
4139
3996
  *
@@ -4273,8 +4130,7 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
4273
4130
  *
4274
4131
  * 展开的卡片里是**当前这个平台的全部账号**(不是「所有平台的账号」):
4275
4132
  * WorkBuddy 与 Trae 各自的国内版 + 国际版都列出来,Qoder 只有一个池。
4276
- * 每行带两个控件 —— 「停用/启用」开关与「切换到此账号」,见
4277
- * setAccountDisabledRemote / selectAccountRemote 的语义说明。
4133
+ * 每行带一个控件 —— 「切换到此账号」,见 selectAccountRemote 的语义说明。
4278
4134
  *
4279
4135
  * 刷新策略分两档,因为两档的成本差一个量级:
4280
4136
  * - 胶囊那颗数字:**每 30 秒自动刷一次**(见 CREDIT_REFRESH_MS 的成本说明),
@@ -4550,28 +4406,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
4550
4406
  refreshHeadline();
4551
4407
  };
4552
4408
 
4553
- /** 停用 / 启用某一行 */
4554
- const onToggleRow = async (row) => {
4555
- const next = row.disabled !== true;
4556
- setBusyRow(row.key);
4557
- setWriteError('');
4558
- setNote('');
4559
- try {
4560
- await setAccountDisabledRemote(row.family, row.region, row.id, next);
4561
- patchCreditRows(row.family, (r) => r.key === row.key, { disabled: next });
4562
- // 停掉的正好是「这一轮在用的那个」→ 胶囊上的主语马上就会变,补一发
4563
- if (next === true && row.serving === true && row.region === source.region) {
4564
- refreshHeadline();
4565
- }
4566
- setNote(next ? `已停用 ${row.name},请求失败时请手动切换` : `已重新启用 ${row.name}`);
4567
- } catch (e) {
4568
- setWriteError(e?.message ?? String(e));
4569
- } finally {
4570
- setBusyRow('');
4571
- setTick((n) => n + 1);
4572
- }
4573
- };
4574
-
4575
4409
  /** 切换到此账号 / 取消固定 */
4576
4410
  const onSelectRow = async (row) => {
4577
4411
  // WorkBuddy 独有的「取消固定」:完全手动语义下它的池把「没有当前账号」
@@ -4607,7 +4441,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
4607
4441
  // 但选中账号不可用时上一轮可能根本没扣到它。
4608
4442
  if (row.pinned === true) push('on', row.family === 'wb' ? '已固定' : '当前使用');
4609
4443
  if (row.serving === true) push(row.pinned === true ? 'muted' : 'on', '本次调用');
4610
- if (row.disabled === true) push('warn', '已停用');
4611
4444
  if (row.expired === true) push('warn', '凭据已过期');
4612
4445
  if (row.error !== '') push('warn', `额度读不到:${row.error}`);
4613
4446
  return tags.map((tag, i) =>
@@ -4641,14 +4474,11 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
4641
4474
  const hideSelect = unpin === false && row.pinned === true;
4642
4475
  const selectTitle = unpin
4643
4476
  ? '取消固定后请求会失败,请手动切换'
4644
- : row.disabled === true
4645
- ? '这个账号已停用:选中它请求会失败,请先启用或换一个'
4646
4477
  : `让 ${row.fullName} 成为「当前账号」,请求只用它`;
4647
4478
  return jsxs(
4648
4479
  'div',
4649
4480
  {
4650
4481
  className: 'wotr-credit-row',
4651
- 'data-off': row.disabled === true ? '1' : '0',
4652
4482
  'data-serving': row.serving === true ? '1' : '0',
4653
4483
  children: [
4654
4484
  jsxs('div', {
@@ -4678,22 +4508,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
4678
4508
  },
4679
4509
  children: label,
4680
4510
  }),
4681
- jsx('button', {
4682
- type: 'button',
4683
- role: 'switch',
4684
- className: 'wotr-credit-switch',
4685
- 'aria-checked': row.disabled === true ? 'false' : 'true',
4686
- 'aria-label': `${row.name} 停用/启用`,
4687
- 'data-on': row.disabled === true ? '0' : '1',
4688
- disabled: busy,
4689
- title:
4690
- row.disabled === true
4691
- ? `启用 ${row.fullName}(恢复参与取号)`
4692
- : `停用 ${row.fullName}(选中它时请求会失败)`,
4693
- onClick: () => {
4694
- void onToggleRow(row);
4695
- },
4696
- }),
4697
4511
  ],
4698
4512
  }),
4699
4513
  ],
@@ -5253,29 +5067,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
5253
5067
  [loadQoder],
5254
5068
  );
5255
5069
 
5256
- /**
5257
- * 停用 / 启用:往 `disabledAccountIds` 里加减这个账号。
5258
- *
5259
- * 必须**读出当前列表再合并** —— 整段覆盖写会把别的账号的停用状态清掉,
5260
- * 表现为「停用了 A,B 自己被启用了」。
5261
- */
5262
- const onQoderToggle = useCallback(
5263
- (accountId, disabled) => {
5264
- const current = asArray(qoderConfigSnapshot().disabledAccountIds).filter(
5265
- (id) => typeof id === 'string',
5266
- );
5267
- const next = disabled === true
5268
- ? [...new Set([...current, accountId])]
5269
- : current.filter((id) => id !== accountId);
5270
- const want = disabled === true;
5271
- return writeQoderPoolField(
5272
- 'disabledAccountIds',
5273
- next,
5274
- (doc) => asArray(doc?.disabledAccountIds).includes(accountId) === want,
5275
- );
5276
- },
5277
- [qoderConfigSnapshot, writeQoderPoolField],
5278
- );
5279
5070
 
5280
5071
  const onQoderRemove = useCallback(
5281
5072
  (accountId) => qoderAction(`${SELF_API}/qoder/pool/remove`, { accountId }),
@@ -5530,7 +5321,6 @@ export function createConsoleSection({ react, jsxRuntime, embedded }) {
5530
5321
  creditsAtMs: qoderCreditsAtMs,
5531
5322
  onRefresh: loadQoder,
5532
5323
  onAddAccount: onQoderAddAccount,
5533
- onToggle: onQoderToggle,
5534
5324
  onRemove: onQoderRemove,
5535
5325
  onSelect: onQoderSelect,
5536
5326
  // 每日签到(按账号,不切号):正在签的 id / 本页各账号的答复 / 顶部结论。
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-kdczyz-mode",
3
- "version": "1.2.2-beta",
3
+ "version": "1.2.4-beta",
4
4
  "description": "WorkBuddy + Trae + Qoder merged into one DSH plugin: the WorkBuddy desktop account/model pool, the Trae connector and the Qoder account pool as three independent providers, plus one settings page with six tabs — two configuration tabs (XD Pool / Trae config: provider switch, account binding, model selection and its own multi-account pool) and four management/read-only tabs (accounts [WorkBuddy + Trae + Qoder, three columns] / Qoder pool / credits / usage history).",
5
5
  "repository": {
6
6
  "type": "git",