@eddyskywalker/dsh-chatgpt-subscription 0.54.0 → 0.56.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 (107) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +148 -1268
  3. package/lib/client.js +398 -23
  4. package/lib/client.js.map +1 -1
  5. package/lib/{entry-progress-updates-BEkdyDZU.js → entry-progress-updates-CxQewio9.js} +4 -2
  6. package/lib/index.js +1089 -212
  7. package/lib/plan-mode.js +3 -7
  8. package/lib/progress-updates.js +1 -1
  9. package/lib/tool-result-pruner.js +1 -1
  10. package/lib/types/client/common/host-locale-mirror.d.ts +24 -0
  11. package/lib/types/client/common/host-locale-mirror.d.ts.map +1 -0
  12. package/lib/types/client/hub/HubOverview.d.ts.map +1 -1
  13. package/lib/types/client/hub/providers.d.ts +18 -1
  14. package/lib/types/client/hub/providers.d.ts.map +1 -1
  15. package/lib/types/client/index.d.ts.map +1 -1
  16. package/lib/types/client/locales-ru/hub.d.ts.map +1 -1
  17. package/lib/types/client/locales-ru/index.d.ts +2 -3
  18. package/lib/types/client/locales-ru/index.d.ts.map +1 -1
  19. package/lib/types/client/locales-ru/progress-updates.d.ts.map +1 -1
  20. package/lib/types/client/locales.d.ts +27 -1
  21. package/lib/types/client/locales.d.ts.map +1 -1
  22. package/lib/types/client/minimax-code/commands-contract.d.ts +1 -1
  23. package/lib/types/client/progress-updates/locales.d.ts +5 -2
  24. package/lib/types/client/progress-updates/locales.d.ts.map +1 -1
  25. package/lib/types/client/progress-updates/settings-binding.d.ts +1 -1
  26. package/lib/types/client/progress-updates/settings-binding.d.ts.map +1 -1
  27. package/lib/types/client/progress-updates/settings-section.d.ts.map +1 -1
  28. package/lib/types/client/subagent/SubagentCard.d.ts.map +1 -1
  29. package/lib/types/client/subagent/locales.d.ts +14 -2
  30. package/lib/types/client/subagent/locales.d.ts.map +1 -1
  31. package/lib/types/client/subagent/styles.d.ts +1 -1
  32. package/lib/types/client/subagent/styles.d.ts.map +1 -1
  33. package/lib/types/client/subagent/subagent-card-controller.d.ts +26 -3
  34. package/lib/types/client/subagent/subagent-card-controller.d.ts.map +1 -1
  35. package/lib/types/compat.d.ts +1 -1
  36. package/lib/types/entry-plan-mode.d.ts +3 -7
  37. package/lib/types/entry-plan-mode.d.ts.map +1 -1
  38. package/lib/types/entry-tool-result-pruner.d.ts +1 -1
  39. package/lib/types/host/adapter.d.ts.map +1 -1
  40. package/lib/types/host/agent-preset.d.ts +5 -0
  41. package/lib/types/host/agent-preset.d.ts.map +1 -1
  42. package/lib/types/host/antigravity/adapter.d.ts.map +1 -1
  43. package/lib/types/host/claude/adapter.d.ts.map +1 -1
  44. package/lib/types/host/cline-pass/adapter.d.ts.map +1 -1
  45. package/lib/types/host/codex-account-pool.d.ts.map +1 -1
  46. package/lib/types/host/command-code/adapter.d.ts.map +1 -1
  47. package/lib/types/host/common/account-pool.d.ts.map +1 -1
  48. package/lib/types/host/common/i18n/en.d.ts +9 -0
  49. package/lib/types/host/common/i18n/en.d.ts.map +1 -0
  50. package/lib/types/host/common/i18n/index.d.ts +13 -0
  51. package/lib/types/host/common/i18n/index.d.ts.map +1 -0
  52. package/lib/types/host/common/i18n/provider-name.d.ts +10 -0
  53. package/lib/types/host/common/i18n/provider-name.d.ts.map +1 -0
  54. package/lib/types/host/common/i18n/ru.d.ts +10 -0
  55. package/lib/types/host/common/i18n/ru.d.ts.map +1 -0
  56. package/lib/types/host/common/i18n/runtime.d.ts +54 -0
  57. package/lib/types/host/common/i18n/runtime.d.ts.map +1 -0
  58. package/lib/types/host/common/i18n/t.d.ts +38 -0
  59. package/lib/types/host/common/i18n/t.d.ts.map +1 -0
  60. package/lib/types/host/common/i18n/zh.d.ts +167 -0
  61. package/lib/types/host/common/i18n/zh.d.ts.map +1 -0
  62. package/lib/types/host/common/llm-compat.d.ts +3 -1
  63. package/lib/types/host/common/llm-compat.d.ts.map +1 -1
  64. package/lib/types/host/glm-coding-plan/adapter.d.ts.map +1 -1
  65. package/lib/types/host/glm-coding-plan/client.d.ts.map +1 -1
  66. package/lib/types/host/glm-coding-plan/oauth.d.ts.map +1 -1
  67. package/lib/types/host/glm-coding-plan/routes.d.ts.map +1 -1
  68. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  69. package/lib/types/host/kimi-code/repeat-breaker.d.ts +1 -1
  70. package/lib/types/host/minimax-code/adapter.d.ts.map +1 -1
  71. package/lib/types/host/ollama/adapter.d.ts.map +1 -1
  72. package/lib/types/host/opendesign/adapter.d.ts.map +1 -1
  73. package/lib/types/host/plan-mode-cache-guard.d.ts.map +1 -1
  74. package/lib/types/host/preferences.d.ts.map +1 -1
  75. package/lib/types/host/progress-updates/prompt.d.ts +1 -1
  76. package/lib/types/host/progress-updates/prompt.d.ts.map +1 -1
  77. package/lib/types/host/qoder/account-pool.d.ts.map +1 -1
  78. package/lib/types/host/qoder/adapter.d.ts.map +1 -1
  79. package/lib/types/host/qoder/client.d.ts.map +1 -1
  80. package/lib/types/host/qoder/oauth.d.ts.map +1 -1
  81. package/lib/types/host/qoder/routes.d.ts.map +1 -1
  82. package/lib/types/host/qoder/token-store.d.ts.map +1 -1
  83. package/lib/types/host/routes.d.ts.map +1 -1
  84. package/lib/types/host/step-code/account-pool.d.ts.map +1 -1
  85. package/lib/types/host/step-code/adapter.d.ts.map +1 -1
  86. package/lib/types/host/step-code/oauth.d.ts.map +1 -1
  87. package/lib/types/host/step-code/routes.d.ts.map +1 -1
  88. package/lib/types/host/step-code/token-store.d.ts.map +1 -1
  89. package/lib/types/host/subagent-model-authorization.d.ts +34 -16
  90. package/lib/types/host/subagent-model-authorization.d.ts.map +1 -1
  91. package/lib/types/host/subagent-route-audit.d.ts +6 -1
  92. package/lib/types/host/subagent-route-audit.d.ts.map +1 -1
  93. package/lib/types/host/workbuddy/account-pool.d.ts.map +1 -1
  94. package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
  95. package/lib/types/host/workbuddy/oauth.d.ts.map +1 -1
  96. package/lib/types/index.d.ts +2 -2
  97. package/lib/types/index.d.ts.map +1 -1
  98. package/lib/types/shared/contracts.d.ts +19 -0
  99. package/lib/types/shared/contracts.d.ts.map +1 -1
  100. package/lib/types/shared/i18n-contracts.d.ts +35 -0
  101. package/lib/types/shared/i18n-contracts.d.ts.map +1 -0
  102. package/lib/types/shared/preferences.d.ts +22 -1
  103. package/lib/types/shared/preferences.d.ts.map +1 -1
  104. package/locale/progress-updates/ru.json +6 -0
  105. package/package.json +46 -43
  106. package/presets/dispatch/README.md +6 -5
  107. package/presets/dispatch/agent.cordis.yml +18 -14
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
  })
@@ -56467,6 +56616,22 @@ window.__ModuleLoader__.load({
56467
56616
  function routeKey(route) {
56468
56617
  return `${route.provider}/${route.model}`;
56469
56618
  }
56619
+ /**
56620
+ * 把 `<provider>/<model>` 拆回一条路由。
56621
+ *
56622
+ * provider id 与 model id 都可能含 `/`(例如 `openrouter/anthropic/claude`),
56623
+ * 所以只按**第一个**斜杠拆;这与 `list_subagent_models` 的输出约定一致。
56624
+ * @param key - 目标键。
56625
+ * @returns 路由,或 undefined(不是路由形态)。
56626
+ */
56627
+ function parseRouteKey(key) {
56628
+ const cut = key.indexOf("/");
56629
+ if (cut <= 0 || cut === key.length - 1) return void 0;
56630
+ return {
56631
+ provider: key.slice(0, cut),
56632
+ model: key.slice(cut + 1)
56633
+ };
56634
+ }
56470
56635
  /** 过滤并克隆非空合法路由。 */
56471
56636
  function cloneRoutes(routes) {
56472
56637
  const out = [];
@@ -56498,6 +56663,22 @@ window.__ModuleLoader__.load({
56498
56663
  if (leftKeys.length !== rightKeys.length) return false;
56499
56664
  return leftKeys.every((key, index) => key === rightKeys[index] && sameRouteSet(left[key] ?? [], right[key] ?? []));
56500
56665
  }
56666
+ function normalizeForkOverrides(raw) {
56667
+ const out = {};
56668
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return out;
56669
+ for (const [rawKey, value] of Object.entries(raw)) {
56670
+ const key = rawKey.trim();
56671
+ if (parseRouteKey(key) === void 0 || typeof value !== "boolean") continue;
56672
+ out[key] = value;
56673
+ }
56674
+ return out;
56675
+ }
56676
+ function sameForkOverrides(left, right) {
56677
+ const leftKeys = Object.keys(left).sort();
56678
+ const rightKeys = Object.keys(right).sort();
56679
+ if (leftKeys.length !== rightKeys.length) return false;
56680
+ return leftKeys.every((key, index) => key === rightKeys[index] && left[key] === right[key]);
56681
+ }
56501
56682
  /** 最小快照 store:`useSyncExternalStore` 要求引用在两次变更之间稳定。 */
56502
56683
  function createStore(initial) {
56503
56684
  let snapshot = initial;
@@ -56571,7 +56752,9 @@ window.__ModuleLoader__.load({
56571
56752
  if (typeof parsed !== "object" || parsed === null) return void 0;
56572
56753
  return {
56573
56754
  subagentDefaultModels: Array.isArray(parsed.subagentDefaultModels) ? cloneRoutes(parsed.subagentDefaultModels) : [],
56574
- subagentModelsByMainModel: parsed.subagentModelsByMainModel ?? {}
56755
+ subagentModelsByMainModel: parsed.subagentModelsByMainModel ?? {},
56756
+ subagentDefaultAllowParentFork: parsed.subagentDefaultAllowParentFork === true,
56757
+ subagentAllowParentForkByMainModel: normalizeForkOverrides(parsed.subagentAllowParentForkByMainModel)
56575
56758
  };
56576
56759
  } catch {
56577
56760
  return;
@@ -56584,14 +56767,22 @@ window.__ModuleLoader__.load({
56584
56767
  const mergedOverrides = { ...prev?.subagentModelsByMainModel ?? {} };
56585
56768
  for (const [k, v] of Object.entries(patch.subagentModelsByMainModel ?? {})) if (v === null || !Array.isArray(v) || v.length === 0) delete mergedOverrides[k];
56586
56769
  else mergedOverrides[k] = cloneRoutes(v);
56770
+ const mergedForkOverrides = normalizeForkOverrides(prev?.subagentAllowParentForkByMainModel);
56771
+ for (const [k, v] of Object.entries(patch.subagentAllowParentForkByMainModel ?? {})) {
56772
+ const trimmed = k.trim();
56773
+ if (v === null) delete mergedForkOverrides[trimmed];
56774
+ else if (typeof v === "boolean" && parseRouteKey(trimmed) !== void 0) mergedForkOverrides[trimmed] = v;
56775
+ }
56587
56776
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify({
56588
56777
  subagentDefaultModels: Array.isArray(patch.subagentDefaultModels) ? cloneRoutes(patch.subagentDefaultModels) : prev?.subagentDefaultModels ?? [],
56589
- subagentModelsByMainModel: mergedOverrides
56778
+ subagentModelsByMainModel: mergedOverrides,
56779
+ subagentDefaultAllowParentFork: typeof patch.subagentDefaultAllowParentFork === "boolean" ? patch.subagentDefaultAllowParentFork : prev?.subagentDefaultAllowParentFork === true,
56780
+ subagentAllowParentForkByMainModel: mergedForkOverrides
56590
56781
  }));
56591
56782
  } catch {}
56592
56783
  }
56593
56784
  /**
56594
- * 读本插件偏好里的子代理模型两项。
56785
+ * 读本插件偏好里的子代理模型配置。
56595
56786
  * @returns 偏好切片;读取失败时 undefined(卡片照常可用,只是从空列表起步)。
56596
56787
  */
56597
56788
  async function readSubagentPreferences() {
@@ -56603,10 +56794,14 @@ window.__ModuleLoader__.load({
56603
56794
  if (preferences === void 0 || preferences === null) return local;
56604
56795
  const serverDefaults = Array.isArray(preferences.subagentDefaultModels) ? cloneRoutes(preferences.subagentDefaultModels) : [];
56605
56796
  const serverByMain = preferences.subagentModelsByMainModel ?? {};
56606
- if (serverDefaults.length === 0 && Object.keys(serverByMain).length === 0 && local !== void 0) return local;
56797
+ const serverDefaultFork = preferences.subagentDefaultAllowParentFork === true;
56798
+ const serverForkByMain = normalizeForkOverrides(preferences.subagentAllowParentForkByMainModel);
56799
+ if (serverDefaults.length === 0 && Object.keys(serverByMain).length === 0 && !serverDefaultFork && Object.keys(serverForkByMain).length === 0 && local !== void 0) return local;
56607
56800
  return {
56608
56801
  subagentDefaultModels: serverDefaults,
56609
- subagentModelsByMainModel: serverByMain
56802
+ subagentModelsByMainModel: serverByMain,
56803
+ subagentDefaultAllowParentFork: serverDefaultFork,
56804
+ subagentAllowParentForkByMainModel: serverForkByMain
56610
56805
  };
56611
56806
  } catch {
56612
56807
  return local;
@@ -56702,6 +56897,8 @@ window.__ModuleLoader__.load({
56702
56897
  draftEnabled;
56703
56898
  draftDefault;
56704
56899
  draftOverrides;
56900
+ draftDefaultFork;
56901
+ draftForkOverrides;
56705
56902
  draftRevision;
56706
56903
  activeTarget = GLOBAL_TARGET;
56707
56904
  saving = false;
@@ -56772,12 +56969,18 @@ window.__ModuleLoader__.load({
56772
56969
  toggleModel: (key) => {
56773
56970
  this.toggleModel(key);
56774
56971
  },
56972
+ toggleAllowParentFork: () => {
56973
+ this.toggleAllowParentFork();
56974
+ },
56775
56975
  setActiveTarget: (target) => {
56776
56976
  this.setActiveTarget(target);
56777
56977
  },
56778
56978
  resetActiveTarget: () => {
56779
56979
  this.resetActiveTarget();
56780
56980
  },
56981
+ resetActiveTargetFork: () => {
56982
+ this.resetActiveTargetFork();
56983
+ },
56781
56984
  retryCatalog: () => {
56782
56985
  this.loadCatalogOnce();
56783
56986
  },
@@ -56851,6 +57054,12 @@ window.__ModuleLoader__.load({
56851
57054
  }
56852
57055
  return out;
56853
57056
  }
57057
+ currentDefaultFork() {
57058
+ return this.preferences?.subagentDefaultAllowParentFork === true;
57059
+ }
57060
+ currentForkOverrides() {
57061
+ return normalizeForkOverrides(this.preferences?.subagentAllowParentForkByMainModel);
57062
+ }
56854
57063
  enabled() {
56855
57064
  return this.draftEnabled ?? this.currentEnabled();
56856
57065
  }
@@ -56863,6 +57072,17 @@ window.__ModuleLoader__.load({
56863
57072
  for (const [key, value] of Object.entries(source)) out[key] = cloneRoutes(value);
56864
57073
  return out;
56865
57074
  }
57075
+ defaultAllowParentFork() {
57076
+ return this.draftDefaultFork ?? this.currentDefaultFork();
57077
+ }
57078
+ forkOverrides() {
57079
+ return { ...this.draftForkOverrides ?? this.currentForkOverrides() };
57080
+ }
57081
+ activeAllowParentFork() {
57082
+ if (this.activeTarget === "default") return this.defaultAllowParentFork();
57083
+ const own = this.forkOverrides()[this.activeTarget];
57084
+ return typeof own === "boolean" ? own : this.defaultAllowParentFork();
57085
+ }
56866
57086
  /** 当前目标生效的列表(专属列表优先,否则回落到全局默认)。 */
56867
57087
  activeRoutes() {
56868
57088
  if (this.activeTarget === "default") return this.defaultRoutes();
@@ -56874,6 +57094,8 @@ window.__ModuleLoader__.load({
56874
57094
  this.draftEnabled = this.currentEnabled();
56875
57095
  this.draftDefault = this.currentDefault();
56876
57096
  this.draftOverrides = this.currentOverrides();
57097
+ this.draftDefaultFork = this.currentDefaultFork();
57098
+ this.draftForkOverrides = this.currentForkOverrides();
56877
57099
  this.draftRevision = this.modelSelection.getSnapshot().revision;
56878
57100
  }
56879
57101
  clearDraft() {
@@ -56884,6 +57106,8 @@ window.__ModuleLoader__.load({
56884
57106
  this.draftEnabled = void 0;
56885
57107
  this.draftDefault = void 0;
56886
57108
  this.draftOverrides = void 0;
57109
+ this.draftDefaultFork = void 0;
57110
+ this.draftForkOverrides = void 0;
56887
57111
  this.draftRevision = void 0;
56888
57112
  this.failed = false;
56889
57113
  }
@@ -56960,13 +57184,41 @@ window.__ModuleLoader__.load({
56960
57184
  this.activeTarget = target === "" ? GLOBAL_TARGET : target;
56961
57185
  this.publish();
56962
57186
  }
56963
- /** 让当前目标恢复「跟随全局默认」:删掉它的专属列表。 */
57187
+ /** 切换当前目标的同源分叉(`subagent_fork`)开关。 */
57188
+ toggleAllowParentFork() {
57189
+ if (this.saving || !this.enabled()) return;
57190
+ if (this.modelSelection.getSnapshot().status !== "ready") return;
57191
+ this.ensureDraft();
57192
+ if (this.activeTarget === "default") this.draftDefaultFork = !this.defaultAllowParentFork();
57193
+ else {
57194
+ const forkOverrides = this.draftForkOverrides ?? this.currentForkOverrides();
57195
+ const current = forkOverrides[this.activeTarget] ?? this.defaultAllowParentFork();
57196
+ forkOverrides[this.activeTarget] = !current;
57197
+ this.draftForkOverrides = forkOverrides;
57198
+ }
57199
+ this.failed = false;
57200
+ this.publish();
57201
+ }
57202
+ /** 让当前主代理的同源分叉策略单独恢复「跟随全局默认」。 */
57203
+ resetActiveTargetFork() {
57204
+ if (this.saving || this.activeTarget === "default") return;
57205
+ this.ensureDraft();
57206
+ const forkOverrides = this.draftForkOverrides ?? this.currentForkOverrides();
57207
+ delete forkOverrides[this.activeTarget];
57208
+ this.draftForkOverrides = forkOverrides;
57209
+ this.failed = false;
57210
+ this.publish();
57211
+ }
57212
+ /** 让当前目标恢复「跟随全局默认」:删掉它的专属列表与专属同源分叉覆盖。 */
56964
57213
  resetActiveTarget() {
56965
57214
  if (this.saving || this.activeTarget === "default") return;
56966
57215
  this.ensureDraft();
56967
57216
  const overrides = this.draftOverrides ?? this.currentOverrides();
56968
57217
  delete overrides[this.activeTarget];
56969
57218
  this.draftOverrides = overrides;
57219
+ const forkOverrides = this.draftForkOverrides ?? this.currentForkOverrides();
57220
+ delete forkOverrides[this.activeTarget];
57221
+ this.draftForkOverrides = forkOverrides;
56970
57222
  this.failed = false;
56971
57223
  this.publish();
56972
57224
  }
@@ -57017,16 +57269,18 @@ window.__ModuleLoader__.load({
57017
57269
  /** 主代理模型下拉的分组(目录分组 + 已保存但不可用的孤儿)。 */
57018
57270
  mainModelGroups() {
57019
57271
  const overrides = this.overrides();
57272
+ const forkOverrides = this.forkOverrides();
57020
57273
  const groups = [];
57021
57274
  for (const group of this.catalogGroups) {
57022
57275
  if (!group.provider || group.provider === "undefined") continue;
57023
57276
  const models = group.models.filter((model) => Boolean(model.id) && model.id !== "undefined").map((model) => {
57024
57277
  const key = `${group.provider}/${model.id}`;
57278
+ const overridden = overrides[key] !== void 0 || forkOverrides[key] !== void 0;
57025
57279
  return {
57026
57280
  key,
57027
57281
  model: model.id,
57028
57282
  modelName: model.name,
57029
- overridden: overrides[key] !== void 0
57283
+ overridden
57030
57284
  };
57031
57285
  });
57032
57286
  if (models.length > 0) groups.push({
@@ -57041,7 +57295,7 @@ window.__ModuleLoader__.load({
57041
57295
  orphanMainModels() {
57042
57296
  const known = /* @__PURE__ */ new Set();
57043
57297
  for (const group of this.catalogGroups) for (const model of group.models) known.add(`${group.provider}/${model.id}`);
57044
- return Object.keys(this.overrides()).filter((key) => !known.has(key));
57298
+ return [.../* @__PURE__ */ new Set([...Object.keys(this.overrides()), ...Object.keys(this.forkOverrides())])].filter((key) => !known.has(key));
57045
57299
  }
57046
57300
  /**
57047
57301
  * 一次保存三份存储。
@@ -57052,6 +57306,8 @@ window.__ModuleLoader__.load({
57052
57306
  const desiredEnabled = this.enabled();
57053
57307
  const desiredDefault = this.defaultRoutes();
57054
57308
  const desiredOverrides = this.overrides();
57309
+ const desiredDefaultFork = this.defaultAllowParentFork();
57310
+ const desiredForkOverrides = this.forkOverrides();
57055
57311
  const generation = this.saveGeneration;
57056
57312
  this.saving = true;
57057
57313
  this.failed = false;
@@ -57063,16 +57319,28 @@ window.__ModuleLoader__.load({
57063
57319
  const list = desiredOverrides[key];
57064
57320
  patch[key] = list !== void 0 && list.length > 0 ? cloneRoutes(list) : null;
57065
57321
  }
57322
+ const initialFork = this.currentForkOverrides();
57323
+ const forkPatch = {};
57324
+ for (const key of /* @__PURE__ */ new Set([...Object.keys(initialFork), ...Object.keys(desiredForkOverrides)])) {
57325
+ const flag = desiredForkOverrides[key];
57326
+ forkPatch[key] = typeof flag === "boolean" ? flag : null;
57327
+ }
57066
57328
  await this.savePreferences({
57067
57329
  subagentDefaultModels: cloneRoutes(desiredDefault),
57068
- subagentModelsByMainModel: patch
57330
+ subagentModelsByMainModel: patch,
57331
+ subagentDefaultAllowParentFork: desiredDefaultFork,
57332
+ subagentAllowParentForkByMainModel: forkPatch
57069
57333
  });
57070
57334
  if (this.disposed || generation !== this.saveGeneration) return;
57071
57335
  const nextOverrides = {};
57072
57336
  for (const [k, v] of Object.entries(desiredOverrides)) if (v.length > 0) nextOverrides[k] = cloneRoutes(v);
57337
+ const nextForkOverrides = {};
57338
+ for (const [k, v] of Object.entries(desiredForkOverrides)) if (typeof v === "boolean") nextForkOverrides[k] = v;
57073
57339
  this.preferences = {
57074
57340
  subagentDefaultModels: cloneRoutes(desiredDefault),
57075
- subagentModelsByMainModel: nextOverrides
57341
+ subagentModelsByMainModel: nextOverrides,
57342
+ subagentDefaultAllowParentFork: desiredDefaultFork,
57343
+ subagentAllowParentForkByMainModel: nextForkOverrides
57076
57344
  };
57077
57345
  this.preferencesStatus = "ready";
57078
57346
  const union = /* @__PURE__ */ new Map();
@@ -57179,13 +57447,17 @@ window.__ModuleLoader__.load({
57179
57447
  const enabled = this.enabled();
57180
57448
  const desiredDefault = this.defaultRoutes();
57181
57449
  const desiredOverrides = this.overrides();
57450
+ const desiredDefaultFork = this.defaultAllowParentFork();
57451
+ const desiredForkOverrides = this.forkOverrides();
57182
57452
  const currentOverrides = this.currentOverrides();
57183
57453
  const currentDefault = this.currentDefault();
57454
+ const currentDefaultFork = this.currentDefaultFork();
57455
+ const currentForkOverrides = this.currentForkOverrides();
57184
57456
  const union = /* @__PURE__ */ new Map();
57185
57457
  for (const route of desiredDefault) union.set(routeKey(route), route);
57186
57458
  for (const list of Object.values(desiredOverrides)) for (const route of list) union.set(routeKey(route), route);
57187
57459
  const hostAllowed = cloneRoutes(modelSnapshot.value?.allowedModels ?? []);
57188
- const modelsDirty = this.currentEnabled() !== enabled || !sameRouteSet(currentDefault, desiredDefault) || !sameOverrides(currentOverrides, desiredOverrides) || this.draftDefault !== void 0 && !sameRouteSet(hostAllowed, [...union.values()]);
57460
+ const modelsDirty = this.currentEnabled() !== enabled || !sameRouteSet(currentDefault, desiredDefault) || !sameOverrides(currentOverrides, desiredOverrides) || currentDefaultFork !== desiredDefaultFork || !sameForkOverrides(currentForkOverrides, desiredForkOverrides) || this.draftDefault !== void 0 && !sameRouteSet(hostAllowed, [...union.values()]);
57189
57461
  const depthPersistedOverridden = userHas(limitsSnapshot.user, "maxDepth");
57190
57462
  const activePersistedOverridden = userHas(limitsSnapshot.user, "maxActiveSubagents");
57191
57463
  const depthDirty = this.draftDepthCleared ? depthPersistedOverridden : this.draftDepth !== void 0 && maxDepth.value !== String(readNumber(limitsSnapshot.value, "maxDepth", 1));
@@ -57194,6 +57466,7 @@ window.__ModuleLoader__.load({
57194
57466
  const emptyOverride = Object.values(desiredOverrides).some((list) => list.length === 0);
57195
57467
  const invalid = maxDepth.invalid || maxActive.invalid || enabled && (desiredDefault.length === 0 || emptyOverride);
57196
57468
  const activeOverridden = this.activeTarget !== "default" && desiredOverrides[this.activeTarget] !== void 0;
57469
+ const activeForkOverridden = this.activeTarget !== "default" && desiredForkOverrides[this.activeTarget] !== void 0;
57197
57470
  return {
57198
57471
  available: limitsAvailable || modelsAvailable,
57199
57472
  writable: (limitsAvailable ? limitsSnapshot.writable : true) && (modelsAvailable ? modelSnapshot.writable : true),
@@ -57214,6 +57487,10 @@ window.__ModuleLoader__.load({
57214
57487
  candidates: this.candidates(),
57215
57488
  activeTargetOverridden: activeOverridden,
57216
57489
  activeTargetCount: this.activeRoutes().length,
57490
+ defaultAllowParentFork: desiredDefaultFork,
57491
+ forkOverridesByMainModel: desiredForkOverrides,
57492
+ activeTargetAllowParentFork: this.activeAllowParentFork(),
57493
+ activeTargetForkOverridden: activeForkOverridden,
57217
57494
  preferencesStatus: this.preferencesStatus
57218
57495
  };
57219
57496
  }
@@ -57414,7 +57691,8 @@ window.__ModuleLoader__.load({
57414
57691
  return key;
57415
57692
  };
57416
57693
  const activeModelKey = state.activeTarget;
57417
- const overrideKeys = Object.keys(state.overridesByMainModel);
57694
+ const overrideKeys = [.../* @__PURE__ */ new Set([...Object.keys(state.overridesByMainModel), ...Object.keys(state.forkOverridesByMainModel)])];
57695
+ const activeAnyOverridden = state.activeTargetOverridden || state.activeTargetForkOverridden;
57418
57696
  const limitsHeadingId = headingId + "-limits";
57419
57697
  const modelsHeadingId = headingId + "-models";
57420
57698
  const mainModelId = headingId + "-main-model";
@@ -57593,7 +57871,7 @@ window.__ModuleLoader__.load({
57593
57871
  onClick: () => {
57594
57872
  props.setActiveTarget(key);
57595
57873
  },
57596
- children: mainModelName(key) + " (" + String(state.overridesByMainModel[key]?.length ?? 0) + ")"
57874
+ children: mainModelName(key) + " (" + String(state.overridesByMainModel[key]?.length ?? state.defaultCount) + ")"
57597
57875
  }, key))]
57598
57876
  }),
57599
57877
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -57605,10 +57883,13 @@ window.__ModuleLoader__.load({
57605
57883
  }) : state.activeTargetOverridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
57606
57884
  className: "dsh-subagent-hint",
57607
57885
  children: withCount(t("subagentTargetOverrideStatus"), state.activeTargetCount)
57886
+ }) : state.activeTargetForkOverridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
57887
+ className: "dsh-subagent-hint",
57888
+ children: t("subagentTargetForkOnlyOverrideStatus")
57608
57889
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
57609
57890
  className: "dsh-subagent-hint",
57610
57891
  children: t("subagentTargetFollowGlobalStatus")
57611
- }), activeModelKey !== "default" && state.activeTargetOverridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
57892
+ }), activeModelKey !== "default" && activeAnyOverridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
57612
57893
  type: "button",
57613
57894
  className: "dsh-subagent-reset",
57614
57895
  "data-dsh-part": "subagent-reset-to-global",
@@ -57621,6 +57902,54 @@ window.__ModuleLoader__.load({
57621
57902
  })
57622
57903
  ]
57623
57904
  }),
57905
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
57906
+ className: "dsh-subagent-fork-card",
57907
+ "data-dsh-part": "subagent-fork-card",
57908
+ children: [
57909
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", { children: t("subagentForkTitle") }),
57910
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
57911
+ className: "dsh-subagent-fork-head",
57912
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
57913
+ className: "dsh-subagent-fork-title-group",
57914
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
57915
+ className: "dsh-subagent-fork-label",
57916
+ children: t("subagentForkToggle")
57917
+ }), activeModelKey !== "default" && state.activeTargetForkOverridden ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
57918
+ className: "dsh-subagent-badges",
57919
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
57920
+ className: "dsh-subagent-override-tag",
57921
+ children: t("overridden")
57922
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
57923
+ type: "button",
57924
+ className: "dsh-subagent-reset-link",
57925
+ "data-dsh-part": "subagent-fork-reset",
57926
+ disabled,
57927
+ onClick: () => {
57928
+ props.resetActiveTargetFork();
57929
+ },
57930
+ children: t("reset")
57931
+ })]
57932
+ }) : null]
57933
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
57934
+ type: "button",
57935
+ role: "switch",
57936
+ "aria-checked": state.activeTargetAllowParentFork,
57937
+ "aria-label": t("subagentForkToggle"),
57938
+ className: "dsh-subagent-switch",
57939
+ "data-dsh-part": "subagent-fork-switch",
57940
+ disabled,
57941
+ onClick: () => {
57942
+ props.toggleAllowParentFork();
57943
+ },
57944
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "dsh-subagent-switch-thumb" })
57945
+ })]
57946
+ }),
57947
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
57948
+ className: "dsh-subagent-hint",
57949
+ children: t("subagentForkHint")
57950
+ })
57951
+ ]
57952
+ }),
57624
57953
  state.catalogStatus === "loading" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
57625
57954
  className: "dsh-subagent-notice",
57626
57955
  role: "status",
@@ -57785,11 +58114,15 @@ window.__ModuleLoader__.load({
57785
58114
  subagentChipGlobal: "全局默认 ({count})",
57786
58115
  subagentTargetGlobalHint: "正在编辑全局默认子代理模型列表;未单独配置专属列表的主代理将使用此列表。",
57787
58116
  subagentTargetOverrideStatus: "已为该主代理单独配置 {count} 个子代理模型",
58117
+ subagentTargetForkOnlyOverrideStatus: "子代理模型列表跟随全局默认;已为该主代理单独配置同源分叉策略",
57788
58118
  subagentTargetFollowGlobalStatus: "当前跟随全局默认列表(勾选或取消下方模型即可为该主代理创建专属列表)",
57789
58119
  subagentResetToGlobal: "恢复跟随全局默认",
57790
58120
  subagentOverrideBadge: "(已覆盖)",
57791
58121
  subagentPreferencesLoadFailed: "无法读取已保存的子代理模型偏好;保存时将以当前界面为准。",
57792
- subagentModelPerTargetRequired: "保存前请至少选择一个模型(或点击「恢复跟随全局默认」)。"
58122
+ subagentModelPerTargetRequired: "保存前请至少选择一个模型(或点击「恢复跟随全局默认」)。",
58123
+ subagentForkTitle: "同源分叉",
58124
+ subagentForkToggle: "允许同源分叉(subagent_fork 继承当前主代理模型)",
58125
+ subagentForkHint: "开启后,subagent_fork 可直接继承当前主代理模型以复用会话上下文与前缀缓存,无需将该主模型加入下方冷启动可选列表;不影响冷启动 subagent 与团队派生。"
57793
58126
  };
57794
58127
  /** 英文对照,键集与中文完全一致。 */
57795
58128
  const en = {
@@ -57834,11 +58167,15 @@ window.__ModuleLoader__.load({
57834
58167
  subagentChipGlobal: "Global default ({count})",
57835
58168
  subagentTargetGlobalHint: "Editing the global default subagent model list; main agents without their own list use it.",
57836
58169
  subagentTargetOverrideStatus: "This main agent has {count} dedicated subagent models",
58170
+ subagentTargetForkOnlyOverrideStatus: "Subagent models follow the global default; same-model fork is overridden for this main agent",
57837
58171
  subagentTargetFollowGlobalStatus: "Currently following the global default list (tick or untick a model below to create a dedicated list for this main agent)",
57838
58172
  subagentResetToGlobal: "Follow the global default again",
57839
58173
  subagentOverrideBadge: " (overridden)",
57840
58174
  subagentPreferencesLoadFailed: "Saved subagent model preferences could not be read; saving will use what this page shows.",
57841
- subagentModelPerTargetRequired: "Select at least one model before saving (or choose \"Follow the global default again\")."
58175
+ subagentModelPerTargetRequired: "Select at least one model before saving (or choose \"Follow the global default again\").",
58176
+ subagentForkTitle: "Same-model fork",
58177
+ subagentForkToggle: "Allow same-model fork (subagent_fork inherits the main agent model)",
58178
+ subagentForkHint: "When enabled, subagent_fork may inherit the main agent model to reuse conversation context and prefix cache without adding that model to the cold-spawn list below; cold-spawn subagent and teammate creation remain governed by the list."
57842
58179
  };
57843
58180
  /** 与其余线路同形的字典包(四个内置语言 id 都指向那两份)。 */
57844
58181
  const dictionaries = {
@@ -58463,12 +58800,49 @@ window.__ModuleLoader__.load({
58463
58800
  border-radius: var(--dsw-radius-lg, 10px);
58464
58801
  }
58465
58802
 
58466
- .dsh-subagent-models > legend {
58803
+ .dsh-subagent-models > legend,
58804
+ .dsh-subagent-fork-card > legend {
58467
58805
  padding: 0 4px;
58468
58806
  font-size: 12px;
58469
58807
  color: var(--dsw-alias-label-secondary);
58470
58808
  }
58471
58809
 
58810
+ .dsh-subagent-fork-card {
58811
+ display: grid;
58812
+ align-content: start;
58813
+ gap: 4px;
58814
+ min-width: 0;
58815
+ margin: 0;
58816
+ padding: 10px;
58817
+ border: 0.5px solid var(--dsw-alias-border-l4);
58818
+ border-radius: var(--dsw-radius-lg, 10px);
58819
+ background: transparent;
58820
+ }
58821
+
58822
+ .dsh-subagent-fork-head {
58823
+ display: flex;
58824
+ align-items: center;
58825
+ justify-content: space-between;
58826
+ gap: 16px;
58827
+ min-width: 0;
58828
+ }
58829
+
58830
+ .dsh-subagent-fork-title-group {
58831
+ display: flex;
58832
+ flex-wrap: wrap;
58833
+ align-items: center;
58834
+ gap: 8px;
58835
+ flex: 1;
58836
+ min-width: 0;
58837
+ }
58838
+
58839
+ .dsh-subagent-fork-label {
58840
+ font-size: 13px;
58841
+ font-weight: 500;
58842
+ line-height: 1.5;
58843
+ color: var(--dsw-alias-label-primary);
58844
+ }
58845
+
58472
58846
  .dsh-subagent-group {
58473
58847
  display: grid;
58474
58848
  gap: 6px;
@@ -58607,6 +58981,7 @@ window.__ModuleLoader__.load({
58607
58981
  ];
58608
58982
  function apply(ctx) {
58609
58983
  installLineLocale(ctx.locale);
58984
+ ctx.effect(() => installHostLocaleMirror(ctx.locale), "dsh-chatgpt-subscription: host locale mirror");
58610
58985
  installRussianLocale(ctx);
58611
58986
  ctx.effect(() => ctx.locale.register(NS, dictionaries$2), "dsh-chatgpt-subscription: dictionaries");
58612
58987
  ctx.effect(() => installStyles(), "dsh-chatgpt-subscription: styles");