@eddyskywalker/dsh-chatgpt-subscription 0.1.27 → 0.1.29

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 (46) hide show
  1. package/CHANGELOG.md +26 -25
  2. package/LICENSE +21 -21
  3. package/cordis.patch.yml +6 -6
  4. package/lib/client.js +385 -453
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +342 -281
  7. package/lib/types/client/CodexSubscriptionSection.d.ts +2 -2
  8. package/lib/types/client/CodexSubscriptionSection.d.ts.map +1 -1
  9. package/lib/types/client/api.d.ts +1 -2
  10. package/lib/types/client/api.d.ts.map +1 -1
  11. package/lib/types/client/index.d.ts.map +1 -1
  12. package/lib/types/client/locales.d.ts +53 -59
  13. package/lib/types/client/locales.d.ts.map +1 -1
  14. package/lib/types/client/quota.d.ts.map +1 -1
  15. package/lib/types/client/styles.d.ts.map +1 -1
  16. package/lib/types/compat.d.ts +1 -0
  17. package/lib/types/compat.d.ts.map +1 -1
  18. package/lib/types/host/codex-fetch.d.ts +10 -0
  19. package/lib/types/host/codex-fetch.d.ts.map +1 -0
  20. package/lib/types/host/model-catalog.d.ts.map +1 -1
  21. package/lib/types/host/preferences.d.ts.map +1 -1
  22. package/lib/types/host/proxy-manager.d.ts +29 -0
  23. package/lib/types/host/proxy-manager.d.ts.map +1 -0
  24. package/lib/types/host/responses-client.d.ts +2 -0
  25. package/lib/types/host/responses-client.d.ts.map +1 -1
  26. package/lib/types/host/responses-mapper.d.ts +2 -1
  27. package/lib/types/host/responses-mapper.d.ts.map +1 -1
  28. package/lib/types/host/routes.d.ts +2 -1
  29. package/lib/types/host/routes.d.ts.map +1 -1
  30. package/lib/types/host/search-provider-switcher.d.ts +2 -1
  31. package/lib/types/host/search-provider-switcher.d.ts.map +1 -1
  32. package/lib/types/index.d.ts +2 -0
  33. package/lib/types/index.d.ts.map +1 -1
  34. package/lib/types/shared/contracts.d.ts +13 -38
  35. package/lib/types/shared/contracts.d.ts.map +1 -1
  36. package/lib/types/shared/preferences.d.ts +2 -1
  37. package/lib/types/shared/preferences.d.ts.map +1 -1
  38. package/package.json +10 -11
  39. package/lib/types/client/SubagentSettingsSection.d.ts +0 -9
  40. package/lib/types/client/SubagentSettingsSection.d.ts.map +0 -1
  41. package/lib/types/host/subagent-context-adapter.d.ts +0 -24
  42. package/lib/types/host/subagent-context-adapter.d.ts.map +0 -1
  43. package/lib/types/host/subagent-model-preference.d.ts +0 -5
  44. package/lib/types/host/subagent-model-preference.d.ts.map +0 -1
  45. package/lib/types/host/subagent-policy.d.ts +0 -17
  46. package/lib/types/host/subagent-policy.d.ts.map +0 -1
package/lib/client.js CHANGED
@@ -17,7 +17,9 @@ window.__ModuleLoader__.load({
17
17
  if (bucket === void 0) return null;
18
18
  const windows = quotaWindows(bucket);
19
19
  if (windows.length === 0) return null;
20
- const window = windows.reduce((tightest, candidate) => candidate.usedPercent > tightest.usedPercent ? candidate : tightest, windows[0]);
20
+ const window = [...windows].sort((a, b) => {
21
+ return (a.windowDurationMins ?? Infinity) - (b.windowDurationMins ?? Infinity);
22
+ })[0];
21
23
  return {
22
24
  bucket,
23
25
  window,
@@ -260,9 +262,6 @@ window.__ModuleLoader__.load({
260
262
  status() {
261
263
  return request(`${ROUTE_PREFIX}/status`);
262
264
  }
263
- models() {
264
- return request(`${ROUTE_PREFIX}/models`);
265
- }
266
265
  startLogin() {
267
266
  return post(`${ROUTE_PREFIX}/login/start`, {});
268
267
  }
@@ -328,6 +327,8 @@ window.__ModuleLoader__.load({
328
327
  const [resetCreditNotice, setResetCreditNotice] = (0, react.useState)(null);
329
328
  const [connection, setConnection] = (0, react.useState)(null);
330
329
  const [contextDrafts, setContextDrafts] = (0, react.useState)({});
330
+ const [subagentContextDraft, setSubagentContextDraft] = (0, react.useState)(null);
331
+ const [customProxyDraft, setCustomProxyDraft] = (0, react.useState)(null);
331
332
  const load = (0, react.useCallback)(async (quiet = false) => {
332
333
  if (!quiet) setError(null);
333
334
  try {
@@ -335,7 +336,7 @@ window.__ModuleLoader__.load({
335
336
  setStatus(next);
336
337
  if (next.error !== void 0) setError(next.error.message);
337
338
  } catch (cause) {
338
- if (!quiet) setError(messageOf$1(cause));
339
+ if (!quiet) setError(messageOf(cause));
339
340
  }
340
341
  }, []);
341
342
  (0, react.useEffect)(() => {
@@ -395,7 +396,7 @@ window.__ModuleLoader__.load({
395
396
  } catch (cause) {
396
397
  popup?.close();
397
398
  setBusy(null);
398
- setError(messageOf$1(cause));
399
+ setError(messageOf(cause));
399
400
  }
400
401
  };
401
402
  const cancelLogin = async () => {
@@ -409,7 +410,7 @@ window.__ModuleLoader__.load({
409
410
  setAuthUrl(null);
410
411
  await load();
411
412
  } catch (cause) {
412
- setError(messageOf$1(cause));
413
+ setError(messageOf(cause));
413
414
  } finally {
414
415
  setBusy(null);
415
416
  }
@@ -449,6 +450,16 @@ window.__ModuleLoader__.load({
449
450
  preferences
450
451
  });
451
452
  });
453
+ const selectSearchProvider = (provider) => {
454
+ setStatus((current) => current ? {
455
+ ...current,
456
+ preferences: {
457
+ ...current.preferences,
458
+ searchProvider: provider
459
+ }
460
+ } : current);
461
+ updatePreferences({ searchProvider: provider });
462
+ };
452
463
  const toggleVisibleModel = async (modelId, checked) => {
453
464
  const current = status?.preferences.visibleModelIds ?? [...DEFAULT_VISIBLE_CODEX_MODEL_IDS];
454
465
  const visibleModelIds = checked ? [...current, modelId] : current.filter((id) => id !== modelId);
@@ -457,7 +468,7 @@ window.__ModuleLoader__.load({
457
468
  };
458
469
  const updateContextWindow = async (model) => {
459
470
  const current = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow;
460
- const parsed = parseCapacity$1(contextDrafts[model] ?? String(current));
471
+ const parsed = parseCapacity(contextDrafts[model] ?? String(current));
461
472
  if (parsed === null) {
462
473
  setError(t("contextWindowInvalid"));
463
474
  return;
@@ -468,6 +479,26 @@ window.__ModuleLoader__.load({
468
479
  [model]: String(parsed)
469
480
  }));
470
481
  };
482
+ const updateSubagentContextWindow = async () => {
483
+ const draft = subagentContextDraft?.trim();
484
+ if (draft === void 0 || draft === "") {
485
+ await updatePreferences({ subagentContextWindow: null });
486
+ setSubagentContextDraft(null);
487
+ return;
488
+ }
489
+ const parsed = parsePositiveCapacity(draft);
490
+ if (parsed === null) {
491
+ setError(t("contextWindowInvalid"));
492
+ return;
493
+ }
494
+ await updatePreferences({ subagentContextWindow: parsed });
495
+ setSubagentContextDraft(null);
496
+ };
497
+ const updateCustomProxyUrl = async () => {
498
+ const draft = customProxyDraft?.trim();
499
+ await updatePreferences({ customProxyUrl: draft ? draft : null });
500
+ setCustomProxyDraft(null);
501
+ };
471
502
  const logout = async () => run("logout", async () => {
472
503
  await apiRef.current.logout();
473
504
  eventSourceRef.current?.close();
@@ -483,13 +514,17 @@ window.__ModuleLoader__.load({
483
514
  try {
484
515
  await task();
485
516
  } catch (cause) {
486
- setError(messageOf$1(cause));
517
+ setError(messageOf(cause));
487
518
  } finally {
488
519
  setBusy(null);
489
520
  }
490
521
  };
491
522
  const account = status?.account;
492
- const visibleModelIds = status?.preferences.visibleModelIds ?? DEFAULT_VISIBLE_CODEX_MODEL_IDS;
523
+ const preferences = status?.preferences;
524
+ const quota = status?.quota;
525
+ const storage = status?.storage;
526
+ const login = status?.login;
527
+ const visibleModelIds = preferences?.visibleModelIds ?? DEFAULT_VISIBLE_CODEX_MODEL_IDS;
493
528
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
494
529
  className: "dsh-codex-page",
495
530
  "aria-labelledby": "dsh-codex-title",
@@ -535,13 +570,13 @@ window.__ModuleLoader__.load({
535
570
  ] }) : null,
536
571
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoRow, {
537
572
  label: t("storage"),
538
- value: storageLabel(status?.storage, t)
573
+ value: storageLabel(storage, t)
539
574
  }),
540
575
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
541
576
  className: "dsh-codex-notice",
542
- children: storageNotice(status?.storage, t)
577
+ children: storageNotice(storage, t)
543
578
  }),
544
- status?.login.active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
579
+ login?.active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
545
580
  className: "dsh-codex-muted",
546
581
  role: "status",
547
582
  children: t("pending")
@@ -559,13 +594,13 @@ window.__ModuleLoader__.load({
559
594
  }) : null,
560
595
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
561
596
  className: "dsh-codex-actions",
562
- children: [status?.login.active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
597
+ children: [login?.active ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
563
598
  disabled: busy !== null,
564
599
  onClick: cancelLogin,
565
600
  children: t("cancel")
566
601
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
567
602
  primary: true,
568
- disabled: busy !== null || status?.storage.available === false,
603
+ disabled: busy !== null || storage?.available === false,
569
604
  onClick: startLogin,
570
605
  children: status?.authenticated ? t("signInAgain") : t("signIn")
571
606
  }), status?.authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
@@ -626,6 +661,105 @@ window.__ModuleLoader__.load({
626
661
  })
627
662
  ]
628
663
  }),
664
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
665
+ title: t("proxySettings"),
666
+ children: [
667
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
668
+ className: "dsh-codex-pref-row",
669
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("proxyMode") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
670
+ className: "dsh-codex-muted",
671
+ children: t("proxyModeHint")
672
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
673
+ className: "dsh-codex-select",
674
+ "aria-label": t("proxyMode"),
675
+ value: preferences?.proxyMode ?? "auto",
676
+ disabled: busy !== null,
677
+ onChange: (event) => {
678
+ const mode = event.currentTarget.value;
679
+ setStatus((current) => current ? {
680
+ ...current,
681
+ preferences: {
682
+ ...current.preferences,
683
+ proxyMode: mode
684
+ }
685
+ } : current);
686
+ updatePreferences({ proxyMode: mode });
687
+ },
688
+ children: [
689
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
690
+ value: "auto",
691
+ children: t("proxyModeAuto")
692
+ }),
693
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
694
+ value: "custom",
695
+ children: t("proxyModeCustom")
696
+ }),
697
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
698
+ value: "direct",
699
+ children: t("proxyModeDirect")
700
+ })
701
+ ]
702
+ })]
703
+ }),
704
+ (preferences?.proxyMode ?? "auto") === "auto" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
705
+ className: "dsh-codex-proxy-status",
706
+ children: status?.detectedProxy ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
707
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [t("proxyDetected"), ":"] }),
708
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
709
+ className: "dsh-codex-proxy-tag",
710
+ children: status.detectedProxy
711
+ }),
712
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
713
+ className: "dsh-codex-success",
714
+ children: t("proxyDetectedEffective")
715
+ })
716
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
717
+ className: "dsh-codex-muted",
718
+ children: t("proxyNoneDetected")
719
+ })
720
+ }) : null,
721
+ preferences?.proxyMode === "direct" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
722
+ className: "dsh-codex-muted",
723
+ style: { margin: "8px 0 0" },
724
+ children: t("proxyDirectHint")
725
+ }) : null,
726
+ preferences?.proxyMode === "custom" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
727
+ className: "dsh-codex-context-settings",
728
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("customProxyUrl") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
729
+ className: "dsh-codex-muted",
730
+ children: t("customProxyUrlHint")
731
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
732
+ className: "dsh-codex-context-row",
733
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
734
+ className: "dsh-codex-proxy-control",
735
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
736
+ id: "dsh-codex-custom-proxy",
737
+ type: "text",
738
+ placeholder: t("customProxyUrlPlaceholder"),
739
+ value: customProxyDraft ?? preferences?.customProxyUrl ?? "",
740
+ disabled: busy !== null,
741
+ "aria-label": t("customProxyUrl"),
742
+ onChange: (event) => {
743
+ setCustomProxyDraft(event.currentTarget.value);
744
+ },
745
+ onKeyDown: (event) => {
746
+ if (event.key !== "Enter") return;
747
+ event.preventDefault();
748
+ updateCustomProxyUrl();
749
+ }
750
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
751
+ className: "dsh-codex-context-save",
752
+ type: "button",
753
+ "aria-label": t("saveProxyUrl"),
754
+ disabled: busy !== null || customProxyDraft === null,
755
+ onClick: () => void updateCustomProxyUrl(),
756
+ children: t("save")
757
+ })]
758
+ })
759
+ })]
760
+ }) : null
761
+ ]
762
+ }),
629
763
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
630
764
  title: t("enhancements"),
631
765
  children: [
@@ -636,21 +770,23 @@ window.__ModuleLoader__.load({
636
770
  children: t("searchProviderHint")
637
771
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
638
772
  className: "dsh-codex-segments",
639
- role: "radiogroup",
773
+ role: "group",
640
774
  "aria-label": t("searchProvider"),
641
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
642
- type: "radio",
643
- name: "dsh-codex-search-provider",
644
- checked: status?.preferences.searchProvider === "dsh",
775
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
776
+ type: "button",
777
+ className: preferences?.searchProvider === "dsh" ? "active" : "",
778
+ "aria-pressed": preferences?.searchProvider === "dsh",
645
779
  disabled: busy !== null,
646
- onChange: () => updatePreferences({ searchProvider: "dsh" })
647
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("searchProviderDsh") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
648
- type: "radio",
649
- name: "dsh-codex-search-provider",
650
- checked: status?.preferences.searchProvider === "codex",
780
+ onClick: () => selectSearchProvider("dsh"),
781
+ children: t("searchProviderDsh")
782
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
783
+ type: "button",
784
+ className: preferences?.searchProvider === "codex" ? "active" : "",
785
+ "aria-pressed": preferences?.searchProvider === "codex",
651
786
  disabled: busy !== null,
652
- onChange: () => updatePreferences({ searchProvider: "codex" })
653
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("searchProviderCodex") })] })]
787
+ onClick: () => selectSearchProvider("codex"),
788
+ children: t("searchProviderCodex")
789
+ })]
654
790
  })]
655
791
  }),
656
792
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -661,7 +797,7 @@ window.__ModuleLoader__.load({
661
797
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
662
798
  className: "dsh-codex-select",
663
799
  "aria-label": t("outputVerbosity"),
664
- value: status?.preferences.outputVerbosity ?? "",
800
+ value: preferences?.outputVerbosity ?? "",
665
801
  disabled: busy !== null,
666
802
  onChange: (event) => {
667
803
  const value = event.currentTarget.value;
@@ -687,6 +823,91 @@ window.__ModuleLoader__.load({
687
823
  ]
688
824
  })]
689
825
  }),
826
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
827
+ className: "dsh-codex-pref-row",
828
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentMaxDepth") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
829
+ className: "dsh-codex-muted",
830
+ children: t("subagentMaxDepthHint")
831
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
832
+ className: "dsh-codex-select",
833
+ "aria-label": t("subagentMaxDepth"),
834
+ value: preferences?.subagentMaxDepth === null || preferences?.subagentMaxDepth === void 0 ? "" : String(preferences.subagentMaxDepth),
835
+ disabled: busy !== null,
836
+ onChange: (event) => {
837
+ const value = event.currentTarget.value;
838
+ updatePreferences({ subagentMaxDepth: value === "" ? null : Number(value) });
839
+ },
840
+ children: [
841
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
842
+ value: "",
843
+ children: t("providerDefault")
844
+ }),
845
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
846
+ value: "0",
847
+ children: [
848
+ "0 (",
849
+ t("subagentDisabled"),
850
+ ")"
851
+ ]
852
+ }),
853
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
854
+ value: "1",
855
+ children: ["1 ", t("levels")]
856
+ }),
857
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
858
+ value: "2",
859
+ children: ["2 ", t("levels")]
860
+ }),
861
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
862
+ value: "3",
863
+ children: ["3 ", t("levels")]
864
+ })
865
+ ]
866
+ })]
867
+ }),
868
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
869
+ className: "dsh-codex-context-settings",
870
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentContextWindow") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
871
+ className: "dsh-codex-muted",
872
+ children: t("subagentContextWindowHint")
873
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
874
+ className: "dsh-codex-context-row",
875
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
876
+ htmlFor: "dsh-codex-subagent-context",
877
+ children: t("subagentContextWindow")
878
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
879
+ className: "dsh-codex-capacity-control",
880
+ children: [
881
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
882
+ id: "dsh-codex-subagent-context",
883
+ type: "text",
884
+ inputMode: "numeric",
885
+ placeholder: t("providerDefault"),
886
+ value: subagentContextDraft ?? (preferences?.subagentContextWindow ? formatCapacity(preferences.subagentContextWindow) : ""),
887
+ disabled: busy !== null,
888
+ "aria-label": t("subagentContextWindow"),
889
+ onChange: (event) => {
890
+ setSubagentContextDraft(event.currentTarget.value);
891
+ },
892
+ onKeyDown: (event) => {
893
+ if (event.key !== "Enter") return;
894
+ event.preventDefault();
895
+ updateSubagentContextWindow();
896
+ }
897
+ }),
898
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("tokens") }),
899
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
900
+ className: "dsh-codex-context-save",
901
+ type: "button",
902
+ "aria-label": t("save") + " " + t("subagentContextWindow"),
903
+ disabled: busy !== null || subagentContextDraft === null,
904
+ onClick: () => void updateSubagentContextWindow(),
905
+ children: t("save")
906
+ })
907
+ ]
908
+ })]
909
+ })]
910
+ }),
690
911
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
691
912
  className: "dsh-codex-context-settings",
692
913
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("contextWindows") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
@@ -694,9 +915,9 @@ window.__ModuleLoader__.load({
694
915
  children: t("contextWindowsHint")
695
916
  })] }), CONFIGURABLE_CONTEXT_MODEL_IDS.map((model) => {
696
917
  const entry = resolveCodexCatalogEntry(model);
697
- const fallback = status?.preferences.contextWindowOverrides[model] ?? entry.contextWindow;
918
+ const fallback = preferences?.contextWindowOverrides?.[model] ?? entry.contextWindow;
698
919
  const draft = contextDrafts[model];
699
- const parsedDraft = draft === void 0 ? fallback : parseCapacity$1(draft);
920
+ const parsedDraft = draft === void 0 ? fallback : parseCapacity(draft);
700
921
  const dirty = draft !== void 0 && parsedDraft !== fallback;
701
922
  const inputId = `dsh-codex-context-${model}`;
702
923
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -711,7 +932,7 @@ window.__ModuleLoader__.load({
711
932
  id: inputId,
712
933
  type: "text",
713
934
  inputMode: "numeric",
714
- value: draft ?? formatCapacity$1(fallback),
935
+ value: draft ?? formatCapacity(fallback),
715
936
  disabled: busy !== null,
716
937
  "aria-label": entry.name + " " + t("contextWindow"),
717
938
  onChange: (event) => {
@@ -746,7 +967,16 @@ window.__ModuleLoader__.load({
746
967
  className: "dsh-codex-check",
747
968
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
748
969
  type: "checkbox",
749
- checked: status?.preferences.quickQuotaVisible === true,
970
+ checked: preferences?.fastMode === true,
971
+ disabled: busy !== null,
972
+ onChange: (event) => updatePreferences({ fastMode: event.currentTarget.checked })
973
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("fastMode") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("fastModeHint") })] })]
974
+ }),
975
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
976
+ className: "dsh-codex-check",
977
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
978
+ type: "checkbox",
979
+ checked: preferences?.quickQuotaVisible === true,
750
980
  disabled: busy !== null,
751
981
  onChange: (event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })
752
982
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("quickQuota") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("quickQuotaHint") })] })]
@@ -765,24 +995,24 @@ window.__ModuleLoader__.load({
765
995
  className: "dsh-codex-muted",
766
996
  children: t("quotaIntro")
767
997
  }),
768
- status?.quota.state === "signed-out" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
998
+ quota?.state === "signed-out" || !status?.authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
769
999
  className: "dsh-codex-empty",
770
1000
  children: t("quotaSignedOut")
771
1001
  }) : null,
772
- status?.quota.buckets.map((bucket) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaBucket, {
1002
+ quota?.buckets?.map((bucket) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaBucket, {
773
1003
  bucket,
774
1004
  t
775
1005
  }, bucket.id)),
776
- status?.quota.credits !== null && status?.quota.credits !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaFact, {
1006
+ quota?.credits !== null && quota?.credits !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaFact, {
777
1007
  label: t("credits"),
778
- value: status.quota.credits.unlimited ? t("unlimited") : status.quota.credits.balance ?? (status.quota.credits.hasCredits ? t("available") : t("unavailable"))
1008
+ value: quota.credits.unlimited ? t("unlimited") : quota.credits.balance ?? (quota.credits.hasCredits ? t("available") : t("unavailable"))
779
1009
  }) : null,
780
- status?.quota.individualLimit !== null && status?.quota.individualLimit !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaFact, {
1010
+ quota?.individualLimit !== null && quota?.individualLimit !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaFact, {
781
1011
  label: t("monthlySpend"),
782
- value: individualLimitLabel(status.quota.individualLimit, t)
1012
+ value: individualLimitLabel(quota.individualLimit, t)
783
1013
  }) : null,
784
- status?.quota.resetCredits !== null && status?.quota.resetCredits !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetCreditsFact, {
785
- resetCredits: status.quota.resetCredits,
1014
+ quota?.resetCredits !== null && quota?.resetCredits !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ResetCreditsFact, {
1015
+ resetCredits: quota.resetCredits,
786
1016
  busy,
787
1017
  onUse: useResetCredit,
788
1018
  t
@@ -792,31 +1022,31 @@ window.__ModuleLoader__.load({
792
1022
  role: "status",
793
1023
  children: resetCreditNotice
794
1024
  }) : null,
795
- status?.quota.spendControlReached === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1025
+ quota?.spendControlReached === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
796
1026
  className: "dsh-codex-warning",
797
1027
  role: "status",
798
1028
  children: t("spendControlReached")
799
1029
  }) : null,
800
- status?.quota.state === "empty" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1030
+ quota?.state === "empty" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
801
1031
  className: "dsh-codex-empty",
802
1032
  children: t("noQuota")
803
1033
  }) : null,
804
- status?.quota.stale ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1034
+ quota?.stale ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
805
1035
  className: "dsh-codex-warning",
806
1036
  role: "status",
807
1037
  children: t("stale")
808
1038
  }) : null,
809
- status?.quota.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1039
+ quota?.error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
810
1040
  className: "dsh-codex-error",
811
1041
  role: "alert",
812
- children: status.quota.error.message
1042
+ children: quota.error.message
813
1043
  }) : null,
814
- status?.quota.fetchedAt ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1044
+ quota?.fetchedAt ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
815
1045
  className: "dsh-codex-timestamp",
816
1046
  children: [
817
1047
  t("updated"),
818
1048
  ": ",
819
- formatDate(status.quota.fetchedAt)
1049
+ formatDate(quota.fetchedAt)
820
1050
  ]
821
1051
  }) : null
822
1052
  ]
@@ -920,7 +1150,7 @@ window.__ModuleLoader__.load({
920
1150
  });
921
1151
  }
922
1152
  function QuotaBar({ label, window, t }) {
923
- const percent = window.usedPercent;
1153
+ const percent = typeof window?.usedPercent === "number" && Number.isFinite(window.usedPercent) ? window.usedPercent : 0;
924
1154
  const level = percent >= 95 ? "danger" : percent >= 80 ? "warning" : "normal";
925
1155
  const remaining = Math.max(0, 100 - percent);
926
1156
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -937,11 +1167,11 @@ window.__ModuleLoader__.load({
937
1167
  "aria-valuemin": 0,
938
1168
  "aria-valuemax": 100,
939
1169
  "aria-valuenow": percent,
940
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${percent}%` } })
1170
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${Math.min(100, Math.max(0, percent))}%` } })
941
1171
  }),
942
1172
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
943
1173
  className: "dsh-codex-meter-meta",
944
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: percent >= 100 ? `${t("exhausted")} · ${formatPercent(remaining)} ${t("remaining")}` : `${formatPercent(percent)} ${t("used")} · ${formatPercent(remaining)} ${t("remaining")}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window.resetsAt === null ? "—" : `${t("resets")}: ${formatReset(window.resetsAt)}` })]
1174
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: percent >= 100 ? `${t("exhausted")} · ${formatPercent(remaining)} ${t("remaining")}` : `${formatPercent(percent)} ${t("used")} · ${formatPercent(remaining)} ${t("remaining")}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window?.resetsAt == null ? "—" : `${t("resets")}: ${formatReset(window.resetsAt)}` })]
945
1175
  })
946
1176
  ]
947
1177
  });
@@ -955,13 +1185,17 @@ window.__ModuleLoader__.load({
955
1185
  });
956
1186
  }
957
1187
  function windowLabel(minutes, t) {
958
- if (minutes === null) return t("limitWindow");
1188
+ if (minutes === null || minutes === void 0 || typeof minutes !== "number" || !Number.isFinite(minutes) || minutes <= 0) return t("limitWindow");
959
1189
  const [value, unit] = minutes >= 1440 && minutes % 1440 === 0 ? [minutes / 1440, "day"] : minutes >= 60 && minutes % 60 === 0 ? [minutes / 60, "hour"] : [Math.round(minutes), "minute"];
960
- return `${new Intl.NumberFormat(void 0, {
961
- style: "unit",
962
- unit,
963
- unitDisplay: "long"
964
- }).format(value)} ${t("limitWindow")}`;
1190
+ try {
1191
+ return `${new Intl.NumberFormat(void 0, {
1192
+ style: "unit",
1193
+ unit,
1194
+ unitDisplay: "long"
1195
+ }).format(value)} ${t("limitWindow")}`;
1196
+ } catch {
1197
+ return `${value} ${t("limitWindow")}`;
1198
+ }
965
1199
  }
966
1200
  function parsePositiveCapacity(value) {
967
1201
  const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
@@ -970,354 +1204,59 @@ window.__ModuleLoader__.load({
970
1204
  const parsed = Number(matched[1]) * multiplier;
971
1205
  return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
972
1206
  }
973
- function parseCapacity$1(value) {
1207
+ function parseCapacity(value) {
974
1208
  const parsed = parsePositiveCapacity(value);
975
1209
  return parsed !== null && parsed <= 1e6 ? parsed : null;
976
1210
  }
977
- function formatCapacity$1(value) {
1211
+ function formatCapacity(value) {
978
1212
  if (value % 1e3 === 0) return `${value / 1e3}K`;
979
1213
  return String(value);
980
1214
  }
981
1215
  function formatPercent(value) {
982
- return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value)}%`;
1216
+ if (value === void 0 || value === null || typeof value !== "number" || !Number.isFinite(value)) return "0%";
1217
+ try {
1218
+ return `${new Intl.NumberFormat(void 0, { maximumFractionDigits: 1 }).format(value)}%`;
1219
+ } catch {
1220
+ return `${value}%`;
1221
+ }
983
1222
  }
984
1223
  function individualLimitLabel(limit, t) {
985
1224
  const parts = [
986
- limit.remainingPercent !== null ? `${formatPercent(limit.remainingPercent)} ${t("remaining")}` : null,
987
- limit.limit !== null ? `${t("limit")}: ${limit.limit}` : null,
988
- limit.used !== null ? `${t("used")}: ${limit.used}` : null,
989
- limit.resetsAt !== null ? `${t("resets")}: ${formatReset(limit.resetsAt)}` : null
1225
+ limit.remainingPercent !== null && limit.remainingPercent !== void 0 ? `${formatPercent(limit.remainingPercent)} ${t("remaining")}` : null,
1226
+ limit.limit !== null && limit.limit !== void 0 ? `${t("limit")}: ${limit.limit}` : null,
1227
+ limit.used !== null && limit.used !== void 0 ? `${t("used")}: ${limit.used}` : null,
1228
+ limit.resetsAt !== null && limit.resetsAt !== void 0 ? `${t("resets")}: ${formatReset(limit.resetsAt)}` : null
990
1229
  ].filter((part) => part !== null);
991
1230
  return parts.length > 0 ? parts.join(" · ") : t("unknown");
992
1231
  }
993
1232
  function formatDate(seconds) {
994
- if (seconds === void 0) return "—";
995
- return new Intl.DateTimeFormat(void 0, {
996
- dateStyle: "medium",
997
- timeStyle: "short"
998
- }).format(seconds * 1e3);
1233
+ if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
1234
+ const ms = seconds > 1e10 ? seconds : seconds * 1e3;
1235
+ try {
1236
+ return new Intl.DateTimeFormat(void 0, {
1237
+ dateStyle: "medium",
1238
+ timeStyle: "short"
1239
+ }).format(ms);
1240
+ } catch {
1241
+ return "—";
1242
+ }
999
1243
  }
1000
1244
  function formatReset(seconds) {
1245
+ if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
1246
+ const ms = seconds > 1e10 ? seconds : seconds * 1e3;
1001
1247
  const absolute = formatDate(seconds);
1002
- const diff = seconds * 1e3 - Date.now();
1248
+ const diff = ms - Date.now();
1003
1249
  const abs = Math.abs(diff);
1004
1250
  const [amount, unit] = abs >= 864e5 ? [Math.round(diff / 864e5), "day"] : abs >= 36e5 ? [Math.round(diff / 36e5), "hour"] : [Math.round(diff / 6e4), "minute"];
1005
- return `${absolute} (${new Intl.RelativeTimeFormat(void 0, { numeric: "auto" }).format(amount, unit)})`;
1251
+ try {
1252
+ return `${absolute} (${new Intl.RelativeTimeFormat(void 0, { numeric: "auto" }).format(amount, unit)})`;
1253
+ } catch {
1254
+ return absolute;
1255
+ }
1006
1256
  }
1007
- function messageOf$1(error) {
1257
+ function messageOf(error) {
1008
1258
  return error instanceof Error ? error.message : String(error);
1009
1259
  }
1010
- [...DEFAULT_VISIBLE_CODEX_MODEL_IDS];
1011
- //#endregion
1012
- //#region src/client/SubagentSettingsSection.tsx
1013
- function SubagentSettingsSection({ t }) {
1014
- const apiRef = (0, react.useRef)(new SubscriptionApi());
1015
- const [preferences, setPreferences] = (0, react.useState)(null);
1016
- const [catalog, setCatalog] = (0, react.useState)(null);
1017
- const [busy, setBusy] = (0, react.useState)(false);
1018
- const [error, setError] = (0, react.useState)(null);
1019
- const [contextDraft, setContextDraft] = (0, react.useState)(null);
1020
- const [depthDraft, setDepthDraft] = (0, react.useState)(null);
1021
- const [agentsDraft, setAgentsDraft] = (0, react.useState)(null);
1022
- const load = (0, react.useCallback)(async () => {
1023
- setError(null);
1024
- try {
1025
- const [status, models] = await Promise.all([apiRef.current.status(), apiRef.current.models()]);
1026
- setPreferences(status.preferences);
1027
- setCatalog(models);
1028
- } catch (cause) {
1029
- setError(messageOf(cause));
1030
- }
1031
- }, []);
1032
- (0, react.useEffect)(() => {
1033
- load();
1034
- }, [load]);
1035
- const update = async (patch) => {
1036
- setBusy(true);
1037
- setError(null);
1038
- try {
1039
- setPreferences(await apiRef.current.updatePreferences(patch));
1040
- } catch (cause) {
1041
- setError(messageOf(cause));
1042
- } finally {
1043
- setBusy(false);
1044
- }
1045
- };
1046
- const selectedProvider = catalog?.providers.find((provider) => provider.id === preferences?.subagentProvider) ?? catalog?.providers[0];
1047
- const selectedModel = selectedProvider?.models.find((model) => model.id === preferences?.subagentModel) ?? selectedProvider?.models[0];
1048
- const reasoning = selectedModel?.reasoning;
1049
- const selectedEffort = preferences?.subagentReasoningEffort ?? reasoning?.defaultEffort ?? reasoning?.efforts[0]?.id ?? "";
1050
- const savedContext = preferences?.subagentContextWindow ?? selectedModel?.contextWindow ?? 1;
1051
- const parsedContext = parseCapacity(contextDraft ?? String(savedContext));
1052
- const contextValid = parsedContext !== null && (selectedModel?.maxContextWindow === void 0 || parsedContext <= selectedModel.maxContextWindow);
1053
- const parsedDepthValue = parseNonNegativeInteger(depthDraft ?? String(preferences?.subagentMaxDepth ?? 0));
1054
- const parsedDepth = parsedDepthValue !== null && parsedDepthValue <= 3 ? parsedDepthValue : null;
1055
- const parsedAgents = parsePositiveInteger(agentsDraft ?? String(preferences?.subagentMaxAgents ?? 1));
1056
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1057
- className: "dsh-codex-page",
1058
- "aria-labelledby": "dsh-subagent-title",
1059
- children: [
1060
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
1061
- id: "dsh-subagent-title",
1062
- className: "dsh-codex-title",
1063
- children: t("subagentSettingsTitle")
1064
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1065
- className: "dsh-codex-intro",
1066
- children: t("subagentSettingsIntro")
1067
- })] }),
1068
- error !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1069
- className: "dsh-codex-errorbar",
1070
- role: "alert",
1071
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: error }), preferences === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1072
- className: "dsh-codex-button",
1073
- type: "button",
1074
- onClick: () => void load(),
1075
- children: t("retry")
1076
- }) : null]
1077
- }) : null,
1078
- preferences === null || catalog === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1079
- className: "dsh-codex-skeleton",
1080
- role: "status",
1081
- "aria-label": t("loading"),
1082
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {})]
1083
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1084
- className: "dsh-codex-group",
1085
- children: [
1086
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1087
- className: "dsh-codex-grouphead",
1088
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("subagentModelGroup") })
1089
- }),
1090
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1091
- className: "dsh-codex-pref-row",
1092
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentProvider") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1093
- className: "dsh-codex-muted",
1094
- children: t("subagentProviderHint")
1095
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
1096
- className: "dsh-codex-select",
1097
- "aria-label": t("subagentProvider"),
1098
- value: selectedProvider?.id ?? "",
1099
- disabled: busy || selectedProvider === void 0,
1100
- onChange: (event) => {
1101
- const provider = catalog.providers.find((entry) => entry.id === event.currentTarget.value);
1102
- const model = provider?.models[0];
1103
- if (provider === void 0 || model === void 0) return;
1104
- const effort = model.reasoning?.defaultEffort ?? model.reasoning?.efforts[0]?.id ?? null;
1105
- setContextDraft(null);
1106
- update({
1107
- subagentProvider: provider.id,
1108
- subagentModel: model.id,
1109
- subagentReasoningEffort: effort,
1110
- subagentContextWindow: model.contextWindow ?? 1
1111
- });
1112
- },
1113
- children: catalog.providers.map((provider) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1114
- value: provider.id,
1115
- children: provider.name
1116
- }, provider.id))
1117
- })]
1118
- }),
1119
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1120
- className: "dsh-codex-pref-row",
1121
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentModel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1122
- className: "dsh-codex-muted",
1123
- children: t("subagentModelHint")
1124
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
1125
- className: "dsh-codex-select",
1126
- "aria-label": t("subagentModel"),
1127
- value: selectedModel?.id ?? "",
1128
- disabled: busy || selectedModel === void 0,
1129
- onChange: (event) => {
1130
- const model = selectedProvider?.models.find((entry) => entry.id === event.currentTarget.value);
1131
- if (selectedProvider === void 0 || model === void 0) return;
1132
- const effort = model.reasoning?.defaultEffort ?? model.reasoning?.efforts[0]?.id ?? null;
1133
- setContextDraft(null);
1134
- update({
1135
- subagentProvider: selectedProvider.id,
1136
- subagentModel: model.id,
1137
- subagentReasoningEffort: effort,
1138
- subagentContextWindow: model.contextWindow ?? 1
1139
- });
1140
- },
1141
- children: selectedProvider?.models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1142
- value: model.id,
1143
- children: model.name
1144
- }, model.id))
1145
- })]
1146
- }),
1147
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1148
- className: "dsh-codex-pref-row",
1149
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentReasoningEffort") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1150
- className: "dsh-codex-muted",
1151
- children: t("subagentReasoningEffortHint")
1152
- })] }), reasoning !== void 0 && reasoning.efforts.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
1153
- className: "dsh-codex-select",
1154
- "aria-label": t("subagentReasoningEffort"),
1155
- value: selectedEffort,
1156
- disabled: busy,
1157
- onChange: (event) => void update({ subagentReasoningEffort: event.currentTarget.value }),
1158
- children: reasoning.efforts.map((effort) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
1159
- value: effort.id,
1160
- children: effort.name
1161
- }, effort.id))
1162
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1163
- className: "dsh-codex-muted",
1164
- children: t("providerDefault")
1165
- })]
1166
- }),
1167
- selectedModel?.contextWindow !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1168
- className: "dsh-codex-context-settings",
1169
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("effectiveContextWindow") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1170
- className: "dsh-codex-muted",
1171
- children: t("selectedModelContextHint")
1172
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1173
- className: "dsh-codex-context-row",
1174
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1175
- htmlFor: "dsh-subagent-context",
1176
- children: selectedModel.name
1177
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1178
- className: "dsh-codex-capacity-control",
1179
- children: [
1180
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1181
- id: "dsh-subagent-context",
1182
- type: "text",
1183
- inputMode: "numeric",
1184
- value: contextDraft ?? formatCapacity(savedContext),
1185
- disabled: busy,
1186
- onChange: (event) => setContextDraft(event.currentTarget.value)
1187
- }),
1188
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("tokens") }),
1189
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1190
- className: "dsh-codex-context-save",
1191
- type: "button",
1192
- disabled: busy || contextDraft === null || !contextValid || parsedContext === savedContext,
1193
- onClick: () => {
1194
- if (parsedContext === null) return;
1195
- update({ subagentContextWindow: parsedContext }).then(() => setContextDraft(null));
1196
- },
1197
- children: t("save")
1198
- })
1199
- ]
1200
- })]
1201
- })]
1202
- }) : null
1203
- ]
1204
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1205
- className: "dsh-codex-group",
1206
- children: [
1207
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1208
- className: "dsh-codex-grouphead",
1209
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("subagentLimitsGroup") })
1210
- }),
1211
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1212
- className: "dsh-codex-context-settings",
1213
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentMaxDepth") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1214
- className: "dsh-codex-muted",
1215
- children: t("subagentMaxDepthHint")
1216
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1217
- className: "dsh-codex-context-row",
1218
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1219
- htmlFor: "dsh-subagent-depth",
1220
- children: t("subagentMaxDepth")
1221
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1222
- className: "dsh-codex-capacity-control",
1223
- children: [
1224
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1225
- id: "dsh-subagent-depth",
1226
- type: "number",
1227
- min: "0",
1228
- max: 3,
1229
- step: "1",
1230
- inputMode: "numeric",
1231
- value: depthDraft ?? String(preferences.subagentMaxDepth),
1232
- disabled: busy,
1233
- onChange: (event) => setDepthDraft(event.currentTarget.value)
1234
- }),
1235
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("levels") }),
1236
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1237
- className: "dsh-codex-context-save",
1238
- type: "button",
1239
- disabled: busy || depthDraft === null || parsedDepth === null || parsedDepth === preferences.subagentMaxDepth,
1240
- onClick: () => {
1241
- if (parsedDepth === null) return;
1242
- update({ subagentMaxDepth: parsedDepth }).then(() => setDepthDraft(null));
1243
- },
1244
- children: t("save")
1245
- })
1246
- ]
1247
- })]
1248
- })]
1249
- }),
1250
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1251
- className: "dsh-codex-context-settings",
1252
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t("subagentMaxAgents") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1253
- className: "dsh-codex-muted",
1254
- children: t("subagentMaxAgentsHint")
1255
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1256
- className: "dsh-codex-context-row",
1257
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1258
- htmlFor: "dsh-subagent-agents",
1259
- children: t("subagentMaxAgents")
1260
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1261
- className: "dsh-codex-capacity-control",
1262
- children: [
1263
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1264
- id: "dsh-subagent-agents",
1265
- type: "number",
1266
- min: "1",
1267
- step: "1",
1268
- inputMode: "numeric",
1269
- value: agentsDraft ?? String(preferences.subagentMaxAgents),
1270
- disabled: busy,
1271
- onChange: (event) => setAgentsDraft(event.currentTarget.value)
1272
- }),
1273
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("agents") }),
1274
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1275
- className: "dsh-codex-context-save",
1276
- type: "button",
1277
- disabled: busy || agentsDraft === null || parsedAgents === null || parsedAgents === preferences.subagentMaxAgents,
1278
- onClick: () => {
1279
- if (parsedAgents === null) return;
1280
- update({ subagentMaxAgents: parsedAgents }).then(() => setAgentsDraft(null));
1281
- },
1282
- children: t("save")
1283
- })
1284
- ]
1285
- })]
1286
- })]
1287
- }),
1288
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1289
- className: "dsh-codex-notice",
1290
- children: t("subagentLimitsNotice")
1291
- })
1292
- ]
1293
- })] })
1294
- ]
1295
- });
1296
- }
1297
- function parseNonNegativeInteger(value) {
1298
- if (!/^\d+$/.test(value.trim())) return null;
1299
- const parsed = Number(value.trim());
1300
- return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null;
1301
- }
1302
- function parsePositiveInteger(value) {
1303
- const parsed = parseNonNegativeInteger(value);
1304
- return parsed !== null && parsed >= 1 ? parsed : null;
1305
- }
1306
- function parseCapacity(value) {
1307
- const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
1308
- if (matched === null) return null;
1309
- const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
1310
- const parsed = Number(matched[1]) * multiplier;
1311
- return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
1312
- }
1313
- function formatCapacity(value) {
1314
- if (value % 1e6 === 0) return `${value / 1e6}M`;
1315
- if (value % 1e3 === 0) return `${value / 1e3}K`;
1316
- return String(value);
1317
- }
1318
- function messageOf(cause) {
1319
- return cause instanceof Error ? cause.message : String(cause);
1320
- }
1321
1260
  //#endregion
1322
1261
  //#region src/client/locales.ts
1323
1262
  const NS = "dsh-chatgpt-subscription";
@@ -1361,43 +1300,40 @@ window.__ModuleLoader__.load({
1361
1300
  latency: "最近延迟",
1362
1301
  models: "可用模型",
1363
1302
  modelsHint: "勾选后模型才会显示在对话页的模型选择列表中;至少保留一个。",
1303
+ proxySettings: "网络代理",
1304
+ proxyMode: "代理模式",
1305
+ proxyModeHint: "配置访问 OpenAI / ChatGPT 服务的网络代理;支持自动读取操作系统代理。",
1306
+ proxyModeAuto: "系统代理(自动检测)",
1307
+ proxyModeCustom: "自定义代理",
1308
+ proxyModeDirect: "直连(禁用代理)",
1309
+ customProxyUrl: "自定义代理地址",
1310
+ customProxyUrlHint: "支持 HTTP/HTTPS/SOCKS5 代理地址,例如 http://127.0.0.1:7890",
1311
+ customProxyUrlPlaceholder: "例如: http://127.0.0.1:7890",
1312
+ saveProxyUrl: "保存代理地址",
1313
+ proxyDetected: "检测到系统代理",
1314
+ proxyDetectedEffective: "(已自动生效)",
1315
+ proxyNoneDetected: "未检测到系统代理,将使用直连",
1316
+ proxyDirectHint: "所有网络请求将直接连接,不经过任何代理服务器。",
1364
1317
  enhancements: "增强功能",
1318
+ fastMode: "快速模式(1.5x 速度)",
1319
+ fastModeHint: "提升 Token 生成速度至约 1.5 倍;将以约 2x–2.5x 速度消耗 Codex 订阅额度。",
1365
1320
  outputVerbosity: "输出详细程度",
1366
1321
  outputVerbosityHint: "控制 Codex 最终回答的详细程度;不影响思考深度。",
1367
1322
  verbosityLow: "低(保持回答简洁)",
1368
1323
  verbosityMedium: "中(兼顾细节与简洁)",
1369
1324
  verbosityHigh: "高(在回答中包含更多细节)",
1370
- subagentSettingsNav: "子代理",
1371
- subagentSettingsTitle: "子代理设置",
1372
- subagentSettingsIntro: "全局配置 DSH 内置子代理。模型、思考深度、上下文预算和运行限制适用于所有父 Agent,不受父 Agent 当前 Provider 或模型影响。",
1373
- subagentModelGroup: "模型与上下文",
1374
- subagentLimitsGroup: "运行限制",
1375
- subagentMaxDepth: "最大嵌套深度",
1376
- subagentMaxDepthHint: "限制从顶层 Agent 开始的子代理层级(0–3);0 禁止创建子代理,1 仅允许直接子代理。",
1377
- subagentMaxAgents: "子代理数量上限",
1378
- subagentMaxAgentsHint: "限制每个父 Agent 子树中同时处于活动或启动中的子代理总数。",
1379
- subagentLimitsNotice: "限制会立即应用于新的委派,不会中断已经运行的子代理。数量上限统计当前父 Agent 的全部活动后代。",
1380
- levels: "层",
1381
- agents: "个",
1382
- searchProvider: "搜索来源",
1383
- searchProviderHint: "选择 DSH Web 搜索工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 搜索来源。",
1325
+ searchProvider: "搜索与抓取来源",
1326
+ searchProviderHint: "选择 DSH 联网工具使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。",
1384
1327
  searchProviderDsh: "DSH 默认",
1385
- searchProviderCodex: "Codex 订阅",
1386
- subagentProvider: "子代理 Provider",
1387
- subagentProviderHint: "选择 DSH 当前已接入且可用的模型提供方。",
1388
- subagentModel: "子代理模型",
1389
- subagentModelHint: "全局应用于所有 DSH 内置子代理;模型可来自任意已接入 Provider。",
1390
- subagentReasoningEffort: "子代理思考深度",
1391
- subagentReasoningEffortHint: "选项来自所选模型实际公开的 reasoning effort 能力。",
1328
+ searchProviderCodex: "Codex 订阅(代理隧道)",
1392
1329
  providerDefault: "使用 Provider 默认值",
1393
- effectiveContextWindow: "有效上下文窗口",
1394
- selectedModelContextHint: "选择模型后展开;该值仅用于子 Agent 的 DSH 上下文预算与压缩判断。",
1395
- reasoningNone: "无",
1396
- reasoningLow: "低",
1397
- reasoningMedium: "中",
1398
- reasoningHigh: "高",
1399
- reasoningXhigh: "超高",
1400
- reasoningMax: "最大",
1330
+ subagentEnhancements: "子代理设置",
1331
+ subagentContextWindow: "子代理上下文预算",
1332
+ subagentContextWindowHint: "限制子代理运行时的最大上下文 Token 数(例如 128K、256K);留空跟随模型主设置。",
1333
+ subagentMaxDepth: "子代理最大嵌套深度",
1334
+ subagentMaxDepthHint: "限制子代理的递归层级(0–3);0 禁止创建子代理。",
1335
+ subagentDisabled: "已禁用",
1336
+ levels: "层",
1401
1337
  contextWindows: "GPT-5.6 上下文窗口",
1402
1338
  contextWindowsHint: "默认 272K;可选启用最高 1M。该值用于 DSH 的压缩与溢出判断,可输入 1M、512K 等容量。",
1403
1339
  contextWindow: "上下文窗口",
@@ -1489,43 +1425,40 @@ window.__ModuleLoader__.load({
1489
1425
  latency: "Last latency",
1490
1426
  models: "Available models",
1491
1427
  modelsHint: "Checked models appear in the conversation model picker; at least one must remain enabled.",
1428
+ proxySettings: "Network Proxy",
1429
+ proxyMode: "Proxy Mode",
1430
+ proxyModeHint: "Configure network proxy for accessing OpenAI / ChatGPT services; supports auto-detecting system proxy.",
1431
+ proxyModeAuto: "System Proxy (Auto-detect)",
1432
+ proxyModeCustom: "Custom Proxy",
1433
+ proxyModeDirect: "Direct (No Proxy)",
1434
+ customProxyUrl: "Custom Proxy URL",
1435
+ customProxyUrlHint: "Supports HTTP/HTTPS/SOCKS5 proxy URLs, e.g. http://127.0.0.1:7890",
1436
+ customProxyUrlPlaceholder: "e.g. http://127.0.0.1:7890",
1437
+ saveProxyUrl: "Save Proxy URL",
1438
+ proxyDetected: "Detected system proxy",
1439
+ proxyDetectedEffective: " (active)",
1440
+ proxyNoneDetected: "No system proxy detected; connecting directly",
1441
+ proxyDirectHint: "All requests connect directly without using any proxy server.",
1492
1442
  enhancements: "Enhancements",
1443
+ fastMode: "Fast mode (1.5x speed)",
1444
+ fastModeHint: "Generates tokens ~1.5x faster; consumes Codex subscription quota at ~2x–2.5x the normal rate.",
1493
1445
  outputVerbosity: "Output verbosity",
1494
1446
  outputVerbosityHint: "Controls the detail level of final Codex answers without changing reasoning effort.",
1495
1447
  verbosityLow: "Low (keep answers concise)",
1496
1448
  verbosityMedium: "Medium (balance detail and brevity)",
1497
1449
  verbosityHigh: "High (include more detail)",
1498
- subagentSettingsNav: "Subagents",
1499
- subagentSettingsTitle: "Subagent settings",
1500
- subagentSettingsIntro: "Configure DSH built-in subagents globally. Model, reasoning effort, context budget, and runtime limits apply to every parent Agent regardless of its current provider or model.",
1501
- subagentModelGroup: "Model and context",
1502
- subagentLimitsGroup: "Runtime limits",
1503
- subagentMaxDepth: "Maximum nesting depth",
1504
- subagentMaxDepthHint: "Limit child levels below a top-level Agent (0–3). Zero disables subagents; one allows direct children only.",
1505
- subagentMaxAgents: "Maximum subagents",
1506
- subagentMaxAgentsHint: "Limit the total number of active or starting subagents in each parent Agent tree.",
1507
- subagentLimitsNotice: "Limits apply immediately to new delegations and do not interrupt subagents already running. The count covers all active descendants of the current parent Agent.",
1508
- levels: "levels",
1509
- agents: "agents",
1510
- searchProvider: "Search provider",
1511
- searchProviderHint: "Choose whether DSH web search uses its default provider or the Codex search source from this ChatGPT subscription.",
1450
+ searchProvider: "Search & Fetch provider",
1451
+ searchProviderHint: "Choose whether DSH web tools use the default provider or the Codex proxy-backed source from this ChatGPT subscription.",
1512
1452
  searchProviderDsh: "DSH default",
1513
- searchProviderCodex: "Codex subscription",
1514
- subagentProvider: "Subagent provider",
1515
- subagentProviderHint: "Choose from providers currently connected and available in DSH.",
1516
- subagentModel: "Subagent model",
1517
- subagentModelHint: "Applies globally to all built-in DSH subagents; the selected child model may come from any connected provider.",
1518
- subagentReasoningEffort: "Subagent reasoning effort",
1519
- subagentReasoningEffortHint: "Options come from the reasoning-effort capabilities exposed by the selected model.",
1453
+ searchProviderCodex: "Codex subscription (Proxy tunnel)",
1520
1454
  providerDefault: "Use provider default",
1521
- effectiveContextWindow: "Effective context window",
1522
- selectedModelContextHint: "Shown after model selection; used only for the child Agent context budget and DSH compaction decisions.",
1523
- reasoningNone: "None",
1524
- reasoningLow: "Low",
1525
- reasoningMedium: "Medium",
1526
- reasoningHigh: "High",
1527
- reasoningXhigh: "Extra high",
1528
- reasoningMax: "Maximum",
1455
+ subagentEnhancements: "Subagent settings",
1456
+ subagentContextWindow: "Subagent context window budget",
1457
+ subagentContextWindowHint: "Limits context capacity in tokens for subagents (e.g. 128K, 256K); leave empty to follow main model settings.",
1458
+ subagentMaxDepth: "Subagent maximum nesting depth",
1459
+ subagentMaxDepthHint: "Limits child levels for subagents (0–3); 0 disables subagents.",
1460
+ subagentDisabled: "Disabled",
1461
+ levels: "levels",
1529
1462
  contextWindows: "GPT-5.6 context windows",
1530
1463
  contextWindowsHint: "Defaults to 272K, with an optional value up to 1M. DSH uses it for compaction and overflow detection; values such as 1M and 512K are accepted.",
1531
1464
  contextWindow: "Context window",
@@ -1616,18 +1549,24 @@ window.__ModuleLoader__.load({
1616
1549
  .dsh-codex-models input:disabled+span{cursor:default;opacity:.5}
1617
1550
  .dsh-codex-pref-row{align-items:center;border-bottom:1px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}
1618
1551
  .dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}
1619
- .dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex:none;gap:2px;padding:2px}
1620
- .dsh-codex-segments label{cursor:pointer;display:block}
1552
+ .dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:8px;display:inline-flex;flex-wrap:nowrap;gap:3px;padding:3px}
1553
+ .dsh-codex-segments label{cursor:pointer;display:block;margin:0}
1621
1554
  .dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}
1622
- .dsh-codex-segments span{border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1;padding:7px 10px;white-space:nowrap}
1623
- .dsh-codex-segments input:checked+span{background:var(--dsw-alias-bg-base);box-shadow:0 1px 2px rgba(0,0,0,.08);color:var(--dsw-alias-label-primary)}
1624
- .dsh-codex-segments input:focus-visible+span{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
1625
- .dsh-codex-segments input:disabled+span{cursor:default;opacity:.5}
1555
+ .dsh-codex-segments span,.dsh-codex-segments button{border:1px solid transparent;border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font:inherit;font-size:12px;font-weight:500;line-height:1.2;padding:6px 12px;transition:all .15s ease;user-select:none;white-space:nowrap}
1556
+ .dsh-codex-segments button{background:transparent;cursor:pointer}
1557
+ .dsh-codex-segments label:hover span,.dsh-codex-segments button:hover:not(:disabled){color:var(--dsw-alias-label-primary)}
1558
+ .dsh-codex-segments input:checked+span,.dsh-codex-segments button.active,.dsh-codex-segments button[aria-pressed=true]{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 22%,var(--dsw-alias-bg-layer-2));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 60%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary);font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.15)}
1559
+ .dsh-codex-segments input:focus-visible+span,.dsh-codex-segments button:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}
1560
+ .dsh-codex-segments input:disabled+span,.dsh-codex-segments button:disabled{cursor:default;opacity:.5}
1626
1561
  .dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}
1627
1562
  .dsh-codex-select{max-width:210px;min-width:150px}
1628
1563
  .dsh-codex-context-settings{border-bottom:1px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}
1629
1564
  .dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}
1630
1565
  .dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}
1566
+ .dsh-codex-proxy-control{align-items:center;display:flex;gap:8px;width:100%}
1567
+ .dsh-codex-proxy-control input{background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);flex:1;font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;min-width:220px;padding:7px 10px;text-align:left}
1568
+ .dsh-codex-proxy-status{align-items:center;color:var(--dsw-alias-label-secondary);display:flex;flex-wrap:wrap;font-size:12px;gap:6px;margin:6px 0 0}
1569
+ .dsh-codex-proxy-tag{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 18%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 45%,transparent);border-radius:4px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:2px 6px}
1631
1570
  .dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}
1632
1571
  .dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}
1633
1572
  .dsh-codex-capacity-control input[type=number]{width:110px}
@@ -1703,13 +1642,6 @@ window.__ModuleLoader__.load({
1703
1642
  ctx.effect(() => ctx.locale.register(NS, dictionaries), "dsh-chatgpt-subscription: dictionaries");
1704
1643
  ctx.effect(() => installStyles(), "dsh-chatgpt-subscription: styles");
1705
1644
  const t = ctx.locale.bind(NS);
1706
- ctx.slots.inject("settings.section", () => ctx.slots.register({
1707
- name: "settings.section",
1708
- id: "subagents",
1709
- order: 30,
1710
- label: () => t("subagentSettingsNav"),
1711
- locale: NS
1712
- }, SubagentSettingsSection));
1713
1645
  ctx.slots.inject("settings.section", () => ctx.slots.register({
1714
1646
  name: "settings.section",
1715
1647
  id: "codex-subscription",