@eddyskywalker/dsh-chatgpt-subscription 0.6.0 → 0.6.8

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/lib/client.js CHANGED
@@ -3255,6 +3255,13 @@ window.__ModuleLoader__.load({
3255
3255
  cacheOutput: "输出 tokens",
3256
3256
  cacheRequests: "请求数",
3257
3257
  cacheHint: "同一会话内:系统提示与工具列表一旦变化会使缓存整体失效,因此保持工具集合稳定、把新增内容追加在末尾,命中率最高。",
3258
+ cacheDrift: "最近前缀状态",
3259
+ cacheDriftFirst: "首个请求(缓存为空)",
3260
+ cacheDriftStable: "稳定(前缀未变)",
3261
+ cacheDriftSystemPrompt: "系统提示已变化(缓存失效)",
3262
+ cacheDriftTools: "工具列表已变化(缓存失效)",
3263
+ cacheDriftCacheKey: "缓存键已变化(会话切换)",
3264
+ cacheDriftColdKey: "未发送缓存键(无法命中)",
3258
3265
  preserveThinking: "保留思考 (Preserved Thinking)",
3259
3266
  preserveOn: "已开启(官方默认):跨轮保留 reasoning_content,多轮工具调用更连贯,但思考 token 也计入输出。",
3260
3267
  preserveOff: "已关闭:不要求服务回传推理内容。可设置 DSH_KIMI_CODE_PRESERVE_THINKING=0 关闭。",
@@ -3368,6 +3375,13 @@ window.__ModuleLoader__.load({
3368
3375
  cacheOutput: "Output tokens",
3369
3376
  cacheRequests: "Requests",
3370
3377
  cacheHint: "Within one session: any change to the system prompt or the tool list invalidates the whole prefix cache, so keep the tool set stable and append new material at the tail for the best hit rate.",
3378
+ cacheDrift: "Last prefix state",
3379
+ cacheDriftFirst: "First request (cache cold)",
3380
+ cacheDriftStable: "Stable (prefix unchanged)",
3381
+ cacheDriftSystemPrompt: "System prompt changed (cache invalidated)",
3382
+ cacheDriftTools: "Tool list changed (cache invalidated)",
3383
+ cacheDriftCacheKey: "Cache key changed (session switch)",
3384
+ cacheDriftColdKey: "No cache key sent (cannot hit)",
3371
3385
  preserveThinking: "Preserved Thinking",
3372
3386
  preserveOn: "On (the official default): reasoning_content is retained across turns, which keeps multi-step tool use coherent — its tokens are billed as output.",
3373
3387
  preserveOff: "Off: the service is not asked to return reasoning. Set DSH_KIMI_CODE_PRESERVE_THINKING=0 to disable.",
@@ -3517,6 +3531,18 @@ window.__ModuleLoader__.load({
3517
3531
  max: zh$2.effortMax,
3518
3532
  none: zh$2.effortNone
3519
3533
  };
3534
+ /** Human label for the last request's prefix-drift cause. */
3535
+ function driftLabel(cause, t) {
3536
+ switch (cause) {
3537
+ case "first-request": return t.cacheDriftFirst;
3538
+ case "stable": return t.cacheDriftStable;
3539
+ case "system-prompt": return t.cacheDriftSystemPrompt;
3540
+ case "tools": return t.cacheDriftTools;
3541
+ case "cache-key": return t.cacheDriftCacheKey;
3542
+ case "cold-key": return t.cacheDriftColdKey;
3543
+ default: return String(cause);
3544
+ }
3545
+ }
3520
3546
  function KimiCodeSection({ onModelChange, loadModelDirectory }) {
3521
3547
  const [status, setStatus] = (0, react.useState)(null);
3522
3548
  const [loading, setLoading] = (0, react.useState)(true);
@@ -3974,6 +4000,79 @@ window.__ModuleLoader__.load({
3974
4000
  })
3975
4001
  ]
3976
4002
  }),
4003
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4004
+ className: "dsha-group",
4005
+ children: [
4006
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4007
+ className: "dsha-grouphead",
4008
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.cacheSection })
4009
+ }),
4010
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4011
+ className: "dsha-muted",
4012
+ children: t.cacheDesc
4013
+ }),
4014
+ status?.cache == null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4015
+ className: "dsha-empty",
4016
+ children: t.cacheEmpty
4017
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4018
+ className: "dsha-quota-card",
4019
+ children: [
4020
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4021
+ className: "dsha-meter-wrap",
4022
+ children: [
4023
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4024
+ className: "dsha-meter-label",
4025
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.cacheHitRatio }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: status.cache.hitRatio === null ? "—" : `${(status.cache.hitRatio * 100).toFixed(1)}%` })]
4026
+ }),
4027
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4028
+ className: `dsha-meter ${(status.cache.hitRatio ?? 0) >= .9 ? "dsha-meter-green" : "dsha-meter-cyan"}`,
4029
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${Math.round((status.cache.hitRatio ?? 0) * 100)}%` } })
4030
+ }),
4031
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4032
+ className: "dsha-meter-meta",
4033
+ children: [
4034
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4035
+ t.cacheCached,
4036
+ ": ",
4037
+ status.cache.cachedTokens.toLocaleString()
4038
+ ] }),
4039
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4040
+ t.cacheFresh,
4041
+ ": ",
4042
+ status.cache.freshTokens.toLocaleString()
4043
+ ] }),
4044
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4045
+ t.cacheOutput,
4046
+ ": ",
4047
+ status.cache.outputTokens.toLocaleString()
4048
+ ] }),
4049
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4050
+ t.cacheRequests,
4051
+ ": ",
4052
+ status.cache.requests
4053
+ ] })
4054
+ ]
4055
+ })
4056
+ ]
4057
+ }),
4058
+ status.cache.lastDrift !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4059
+ className: "dsha-row",
4060
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4061
+ className: "dsha-label",
4062
+ children: t.cacheDrift
4063
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4064
+ className: "dsha-value",
4065
+ children: driftLabel(status.cache.lastDrift, t)
4066
+ })]
4067
+ }),
4068
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4069
+ className: "dsha-muted",
4070
+ children: t.cacheHint
4071
+ })
4072
+ ]
4073
+ })
4074
+ ]
4075
+ }),
3977
4076
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3978
4077
  className: "dsha-group",
3979
4078
  children: [
@@ -4217,41 +4316,28 @@ window.__ModuleLoader__.load({
4217
4316
  title: "WorkBuddy",
4218
4317
  pageDesc: "复用本机 CodeBuddy 桌面端登录态,管理 WorkBuddy(CodeBuddy 订阅)模型、上下文窗口与额度。",
4219
4318
  account: "账号",
4220
- noAccounts: "暂无账号,点击「添加国区账号 / 添加国际区账号」完成浏览器授权,或登录 CodeBuddy 桌面端后重新扫描。",
4221
- signedIn: "已找到凭据",
4319
+ noAccounts: "暂无账号。点击右上角「添加账号」完成浏览器授权,或登录 CodeBuddy 桌面端后重新扫描;桌面账号只能从本插件隐藏,绝不删除 CodeBuddy 的原凭据。",
4222
4320
  signedOut: "未找到凭据",
4223
4321
  nickname: "昵称",
4224
- uid: "账号 ID",
4225
4322
  uin: "UIN",
4226
4323
  region: "区域",
4227
4324
  regionCn: "国区",
4228
4325
  regionIntl: "国际区",
4229
4326
  accountType: "账号类型",
4230
- backend: "后端地址",
4231
- domain: "认证域名",
4232
- tokenExpires: "登录态有效期",
4233
- tokenExpired: "已过期",
4234
4327
  sourceFile: "凭据文件",
4235
4328
  authDirectory: "凭据目录",
4236
4329
  storage: "凭据存储",
4237
4330
  storageNotice: "桌面端账号仍读取 CodeBuddy 自己的凭据文件,插件不会删除这些文件;通过这里添加的账号保存在系统加密存储中(Windows DPAPI / macOS Keychain / Linux Secret Service),token 不进入浏览器。",
4238
- notFoundTitle: "未找到 WorkBuddy 账号",
4239
- notFoundHint: "可安装并登录 CodeBuddy 后重新扫描,也可以直接点击下方「添加国区账号」或「添加国际区账号」完成浏览器授权。",
4240
4331
  routeUnreachable: "无法读取 WorkBuddy 设置路由",
4241
4332
  routeUnreachableHint: "浏览器里加载的插件版本可能比 Host 进程里运行的新(客户端资源是现读磁盘的,Host 只在启动时加载)。请重启 DSH,让两端来自同一份构建。",
4242
4333
  rescan: "重新扫描",
4243
4334
  rescanning: "扫描中...",
4244
- accounts: "本机凭据",
4245
- accountsHint: "按账号地区分组。插件添加的账号可删除;CodeBuddy 桌面账号只能从本插件隐藏,绝不删除桌面端原凭据。点击账号会切换模型目录、额度和后续对话。",
4246
- useAccount: "使用此账号",
4247
- selectedAccount: "当前账号",
4335
+ accounts: "账号管理",
4248
4336
  addCnAccount: "添加国区账号",
4249
4337
  addIntlAccount: "添加国际区账号",
4250
4338
  authorizing: "授权中…",
4251
4339
  loginWaiting: "请在新打开的浏览器页面完成登录与授权。",
4252
4340
  loginFailed: "账号授权失败",
4253
- pluginAccount: "插件账号",
4254
- desktopAccount: "桌面账号",
4255
4341
  encryptedStorage: "系统加密存储",
4256
4342
  hiddenAccount: "已隐藏",
4257
4343
  hideAccount: "从插件隐藏",
@@ -4310,41 +4396,28 @@ window.__ModuleLoader__.load({
4310
4396
  title: "WorkBuddy",
4311
4397
  pageDesc: "Reuse the local CodeBuddy desktop sign-in to manage WorkBuddy (CodeBuddy subscription) models, context windows, and quota.",
4312
4398
  account: "Account",
4313
- noAccounts: "No accounts yet. Add a China or international account, or sign in with the CodeBuddy desktop client and rescan.",
4314
- signedIn: "Credential found",
4399
+ noAccounts: "No accounts yet. Use “Add account” above to authorize, or sign in with the CodeBuddy desktop client and rescan; desktop accounts can only be hidden here, never removed from CodeBuddy.",
4315
4400
  signedOut: "No credential found",
4316
4401
  nickname: "Nickname",
4317
- uid: "Account ID",
4318
4402
  uin: "UIN",
4319
4403
  region: "Region",
4320
4404
  regionCn: "China",
4321
4405
  regionIntl: "International",
4322
4406
  accountType: "Account type",
4323
- backend: "Backend",
4324
- domain: "Auth domain",
4325
- tokenExpires: "Sign-in valid until",
4326
- tokenExpired: "Expired",
4327
4407
  sourceFile: "Credential file",
4328
4408
  authDirectory: "Credential directory",
4329
4409
  storage: "Credential storage",
4330
4410
  storageNotice: "Desktop accounts continue to use CodeBuddy’s credential files, which this plugin never deletes. Accounts added here use encrypted OS storage (Windows DPAPI, macOS Keychain, or Linux Secret Service); tokens never enter the browser.",
4331
- notFoundTitle: "No WorkBuddy account found",
4332
- notFoundHint: "Install and sign in to CodeBuddy and rescan, or use “Add China account” / “Add international account” below to authorize in the browser.",
4333
4411
  routeUnreachable: "The WorkBuddy settings route could not be read",
4334
4412
  routeUnreachableHint: "The plugin loaded in the browser may be newer than the one running in the Host: client assets are read from disk on demand, while the Host loads them only at startup. Restart DSH so both halves come from the same build.",
4335
4413
  rescan: "Rescan",
4336
4414
  rescanning: "Scanning...",
4337
- accounts: "Local credentials",
4338
- accountsHint: "Accounts are grouped by region. Plugin-managed accounts can be deleted; CodeBuddy desktop accounts can only be hidden from this plugin and their source files are never deleted. Selecting one switches models, quota, and chats.",
4339
- useAccount: "Use this account",
4340
- selectedAccount: "Selected account",
4415
+ accounts: "Account Management",
4341
4416
  addCnAccount: "Add China account",
4342
4417
  addIntlAccount: "Add international account",
4343
4418
  authorizing: "Authorizing…",
4344
4419
  loginWaiting: "Complete sign-in and authorization in the newly opened browser page.",
4345
4420
  loginFailed: "Account authorization failed",
4346
- pluginAccount: "Plugin account",
4347
- desktopAccount: "Desktop account",
4348
4421
  encryptedStorage: "Encrypted OS storage",
4349
4422
  hiddenAccount: "Hidden",
4350
4423
  hideAccount: "Hide from plugin",
@@ -4421,6 +4494,21 @@ window.__ModuleLoader__.load({
4421
4494
  };
4422
4495
  const API$4 = "/workbuddy/api";
4423
4496
  /**
4497
+ * The shared card's label set.
4498
+ *
4499
+ * Only the three labels WorkBuddy genuinely words differently are taken from
4500
+ * this tab's dictionary; everything else is the shared set, so the five
4501
+ * provider tabs cannot drift apart in wording.
4502
+ */
4503
+ function accountPoolLabels(t) {
4504
+ return {
4505
+ ...accountPoolZh,
4506
+ noAccounts: t.noAccounts,
4507
+ storageNotice: t.storageNotice,
4508
+ email: t.nickname
4509
+ };
4510
+ }
4511
+ /**
4424
4512
  * Call one settings route and unwrap its `{ ok, value }` envelope.
4425
4513
  *
4426
4514
  * The response body is read as text first, because a route that is not mounted
@@ -4538,24 +4626,6 @@ window.__ModuleLoader__.load({
4538
4626
  accounts: Array.isArray(data?.accounts) ? data.accounts : []
4539
4627
  };
4540
4628
  }
4541
- /**
4542
- * The shared card's label set, taken from this tab's dictionary.
4543
- *
4544
- * Wording is the shared one so the five provider tabs cannot drift apart; the
4545
- * couple of WorkBuddy-specific words are supplied here.
4546
- */
4547
- function accountPoolLabels(t) {
4548
- return {
4549
- ...accountPoolZh,
4550
- accountPool: t.accounts,
4551
- noAccounts: t.noAccounts,
4552
- storage: t.storage,
4553
- storageNotice: t.storageNotice,
4554
- deleteAccount: t.deleteAccount,
4555
- email: t.nickname,
4556
- accountId: t.uid
4557
- };
4558
- }
4559
4629
  function WorkBuddySection({ onModelChange, loadModelDirectory }) {
4560
4630
  const [status, setStatus] = (0, react.useState)(null);
4561
4631
  const [loading, setLoading] = (0, react.useState)(true);
@@ -4563,7 +4633,6 @@ window.__ModuleLoader__.load({
4563
4633
  const [error, setError] = (0, react.useState)(null);
4564
4634
  const [statusFailed, setStatusFailed] = (0, react.useState)(false);
4565
4635
  const [connection, setConnection] = (0, react.useState)(null);
4566
- const [accounts, setAccounts] = (0, react.useState)(null);
4567
4636
  const [loginProgress, setLoginProgress] = (0, react.useState)(null);
4568
4637
  const loginIntervalRef = (0, react.useRef)(null);
4569
4638
  const loginTimeoutRef = (0, react.useRef)(null);
@@ -4594,24 +4663,10 @@ window.__ModuleLoader__.load({
4594
4663
  setLoading(false);
4595
4664
  }
4596
4665
  }, []);
4597
- const loadAccounts = (0, react.useCallback)(async () => {
4598
- try {
4599
- const payload = await fetchApi$4("/accounts");
4600
- setAccounts({
4601
- authDirectory: payload?.authDirectory ?? "",
4602
- managedStoragePath: payload?.managedStoragePath,
4603
- accounts: Array.isArray(payload?.accounts) ? payload.accounts : []
4604
- });
4605
- } catch {}
4606
- }, []);
4607
4666
  (0, react.useEffect)(() => {
4608
4667
  loadStatus();
4609
- loadAccounts();
4610
4668
  const refreshWhenVisible = () => {
4611
- if (document.visibilityState === "visible") {
4612
- loadStatus(true);
4613
- loadAccounts();
4614
- }
4669
+ if (document.visibilityState === "visible") loadStatus(true);
4615
4670
  };
4616
4671
  document.addEventListener("visibilitychange", refreshWhenVisible);
4617
4672
  return () => {
@@ -4619,14 +4674,13 @@ window.__ModuleLoader__.load({
4619
4674
  if (loginIntervalRef.current !== null) window.clearInterval(loginIntervalRef.current);
4620
4675
  if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current);
4621
4676
  };
4622
- }, [loadStatus, loadAccounts]);
4677
+ }, [loadStatus]);
4623
4678
  const handleRescan = async () => {
4624
4679
  try {
4625
4680
  setBusy("rescan");
4626
4681
  setError(null);
4627
4682
  const updated = await fetchApi$4("/rescan", { method: "POST" });
4628
- setStatus(updated);
4629
- await loadAccounts();
4683
+ setStatus(normalizeStatus(updated));
4630
4684
  notifyChange();
4631
4685
  } catch (err) {
4632
4686
  setError(err instanceof Error ? err.message : String(err));
@@ -4663,7 +4717,6 @@ window.__ModuleLoader__.load({
4663
4717
  body: JSON.stringify({ selectedAccountId: poll.accountId })
4664
4718
  });
4665
4719
  await loadStatus();
4666
- await loadAccounts();
4667
4720
  notifyChange();
4668
4721
  } else if (poll.status === "error") {
4669
4722
  window.clearInterval(timer);
@@ -4707,7 +4760,6 @@ window.__ModuleLoader__.load({
4707
4760
  })
4708
4761
  });
4709
4762
  setStatus(normalizeStatus(updated));
4710
- await loadAccounts();
4711
4763
  notifyChange();
4712
4764
  } catch (err) {
4713
4765
  setError(err instanceof Error ? err.message : String(err));
@@ -4728,7 +4780,6 @@ window.__ModuleLoader__.load({
4728
4780
  body: JSON.stringify({ strategy })
4729
4781
  });
4730
4782
  setStatus(normalizeStatus(updated));
4731
- await loadAccounts();
4732
4783
  } catch (err) {
4733
4784
  setError(err instanceof Error ? err.message : String(err));
4734
4785
  } finally {
@@ -4881,136 +4932,12 @@ window.__ModuleLoader__.load({
4881
4932
  })
4882
4933
  });
4883
4934
  const quota = status?.quota;
4884
- const account = status?.account;
4885
4935
  const authenticated = status?.authenticated === true;
4886
4936
  const unreachable = statusFailed && status === null;
4887
4937
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4888
4938
  className: "dsha-page",
4889
4939
  children: [
4890
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
4891
- className: "dsha-group",
4892
- children: [
4893
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4894
- className: "dsha-grouphead",
4895
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: authenticated ? t.account : t.signedOut }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4896
- className: "dsha-btn",
4897
- disabled: busy !== null,
4898
- onClick: () => void handleRescan(),
4899
- children: busy === "rescan" ? t.rescanning : t.rescan
4900
- })]
4901
- }),
4902
- unreachable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4903
- className: "dsha-empty",
4904
- children: t.routeUnreachable
4905
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4906
- className: "dsha-notice",
4907
- children: t.routeUnreachableHint
4908
- })] }) : !authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4909
- className: "dsha-empty",
4910
- children: t.notFoundTitle
4911
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
4912
- className: "dsha-notice",
4913
- children: t.notFoundHint
4914
- })] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
4915
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4916
- className: "dsha-row",
4917
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4918
- className: "dsha-label",
4919
- children: t.nickname
4920
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4921
- className: "dsha-value",
4922
- children: account?.nickname || "—"
4923
- })]
4924
- }),
4925
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4926
- className: "dsha-row",
4927
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4928
- className: "dsha-label",
4929
- children: t.uid
4930
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4931
- className: "dsha-value dshwb-mono",
4932
- children: account?.uid || "—"
4933
- })]
4934
- }),
4935
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4936
- className: "dsha-row",
4937
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4938
- className: "dsha-label",
4939
- children: t.uin
4940
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4941
- className: "dsha-value dshwb-mono",
4942
- children: maskUin(account?.uin)
4943
- })]
4944
- }),
4945
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4946
- className: "dsha-row",
4947
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4948
- className: "dsha-label",
4949
- children: t.region
4950
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
4951
- className: "dsha-value",
4952
- children: [account?.region === "intl" ? t.regionIntl : t.regionCn, account?.accountType ? ` · ${account.accountType}` : ""]
4953
- })]
4954
- }),
4955
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4956
- className: "dsha-row",
4957
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4958
- className: "dsha-label",
4959
- children: t.domain
4960
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4961
- className: "dsha-value dshwb-mono",
4962
- children: account?.domain || "—"
4963
- })]
4964
- }),
4965
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4966
- className: "dsha-row",
4967
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4968
- className: "dsha-label",
4969
- children: t.backend
4970
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4971
- className: "dsha-value dshwb-mono",
4972
- children: account?.backend || "—"
4973
- })]
4974
- }),
4975
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4976
- className: "dsha-row",
4977
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4978
- className: "dsha-label",
4979
- children: t.tokenExpires
4980
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4981
- className: "dsha-value",
4982
- children: account?.expiresAt === null || account?.expiresAt === void 0 ? "—" : account.expiresAt <= Date.now() ? t.tokenExpired : formatDate(account.expiresAt)
4983
- })]
4984
- }),
4985
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4986
- className: "dsha-row",
4987
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4988
- className: "dsha-label",
4989
- children: t.sourceFile
4990
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4991
- className: "dsha-value dshwb-mono",
4992
- title: account?.sourceFile ?? status?.managedStoragePath ?? "",
4993
- children: account?.source === "managed" ? t.encryptedStorage : displayFile(account?.sourceFile)
4994
- })]
4995
- })
4996
- ] }),
4997
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4998
- className: "dsha-row",
4999
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5000
- className: "dsha-label",
5001
- children: t.authDirectory
5002
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5003
- className: "dsha-value dshwb-mono",
5004
- children: status?.authDirectory || "—"
5005
- })]
5006
- }),
5007
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5008
- className: "dsha-notice",
5009
- children: t.storageNotice
5010
- })
5011
- ]
5012
- }),
5013
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountPoolSection, {
4940
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AccountPoolSection, {
5014
4941
  accounts: poolAccounts,
5015
4942
  activeAccountId: status?.activeAccountId,
5016
4943
  rotationStrategy: status?.rotationStrategy ?? "sequential",
@@ -5026,12 +4953,12 @@ window.__ModuleLoader__.load({
5026
4953
  renderLoginActions: () => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5027
4954
  className: "dsha-account-add-actions",
5028
4955
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5029
- className: "dsha-btn",
4956
+ className: "dsha-btn dsha-btn-primary",
5030
4957
  disabled: busy !== null,
5031
4958
  onClick: () => void handleAddAccount("cn"),
5032
4959
  children: busy === "login:cn" ? t.authorizing : t.addCnAccount
5033
4960
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5034
- className: "dsha-btn",
4961
+ className: "dsha-btn dsha-btn-primary",
5035
4962
  disabled: busy !== null,
5036
4963
  onClick: () => void handleAddAccount("intl"),
5037
4964
  children: busy === "login:intl" ? t.authorizing : t.addIntlAccount
@@ -5049,27 +4976,67 @@ window.__ModuleLoader__.load({
5049
4976
  children: t.hideAccount
5050
4977
  })] }),
5051
4978
  renderDetails: (candidate) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
5052
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
5053
- t.region,
5054
- ": ",
5055
- candidate.region === "intl" ? t.regionIntl : t.regionCn
5056
- ] }),
5057
4979
  candidate.uin ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
5058
4980
  t.uin,
5059
4981
  ": ",
5060
4982
  maskUin(candidate.uin)
5061
4983
  ] }) : null,
4984
+ candidate.accountType ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4985
+ t.accountType,
4986
+ ": ",
4987
+ candidate.accountType
4988
+ ] }) : null,
4989
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
4990
+ t.region,
4991
+ ": ",
4992
+ candidate.region === "intl" ? t.regionIntl : t.regionCn
4993
+ ] }),
4994
+ candidate.domain ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4995
+ className: "dshwb-mono",
4996
+ title: `${candidate.domain} · ${candidate.backend ?? ""}`,
4997
+ children: candidate.domain
4998
+ }) : null,
5062
4999
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5063
5000
  className: "dshwb-mono",
5064
5001
  children: candidate.source === "managed" ? t.encryptedStorage : displayFile(candidate.sourceFile)
5065
5002
  }),
5066
5003
  candidate.hidden === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.hiddenAccount }) : null
5067
- ] })
5004
+ ] }),
5005
+ children: [
5006
+ unreachable ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5007
+ className: "dsha-empty",
5008
+ children: t.routeUnreachable
5009
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5010
+ className: "dsha-notice",
5011
+ children: t.routeUnreachableHint
5012
+ })] }) : null,
5013
+ loginProgress ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5014
+ className: "dsha-notice",
5015
+ children: loginProgress
5016
+ }) : null,
5017
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5018
+ className: "dsha-row",
5019
+ style: { marginTop: 12 },
5020
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5021
+ className: "dsha-label",
5022
+ children: t.authDirectory
5023
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5024
+ className: "dsha-value dshwb-mono",
5025
+ title: status?.authDirectory || "",
5026
+ children: status?.authDirectory || "—"
5027
+ })]
5028
+ }),
5029
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5030
+ className: "dsha-actions",
5031
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5032
+ className: "dsha-btn",
5033
+ disabled: busy !== null,
5034
+ onClick: () => void handleRescan(),
5035
+ children: busy === "rescan" ? t.rescanning : t.rescan
5036
+ })
5037
+ })
5038
+ ]
5068
5039
  }),
5069
- loginProgress ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5070
- className: "dsha-notice",
5071
- children: loginProgress
5072
- }) : null,
5073
5040
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5074
5041
  className: "dsha-group",
5075
5042
  children: [
@@ -5145,26 +5112,22 @@ window.__ModuleLoader__.load({
5145
5112
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5146
5113
  className: "dsha-models",
5147
5114
  "aria-label": "WorkBuddy Models",
5148
- children: status?.models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
5149
- title: model.description ?? model.id,
5150
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
5151
- type: "checkbox",
5152
- checked: model.enabled,
5153
- disabled: busy !== null,
5154
- onChange: (event) => void toggleModel(model.id, event.currentTarget.checked)
5155
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5156
- className: "dshwb-model",
5157
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5158
- className: "dshwb-model-meta",
5159
- children: [
5160
- formatCapacity(model.contextWindow),
5161
- " · ",
5162
- model.supportsImage ? t.imageSupport : t.textOnly,
5163
- model.reasoningEfforts && model.reasoningEfforts.length > 0 ? ` · ${model.reasoningEfforts.join("/")}` : ""
5164
- ]
5165
- })]
5166
- })]
5167
- }, model.id))
5115
+ children: status?.models.map((model) => {
5116
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
5117
+ title: [
5118
+ model.id,
5119
+ formatCapacity(model.contextWindow),
5120
+ model.supportsImage ? t.imageSupport : t.textOnly,
5121
+ ...model.reasoningEfforts && model.reasoningEfforts.length > 0 ? [model.reasoningEfforts.join("/")] : []
5122
+ ].join(" · "),
5123
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
5124
+ type: "checkbox",
5125
+ checked: model.enabled,
5126
+ disabled: busy !== null,
5127
+ onChange: (event) => void toggleModel(model.id, event.currentTarget.checked)
5128
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name })]
5129
+ }, model.id);
5130
+ })
5168
5131
  }),
5169
5132
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5170
5133
  className: "dsha-actions",
@@ -6488,29 +6451,24 @@ window.__ModuleLoader__.load({
6488
6451
  /**
6489
6452
  * WorkBuddy-only additions to the shared settings design system.
6490
6453
  *
6491
- * The base control styles (`.dsha-page`, `.dsha-group`, `.dsha-models`, …) come
6492
- * from the stylesheet the sibling routes install, so this file declares only
6493
- * what is unique to this card: the per-model capability line and the
6494
- * "unavailable in this region" treatment.
6454
+ * The base control styles (`.dsha-page`, `.dsha-group`, `.dsha-models`, the
6455
+ * account card, …) come from the stylesheet the sibling routes install, in the
6456
+ * same order the client installs them, so this file declares only what stays
6457
+ * unique to this card: the mono credential paths and the login-progress line.
6458
+ *
6459
+ * Everything this tab used to declare locally — the per-model capability line
6460
+ * and the account-region headings — is gone: the model pill is name-only like
6461
+ * every sibling tab, and the account card is the shared one.
6495
6462
  */
6496
6463
  function installWorkBuddyStyles() {
6497
6464
  if (typeof document === "undefined" || document.getElementById("dsh-workbuddy-settings-style")) return;
6498
6465
  const style = document.createElement("style");
6499
6466
  style.id = STYLE_ID;
6500
6467
  style.textContent = `
6501
- .dshwb-model{display:flex;flex-direction:column;gap:2px;min-width:0}
6502
- .dshwb-model-meta{color:var(--dsw-alias-label-tertiary);font-size:10px;font-weight:400;line-height:1.3;white-space:nowrap}
6503
- .dsha-models input:checked+span .dshwb-model-meta{color:var(--dsw-alias-label-secondary)}
6504
- .dshwb-region{display:inline-flex;align-items:center;gap:4px}
6505
- .dshwb-muted-note{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.5;margin:8px 0 0}
6506
6468
  .dshwb-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}
6507
- .dsha-account-region{margin-top:14px}
6508
- .dsha-account-region h4{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:650;margin:0 0 8px}
6509
6469
  .dsha-account-add-actions{display:flex;flex-wrap:wrap;gap:8px}
6510
- .dsha-account-card.hidden{opacity:.68}
6511
- .dshwb-account-select{appearance:none;background:transparent;border:0;color:inherit;cursor:pointer;font:inherit;padding:0;text-align:left;width:100%}
6512
- .dshwb-account-select:disabled{cursor:default}
6513
- .dshwb-account-select:hover:not(:disabled) .dsha-account-title{color:var(--dsw-alias-label-link,#397ee8)}
6470
+ .dsha-account-add-actions .dsha-btn{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}
6471
+ .dsha-account-add-actions .dsha-btn:hover:not(:disabled){opacity:.9;background:var(--dsw-alias-button-info-fill,#397ee8)}
6514
6472
  `;
6515
6473
  document.head.append(style);
6516
6474
  }