@eddyskywalker/dsh-chatgpt-subscription 0.54.0 → 0.55.0

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/lib/client.js +156 -6
  3. package/lib/client.js.map +1 -1
  4. package/lib/{entry-progress-updates-BEkdyDZU.js → entry-progress-updates-CxQewio9.js} +4 -2
  5. package/lib/index.js +933 -169
  6. package/lib/progress-updates.js +1 -1
  7. package/lib/types/client/common/host-locale-mirror.d.ts +24 -0
  8. package/lib/types/client/common/host-locale-mirror.d.ts.map +1 -0
  9. package/lib/types/client/hub/HubOverview.d.ts.map +1 -1
  10. package/lib/types/client/hub/providers.d.ts +18 -1
  11. package/lib/types/client/hub/providers.d.ts.map +1 -1
  12. package/lib/types/client/index.d.ts.map +1 -1
  13. package/lib/types/client/locales-ru/hub.d.ts.map +1 -1
  14. package/lib/types/client/locales-ru/progress-updates.d.ts.map +1 -1
  15. package/lib/types/client/locales.d.ts +27 -1
  16. package/lib/types/client/locales.d.ts.map +1 -1
  17. package/lib/types/client/progress-updates/locales.d.ts +5 -2
  18. package/lib/types/client/progress-updates/locales.d.ts.map +1 -1
  19. package/lib/types/client/progress-updates/settings-binding.d.ts +1 -1
  20. package/lib/types/client/progress-updates/settings-binding.d.ts.map +1 -1
  21. package/lib/types/client/progress-updates/settings-section.d.ts.map +1 -1
  22. package/lib/types/compat.d.ts +1 -1
  23. package/lib/types/host/adapter.d.ts.map +1 -1
  24. package/lib/types/host/antigravity/adapter.d.ts.map +1 -1
  25. package/lib/types/host/claude/adapter.d.ts.map +1 -1
  26. package/lib/types/host/cline-pass/adapter.d.ts.map +1 -1
  27. package/lib/types/host/codex-account-pool.d.ts.map +1 -1
  28. package/lib/types/host/command-code/adapter.d.ts.map +1 -1
  29. package/lib/types/host/common/account-pool.d.ts.map +1 -1
  30. package/lib/types/host/common/i18n/en.d.ts +9 -0
  31. package/lib/types/host/common/i18n/en.d.ts.map +1 -0
  32. package/lib/types/host/common/i18n/index.d.ts +13 -0
  33. package/lib/types/host/common/i18n/index.d.ts.map +1 -0
  34. package/lib/types/host/common/i18n/provider-name.d.ts +10 -0
  35. package/lib/types/host/common/i18n/provider-name.d.ts.map +1 -0
  36. package/lib/types/host/common/i18n/ru.d.ts +10 -0
  37. package/lib/types/host/common/i18n/ru.d.ts.map +1 -0
  38. package/lib/types/host/common/i18n/runtime.d.ts +54 -0
  39. package/lib/types/host/common/i18n/runtime.d.ts.map +1 -0
  40. package/lib/types/host/common/i18n/t.d.ts +38 -0
  41. package/lib/types/host/common/i18n/t.d.ts.map +1 -0
  42. package/lib/types/host/common/i18n/zh.d.ts +167 -0
  43. package/lib/types/host/common/i18n/zh.d.ts.map +1 -0
  44. package/lib/types/host/glm-coding-plan/adapter.d.ts.map +1 -1
  45. package/lib/types/host/glm-coding-plan/client.d.ts.map +1 -1
  46. package/lib/types/host/glm-coding-plan/oauth.d.ts.map +1 -1
  47. package/lib/types/host/glm-coding-plan/routes.d.ts.map +1 -1
  48. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  49. package/lib/types/host/minimax-code/adapter.d.ts.map +1 -1
  50. package/lib/types/host/ollama/adapter.d.ts.map +1 -1
  51. package/lib/types/host/opendesign/adapter.d.ts.map +1 -1
  52. package/lib/types/host/progress-updates/prompt.d.ts +1 -1
  53. package/lib/types/host/progress-updates/prompt.d.ts.map +1 -1
  54. package/lib/types/host/qoder/account-pool.d.ts.map +1 -1
  55. package/lib/types/host/qoder/adapter.d.ts.map +1 -1
  56. package/lib/types/host/qoder/client.d.ts.map +1 -1
  57. package/lib/types/host/qoder/oauth.d.ts.map +1 -1
  58. package/lib/types/host/qoder/routes.d.ts.map +1 -1
  59. package/lib/types/host/qoder/token-store.d.ts.map +1 -1
  60. package/lib/types/host/routes.d.ts.map +1 -1
  61. package/lib/types/host/step-code/account-pool.d.ts.map +1 -1
  62. package/lib/types/host/step-code/adapter.d.ts.map +1 -1
  63. package/lib/types/host/step-code/oauth.d.ts.map +1 -1
  64. package/lib/types/host/step-code/routes.d.ts.map +1 -1
  65. package/lib/types/host/step-code/token-store.d.ts.map +1 -1
  66. package/lib/types/host/workbuddy/account-pool.d.ts.map +1 -1
  67. package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
  68. package/lib/types/host/workbuddy/oauth.d.ts.map +1 -1
  69. package/lib/types/index.d.ts.map +1 -1
  70. package/lib/types/shared/i18n-contracts.d.ts +35 -0
  71. package/lib/types/shared/i18n-contracts.d.ts.map +1 -0
  72. package/locale/progress-updates/ru.json +6 -0
  73. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.55.0 - 2026-11-02
6
+
7
+ - **[i18n] 宿主侧也能说中英俄:一条镜像缝把界面语言送进线路名与宿主文案**
8
+ - **现状**:设置卡与 Hub 早就有 zh/en 两套字典、俄语语言包(#65)也已覆盖 14 个命名空间,但**宿主说的话只有中文**——`providerInfo()` 的线路名、额度失败、429 冷却、登录流程与号池报错全是中文常量,英文/俄语界面照样显示中文。
9
+ - **缝**:宿主没有 locale 服务,harness 的 `LlmProviderInfo` 也不带语言位。于是由客户端把 `ctx.locale.getSnapshot().active` 镜像到新的 `POST /i18n/locale`(沿用既有同源 POST 校验),宿主侧一个模块级运行时在任何出话时刻读取它。默认语言是 `zh`,没被镜像过的安装保持原话术。
10
+ - 新增 `src/shared/i18n-contracts.ts`(`zh-CN`→`zh`、`ru-RU`→`ru`、未知→`zh`)与 `src/host/common/i18n/`(运行时、`t()` 插值、三份字典;`en`/`ru` 用 `Record<HostLocaleKey, string>` 由类型强制与中文键集对齐)。
11
+ - **线路名**:13 个 `providerInfo()` 改走 `localizedProviderName()`;Hub 卡片名与详情页标题改走新增的 `cardName.<id>` 键(三语)。
12
+ - **文案**:ChatGPT 号池、Antigravity 429、WorkBuddy(登录流程 + 号池)、Qoder(登录 / 令牌 / 额度 / 路由 / 凭据)、Step Code(登录阶段 / 授权地址 / 号池 / 路由 / 凭据)、GLM(额度接口 / 三条 429 冷却 / ZCode 登录全流程 / 路由)的用户可见文案全部入字典;**中文模板逐字保留**,因此既有断言一条未改。
13
+ - **进度更新**新增 `ru` 语言档(`auto` / `zh` / `en` / `ru`)与 `locale/progress-updates/ru.json`。
14
+ - 仍为中文(有意保留):各线路 mapper 与兑换链的**内部诊断**、开发者日志、静态模型目录描述、widget-board 看板文案(后者本身已中英双写在一个字符串里)。
15
+ - **验证**:`npm run typecheck` 0 错误;全量 Vitest 357 文件 / **6550 项通过**(另有 2 文件 / 9 项跳过);`lib/` 干净重建后 `npm run build` 与 `npm pack --dry-run` 通过;真机 GUI 三语视觉验收(同 1280×800、深色主题):中文与改动前逐字一致,English / Русский 下 Hub 卡片名与新增语言档正确切换。
16
+
5
17
  ## 0.54.0 - 2026-11-02
6
18
 
7
19
  - **[provider parity] 对照官方 Agent / 客户端修复其余线路的能力与性能差异**:
package/lib/client.js CHANGED
@@ -9319,7 +9319,7 @@ window.__ModuleLoader__.load({
9319
9319
  * 除 adopt 与 connection/test 外,全部走共享的 { ok, value } 信封,
9320
9320
  * 因此答案都是裸 DTO——createLineApi 已经把信封拆掉了。
9321
9321
  */
9322
- const api$12 = createLineApi(GLM_CODING_PLAN_ROUTE_PREFIX, "GLM(ZCode 账号)");
9322
+ const api$12 = createLineApi(GLM_CODING_PLAN_ROUTE_PREFIX, GLM_CODING_PLAN_PROVIDER_NAME);
9323
9323
  const get$2 = api$12.get;
9324
9324
  const post$3 = api$12.post;
9325
9325
  function messageOf$2(cause) {
@@ -20327,6 +20327,23 @@ window.__ModuleLoader__.load({
20327
20327
  if (!response.ok || !envelope.ok) throw new Error(envelope.error?.message ?? "Request failed");
20328
20328
  }
20329
20329
  /** Card order on the overview; also the former tab order. */
20330
+ /**
20331
+ * Card name for one provider in the language in force.
20332
+ *
20333
+ * The dictionary owns the name so a language pack can translate it; the
20334
+ * descriptor's literal is what a build without that key renders, and comparing
20335
+ * the lookup against the key itself is how a miss is recognised (the locale
20336
+ * service answers with the key when nothing declares it).
20337
+ *
20338
+ * @param descriptor - Provider whose card is being rendered.
20339
+ * @param t - Bound translator of the hub's namespace.
20340
+ * @returns Localized card name.
20341
+ */
20342
+ function hubCardName(descriptor, t) {
20343
+ const key = `cardName.${descriptor.id}`;
20344
+ const text = t(key);
20345
+ return text === key ? descriptor.name : text;
20346
+ }
20330
20347
  const HUB_PROVIDERS = [
20331
20348
  {
20332
20349
  id: "chatgpt",
@@ -20534,6 +20551,7 @@ window.__ModuleLoader__.load({
20534
20551
  function HubProviderCard(props) {
20535
20552
  const { descriptor, summary, t } = props;
20536
20553
  const enabled = summary?.enabled ?? true;
20554
+ const cardName = hubCardName(descriptor, t);
20537
20555
  const annotation = props.toggleError ?? cardAnnotation(summary, descriptor, t);
20538
20556
  const canToggle = descriptor.setEnabled !== null && (summary?.canToggle ?? true);
20539
20557
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -20542,7 +20560,7 @@ window.__ModuleLoader__.load({
20542
20560
  className: "dsh-hub-card",
20543
20561
  "data-enabled": enabled,
20544
20562
  "aria-label": formatPoolLabel(t("hubCardLabel"), {
20545
- name: descriptor.name,
20563
+ name: cardName,
20546
20564
  annotation
20547
20565
  }),
20548
20566
  onClick: () => props.onOpen(descriptor.id),
@@ -20558,7 +20576,7 @@ window.__ModuleLoader__.load({
20558
20576
  className: "dsh-hub-card-copy",
20559
20577
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
20560
20578
  className: "dsh-hub-card-name",
20561
- children: descriptor.name
20579
+ children: cardName
20562
20580
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
20563
20581
  className: `dsh-hub-card-note${props.toggleError !== null || summary?.error === true ? " dsh-hub-note-danger" : ""}`,
20564
20582
  children: annotation
@@ -20570,7 +20588,7 @@ window.__ModuleLoader__.load({
20570
20588
  type: "button",
20571
20589
  role: "switch",
20572
20590
  "aria-checked": enabled,
20573
- "aria-label": formatPoolLabel(t(enabled ? "hubSwitchOff" : "hubSwitchOn"), { name: descriptor.name }),
20591
+ "aria-label": formatPoolLabel(t(enabled ? "hubSwitchOff" : "hubSwitchOn"), { name: cardName }),
20574
20592
  className: "dsh-hub-switch",
20575
20593
  disabled: props.busy || summary === void 0,
20576
20594
  onClick: (event) => {
@@ -20907,7 +20925,7 @@ window.__ModuleLoader__.load({
20907
20925
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
20908
20926
  className: "dsh-hub-backbar-name",
20909
20927
  id: "dsh-hub-detail-name",
20910
- children: descriptor.name
20928
+ children: hubCardName(descriptor, t)
20911
20929
  })]
20912
20930
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
20913
20931
  className: "dsh-hub-detail",
@@ -21118,6 +21136,19 @@ window.__ModuleLoader__.load({
21118
21136
  stopImportingLabel: "停止导入全部本机登录(当前 {count} 个)",
21119
21137
  stopImportingBusy: "停止导入中…",
21120
21138
  stopImportingHint: "停止导入只会让本插件忘记本机 CLI 登录的副本;Codex CLI 自己的登录文件不会被删除或修改。账号池不允许逐条删除借来的凭据,所以这里一次会停止全部导入。",
21139
+ "cardName.chatgpt": "ChatGPT",
21140
+ "cardName.antigravity": "Antigravity",
21141
+ "cardName.command-code": "Command Code",
21142
+ "cardName.kimi-code": "Kimi Code",
21143
+ "cardName.minimax-code": "MiniMax Code",
21144
+ "cardName.glm-coding-plan": "GLM(ZCode 账号)",
21145
+ "cardName.claude": "Claude",
21146
+ "cardName.ollama": "Ollama",
21147
+ "cardName.step-code": "Step Code(Step Plan 订阅)",
21148
+ "cardName.cline-pass": "Cline Pass",
21149
+ "cardName.qoder": "Qoder(订阅)",
21150
+ "cardName.opendesign": "OpenDesign",
21151
+ "cardName.workbuddy": "WorkBuddy",
21121
21152
  modelChecklistCount: "已启用 {count}/{total}"
21122
21153
  },
21123
21154
  en: {
@@ -21315,10 +21346,108 @@ window.__ModuleLoader__.load({
21315
21346
  stopImportingLabel: "Stop importing all local sign-ins ({count} currently imported)",
21316
21347
  stopImportingBusy: "Stopping the import…",
21317
21348
  stopImportingHint: "Stopping the import only makes this plugin forget its copy of the local CLI sign-in; the Codex CLI own sign-in file is never deleted or changed. The account pool does not allow deleting a borrowed credential one at a time, so this stops every import at once.",
21349
+ "cardName.chatgpt": "ChatGPT",
21350
+ "cardName.antigravity": "Antigravity",
21351
+ "cardName.command-code": "Command Code",
21352
+ "cardName.kimi-code": "Kimi Code",
21353
+ "cardName.minimax-code": "MiniMax Code",
21354
+ "cardName.glm-coding-plan": "GLM (ZCode Account)",
21355
+ "cardName.claude": "Claude",
21356
+ "cardName.ollama": "Ollama",
21357
+ "cardName.step-code": "Step Code (Step Plan Subscription)",
21358
+ "cardName.cline-pass": "Cline Pass",
21359
+ "cardName.qoder": "Qoder Subscription",
21360
+ "cardName.opendesign": "OpenDesign",
21361
+ "cardName.workbuddy": "WorkBuddy",
21318
21362
  modelChecklistCount: "{count}/{total} enabled"
21319
21363
  }
21320
21364
  };
21321
21365
  //#endregion
21366
+ //#region src/shared/i18n-contracts.ts
21367
+ /**
21368
+ * Language ids this plugin speaks, and the one parser that decides which one a
21369
+ * tag means.
21370
+ *
21371
+ * The Host has no locale service of its own: the browser decides the active
21372
+ * language and the Host only learns it because the client mirrors it back. So
21373
+ * both halves must agree on one normalization rule, and this module is it —
21374
+ * shared, dependency-free and identical on both sides of the wire.
21375
+ * @module dsh-chatgpt-subscription/i18n-contracts
21376
+ */
21377
+ /** Every language this plugin can answer in, in the order a picker shows them. */
21378
+ const SUPPORTED_LOCALES = [
21379
+ "zh",
21380
+ "en",
21381
+ "ru"
21382
+ ];
21383
+ /**
21384
+ * Reduce a BCP 47 tag (or anything a caller offers) to one supported language.
21385
+ *
21386
+ * `zh-CN`, `zh_TW` and `ZH` are all `zh`; `ru-RU` is `ru`; an unsupported
21387
+ * language (`fr`, `ja`) and a missing value both fall back to
21388
+ * {@link DEFAULT_LOCALE} rather than throwing — a language hint is never worth
21389
+ * failing a request over.
21390
+ *
21391
+ * @param tag - Candidate tag from a URL, a header, a settings document or an event.
21392
+ * @returns The supported language to answer in.
21393
+ */
21394
+ function normalizeLocale(tag) {
21395
+ if (typeof tag !== "string") return "zh";
21396
+ const base = tag.trim().toLowerCase().split(/[-_]/)[0];
21397
+ return SUPPORTED_LOCALES.find((id) => id === base) ?? "zh";
21398
+ }
21399
+ //#endregion
21400
+ //#region src/client/common/host-locale-mirror.ts
21401
+ /** How long a switch is coalesced for; one locale change can emit more than once. */
21402
+ const DEBOUNCE_MS = 200;
21403
+ /**
21404
+ * Mirror the active locale into the Host, now and on every later switch.
21405
+ *
21406
+ * @param locale - The plugin context's locale runtime, when the harness has one.
21407
+ * @returns Teardown for the subscription; a no-op when there is no runtime.
21408
+ */
21409
+ function installHostLocaleMirror(locale) {
21410
+ if (locale === void 0 || typeof locale.getSnapshot !== "function") return () => {};
21411
+ const activeOf = () => {
21412
+ try {
21413
+ return String(locale.getSnapshot().active ?? "");
21414
+ } catch {
21415
+ return "";
21416
+ }
21417
+ };
21418
+ let sent;
21419
+ let timer;
21420
+ let disposed = false;
21421
+ const push = () => {
21422
+ if (disposed) return;
21423
+ const next = normalizeLocale(activeOf());
21424
+ if (next === sent) return;
21425
+ sent = next;
21426
+ fetch(`${ROUTE_PREFIX}/i18n/locale`, {
21427
+ method: "POST",
21428
+ headers: { "content-type": "application/json" },
21429
+ body: JSON.stringify({ locale: next })
21430
+ }).catch(() => {
21431
+ sent = void 0;
21432
+ });
21433
+ };
21434
+ const schedule = () => {
21435
+ if (disposed) return;
21436
+ if (timer !== void 0) clearTimeout(timer);
21437
+ timer = setTimeout(() => {
21438
+ timer = void 0;
21439
+ push();
21440
+ }, DEBOUNCE_MS);
21441
+ };
21442
+ push();
21443
+ const unsubscribe = typeof locale.subscribe === "function" ? locale.subscribe(schedule) : () => {};
21444
+ return () => {
21445
+ disposed = true;
21446
+ if (timer !== void 0) clearTimeout(timer);
21447
+ unsubscribe();
21448
+ };
21449
+ }
21450
+ //#endregion
21322
21451
  //#region src/client/progress-updates/locales.ts
21323
21452
  /**
21324
21453
  * 「进展更新」在 locale 服务里的命名空间。
@@ -21377,6 +21506,7 @@ window.__ModuleLoader__.load({
21377
21506
  settingsLanguageAuto: "自动(跟随对话)",
21378
21507
  settingsLanguageZh: "中文",
21379
21508
  settingsLanguageEn: "English",
21509
+ settingsLanguageRu: "Русский",
21380
21510
  settingsPanelName: "进展面板",
21381
21511
  settingsPanelNote: "在右侧栏查看本次会话的全部进展",
21382
21512
  settingsUnavailable: "这项设置当前不可修改(宿主没有开放配置表单)",
@@ -21423,6 +21553,7 @@ window.__ModuleLoader__.load({
21423
21553
  settingsLanguageAuto: "Auto (follow the conversation)",
21424
21554
  settingsLanguageZh: "Chinese",
21425
21555
  settingsLanguageEn: "English",
21556
+ settingsLanguageRu: "Russian",
21426
21557
  settingsPanelName: "Progress panel",
21427
21558
  settingsPanelNote: "See every update from this session in the right sidebar",
21428
21559
  settingsUnavailable: "This setting cannot be changed right now (the host serves no config form)",
@@ -22212,6 +22343,19 @@ window.__ModuleLoader__.load({
22212
22343
  stopImportingLabel: "Остановить импорт всех локальных входов (сейчас {count})",
22213
22344
  stopImportingBusy: "Останавливаем импорт…",
22214
22345
  stopImportingHint: "Остановка лишь заставляет плагин забыть копию входа локального CLI; собственный файл входа Codex CLI не удаляется и не меняется. Пул аккаунтов не позволяет удалять заимствованные учётные данные по одному, поэтому здесь импорт останавливается сразу для всех.",
22346
+ "cardName.chatgpt": "ChatGPT",
22347
+ "cardName.antigravity": "Antigravity",
22348
+ "cardName.command-code": "Command Code",
22349
+ "cardName.kimi-code": "Kimi Code",
22350
+ "cardName.minimax-code": "MiniMax Code",
22351
+ "cardName.glm-coding-plan": "GLM (аккаунт ZCode)",
22352
+ "cardName.claude": "Claude",
22353
+ "cardName.ollama": "Ollama",
22354
+ "cardName.step-code": "Step Code (подписка Step Plan)",
22355
+ "cardName.cline-pass": "Cline Pass",
22356
+ "cardName.qoder": "Qoder (подписка)",
22357
+ "cardName.opendesign": "OpenDesign",
22358
+ "cardName.workbuddy": "WorkBuddy",
22215
22359
  modelChecklistCount: "Включено {count}/{total}"
22216
22360
  };
22217
22361
  //#endregion
@@ -22793,6 +22937,7 @@ window.__ModuleLoader__.load({
22793
22937
  settingsLanguageAuto: "Авто (как в диалоге)",
22794
22938
  settingsLanguageZh: "Китайский",
22795
22939
  settingsLanguageEn: "English",
22940
+ settingsLanguageRu: "Русский",
22796
22941
  settingsPanelName: "Панель хода работы",
22797
22942
  settingsPanelNote: "Показывать все записи этой сессии в правой панели",
22798
22943
  settingsUnavailable: "Эту настройку сейчас нельзя изменить (Host не предоставляет форму настроек)",
@@ -55234,7 +55379,7 @@ window.__ModuleLoader__.load({
55234
55379
  const planModePipeline = value.planModePipeline !== false;
55235
55380
  const dispatchExecutionGuard = value.dispatchExecutionGuard !== false;
55236
55381
  const threshold = typeof value.progressUpdatesNudgeThreshold === "number" ? value.progressUpdatesNudgeThreshold : 8;
55237
- const language = value.progressUpdatesLanguage === "zh" || value.progressUpdatesLanguage === "en" ? value.progressUpdatesLanguage : "auto";
55382
+ const language = value.progressUpdatesLanguage === "zh" || value.progressUpdatesLanguage === "en" || value.progressUpdatesLanguage === "ru" ? value.progressUpdatesLanguage : "auto";
55238
55383
  const [draft, setDraft] = (0, react.useState)(() => String(threshold));
55239
55384
  (0, react.useEffect)(() => {
55240
55385
  setDraft(String(threshold));
@@ -55487,6 +55632,10 @@ window.__ModuleLoader__.load({
55487
55632
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
55488
55633
  value: "en",
55489
55634
  children: translate("settingsLanguageEn")
55635
+ }),
55636
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
55637
+ value: "ru",
55638
+ children: translate("settingsLanguageRu")
55490
55639
  })
55491
55640
  ]
55492
55641
  })
@@ -58607,6 +58756,7 @@ window.__ModuleLoader__.load({
58607
58756
  ];
58608
58757
  function apply(ctx) {
58609
58758
  installLineLocale(ctx.locale);
58759
+ ctx.effect(() => installHostLocaleMirror(ctx.locale), "dsh-chatgpt-subscription: host locale mirror");
58610
58760
  installRussianLocale(ctx);
58611
58761
  ctx.effect(() => ctx.locale.register(NS, dictionaries$2), "dsh-chatgpt-subscription: dictionaries");
58612
58762
  ctx.effect(() => installStyles(), "dsh-chatgpt-subscription: styles");