@michengai/dsh-codex-ui 0.2.112 → 1.0.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.
package/lib/client.js CHANGED
@@ -30,16 +30,22 @@ window.__ModuleLoader__.load({
30
30
  }
31
31
  let cancelPendingNavigation;
32
32
  const SETTINGS_NAVIGATION_TIMEOUT_MS = 4e3;
33
+ const SETTINGS_TRIGGER_SELECTOR = "[data-dcu-settings-trigger],[aria-haspopup=\"dialog\"]";
34
+ /** 根入口与分区跳转使用同一触发器合约,兼容保留的宿主设置壳。 */
35
+ function openSettingsRoot(root) {
36
+ root?.querySelector(SETTINGS_TRIGGER_SELECTOR)?.click();
37
+ }
33
38
  function openSettingsSection(root, label, onMissing, onSelected) {
34
39
  const labels = typeof label === "string" ? [label] : label;
35
- const trigger = root?.querySelector("[aria-haspopup=\"dialog\"]");
40
+ const trigger = root?.querySelector(SETTINGS_TRIGGER_SELECTOR);
36
41
  if (trigger === null || trigger === void 0) {
37
42
  onMissing?.();
38
43
  return;
39
44
  }
40
45
  const opening = cancelPendingNavigation !== void 0;
41
46
  cancelPendingNavigation?.();
42
- if (!opening && document.querySelector("[role=\"dialog\"]") === null) trigger.click();
47
+ const pageSelector = trigger.hasAttribute("data-dcu-settings-trigger") ? "[data-dcu-settings-page]" : "[role=\"dialog\"]";
48
+ if (!opening && document.querySelector(pageSelector) === null) trigger.click();
43
49
  let frame;
44
50
  let finished = false;
45
51
  const observer = new MutationObserver(() => {
@@ -54,7 +60,7 @@ window.__ModuleLoader__.load({
54
60
  if (cancelPendingNavigation === cleanup) cancelPendingNavigation = void 0;
55
61
  };
56
62
  const select = () => {
57
- const target = pickSettingsSectionButton([...document.querySelectorAll("[role=\"dialog\"] nav button")], labels);
63
+ const target = pickSettingsSectionButton([...document.querySelectorAll(`${pageSelector} nav button`)], labels);
58
64
  if (target === void 0) return false;
59
65
  cleanup();
60
66
  target.click();
@@ -483,6 +489,148 @@ window.__ModuleLoader__.load({
483
489
  * This source code is licensed under the ISC license.
484
490
  * See the LICENSE file in the root directory of this source tree.
485
491
  */
492
+ const ArrowLeft = createLucideIcon("arrow-left", [["path", {
493
+ d: "m12 19-7-7 7-7",
494
+ key: "1l729n"
495
+ }], ["path", {
496
+ d: "M19 12H5",
497
+ key: "x3x0zl"
498
+ }]]);
499
+ /**
500
+ * @license lucide-react v1.39.0 - ISC
501
+ *
502
+ * This source code is licensed under the ISC license.
503
+ * See the LICENSE file in the root directory of this source tree.
504
+ */
505
+ const Box = createLucideIcon("box", [
506
+ ["path", {
507
+ d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z",
508
+ key: "hh9hay"
509
+ }],
510
+ ["path", {
511
+ d: "m3.3 7 8.7 5 8.7-5",
512
+ key: "g66t2b"
513
+ }],
514
+ ["path", {
515
+ d: "M12 22V12",
516
+ key: "d0xqtd"
517
+ }]
518
+ ]);
519
+ /**
520
+ * @license lucide-react v1.39.0 - ISC
521
+ *
522
+ * This source code is licensed under the ISC license.
523
+ * See the LICENSE file in the root directory of this source tree.
524
+ */
525
+ const CircleQuestionMark = createLucideIcon("circle-question-mark", [
526
+ ["circle", {
527
+ cx: "12",
528
+ cy: "12",
529
+ r: "10",
530
+ key: "1mglay"
531
+ }],
532
+ ["path", {
533
+ d: "M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3",
534
+ key: "1u773s"
535
+ }],
536
+ ["path", {
537
+ d: "M12 17h.01",
538
+ key: "p32p05"
539
+ }]
540
+ ]);
541
+ /**
542
+ * @license lucide-react v1.39.0 - ISC
543
+ *
544
+ * This source code is licensed under the ISC license.
545
+ * See the LICENSE file in the root directory of this source tree.
546
+ */
547
+ const Clock = createLucideIcon("clock", [["circle", {
548
+ cx: "12",
549
+ cy: "12",
550
+ r: "10",
551
+ key: "1mglay"
552
+ }], ["path", {
553
+ d: "M12 6v6l4 2",
554
+ key: "mmk7yg"
555
+ }]]);
556
+ /**
557
+ * @license lucide-react v1.39.0 - ISC
558
+ *
559
+ * This source code is licensed under the ISC license.
560
+ * See the LICENSE file in the root directory of this source tree.
561
+ */
562
+ const Cpu = createLucideIcon("cpu", [
563
+ ["path", {
564
+ d: "M12 20v2",
565
+ key: "1lh1kg"
566
+ }],
567
+ ["path", {
568
+ d: "M12 2v2",
569
+ key: "tus03m"
570
+ }],
571
+ ["path", {
572
+ d: "M17 20v2",
573
+ key: "1rnc9c"
574
+ }],
575
+ ["path", {
576
+ d: "M17 2v2",
577
+ key: "11trls"
578
+ }],
579
+ ["path", {
580
+ d: "M2 12h2",
581
+ key: "1t8f8n"
582
+ }],
583
+ ["path", {
584
+ d: "M2 17h2",
585
+ key: "7oei6x"
586
+ }],
587
+ ["path", {
588
+ d: "M2 7h2",
589
+ key: "asdhe0"
590
+ }],
591
+ ["path", {
592
+ d: "M20 12h2",
593
+ key: "1q8mjw"
594
+ }],
595
+ ["path", {
596
+ d: "M20 17h2",
597
+ key: "1fpfkl"
598
+ }],
599
+ ["path", {
600
+ d: "M20 7h2",
601
+ key: "1o8tra"
602
+ }],
603
+ ["path", {
604
+ d: "M7 20v2",
605
+ key: "4gnj0m"
606
+ }],
607
+ ["path", {
608
+ d: "M7 2v2",
609
+ key: "1i4yhu"
610
+ }],
611
+ ["rect", {
612
+ x: "4",
613
+ y: "4",
614
+ width: "16",
615
+ height: "16",
616
+ rx: "2",
617
+ key: "1vbyd7"
618
+ }],
619
+ ["rect", {
620
+ x: "8",
621
+ y: "8",
622
+ width: "8",
623
+ height: "8",
624
+ rx: "1",
625
+ key: "z9xiuo"
626
+ }]
627
+ ]);
628
+ /**
629
+ * @license lucide-react v1.39.0 - ISC
630
+ *
631
+ * This source code is licensed under the ISC license.
632
+ * See the LICENSE file in the root directory of this source tree.
633
+ */
486
634
  const EyeOff = createLucideIcon("eye-off", [
487
635
  ["path", {
488
636
  d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",
@@ -522,6 +670,19 @@ window.__ModuleLoader__.load({
522
670
  * This source code is licensed under the ISC license.
523
671
  * See the LICENSE file in the root directory of this source tree.
524
672
  */
673
+ const Link = createLucideIcon("link", [["path", {
674
+ d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71",
675
+ key: "1cjeqo"
676
+ }], ["path", {
677
+ d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",
678
+ key: "19qd67"
679
+ }]]);
680
+ /**
681
+ * @license lucide-react v1.39.0 - ISC
682
+ *
683
+ * This source code is licensed under the ISC license.
684
+ * See the LICENSE file in the root directory of this source tree.
685
+ */
525
686
  const MessageCircle = createLucideIcon("message-circle", [["path", {
526
687
  d: "M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",
527
688
  key: "1sd12s"
@@ -532,6 +693,33 @@ window.__ModuleLoader__.load({
532
693
  * This source code is licensed under the ISC license.
533
694
  * See the LICENSE file in the root directory of this source tree.
534
695
  */
696
+ const MessageSquare = createLucideIcon("message-square", [["path", {
697
+ d: "M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",
698
+ key: "18887p"
699
+ }]]);
700
+ /**
701
+ * @license lucide-react v1.39.0 - ISC
702
+ *
703
+ * This source code is licensed under the ISC license.
704
+ * See the LICENSE file in the root directory of this source tree.
705
+ */
706
+ const PanelRight = createLucideIcon("panel-right", [["rect", {
707
+ width: "18",
708
+ height: "18",
709
+ x: "3",
710
+ y: "3",
711
+ rx: "2",
712
+ key: "afitv7"
713
+ }], ["path", {
714
+ d: "M15 3v18",
715
+ key: "14nvp0"
716
+ }]]);
717
+ /**
718
+ * @license lucide-react v1.39.0 - ISC
719
+ *
720
+ * This source code is licensed under the ISC license.
721
+ * See the LICENSE file in the root directory of this source tree.
722
+ */
535
723
  const Pin = createLucideIcon("pin", [["path", {
536
724
  d: "M12 17v5",
537
725
  key: "bb1du9"
@@ -545,6 +733,106 @@ window.__ModuleLoader__.load({
545
733
  * This source code is licensed under the ISC license.
546
734
  * See the LICENSE file in the root directory of this source tree.
547
735
  */
736
+ const Search = createLucideIcon("search", [["path", {
737
+ d: "m21 21-4.34-4.34",
738
+ key: "14j7rj"
739
+ }], ["circle", {
740
+ cx: "11",
741
+ cy: "11",
742
+ r: "8",
743
+ key: "4ej97u"
744
+ }]]);
745
+ /**
746
+ * @license lucide-react v1.39.0 - ISC
747
+ *
748
+ * This source code is licensed under the ISC license.
749
+ * See the LICENSE file in the root directory of this source tree.
750
+ */
751
+ const Settings = createLucideIcon("settings", [["path", {
752
+ d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",
753
+ key: "1i5ecw"
754
+ }], ["circle", {
755
+ cx: "12",
756
+ cy: "12",
757
+ r: "3",
758
+ key: "1v7zrd"
759
+ }]]);
760
+ /**
761
+ * @license lucide-react v1.39.0 - ISC
762
+ *
763
+ * This source code is licensed under the ISC license.
764
+ * See the LICENSE file in the root directory of this source tree.
765
+ */
766
+ const SlidersHorizontal = createLucideIcon("sliders-horizontal", [
767
+ ["path", {
768
+ d: "M10 5H3",
769
+ key: "1qgfaw"
770
+ }],
771
+ ["path", {
772
+ d: "M12 19H3",
773
+ key: "yhmn1j"
774
+ }],
775
+ ["path", {
776
+ d: "M14 3v4",
777
+ key: "1sua03"
778
+ }],
779
+ ["path", {
780
+ d: "M16 17v4",
781
+ key: "1q0r14"
782
+ }],
783
+ ["path", {
784
+ d: "M21 12h-9",
785
+ key: "1o4lsq"
786
+ }],
787
+ ["path", {
788
+ d: "M21 19h-5",
789
+ key: "1rlt1p"
790
+ }],
791
+ ["path", {
792
+ d: "M21 5h-7",
793
+ key: "1oszz2"
794
+ }],
795
+ ["path", {
796
+ d: "M8 10v4",
797
+ key: "tgpxqk"
798
+ }],
799
+ ["path", {
800
+ d: "M8 12H3",
801
+ key: "a7s4jb"
802
+ }]
803
+ ]);
804
+ /**
805
+ * @license lucide-react v1.39.0 - ISC
806
+ *
807
+ * This source code is licensed under the ISC license.
808
+ * See the LICENSE file in the root directory of this source tree.
809
+ */
810
+ const Sparkles = createLucideIcon("sparkles", [
811
+ ["path", {
812
+ d: "M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",
813
+ key: "1s2grr"
814
+ }],
815
+ ["path", {
816
+ d: "M20 2v4",
817
+ key: "1rf3ol"
818
+ }],
819
+ ["path", {
820
+ d: "M22 4h-4",
821
+ key: "gwowj6"
822
+ }],
823
+ ["circle", {
824
+ cx: "4",
825
+ cy: "20",
826
+ r: "2",
827
+ key: "6kqj1y"
828
+ }]
829
+ ]);
830
+ /**
831
+ * @license lucide-react v1.39.0 - ISC
832
+ *
833
+ * This source code is licensed under the ISC license.
834
+ * See the LICENSE file in the root directory of this source tree.
835
+ */
548
836
  const SquarePen = createLucideIcon("square-pen", [["path", {
549
837
  d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7",
550
838
  key: "1m0v6g"
@@ -552,6 +840,41 @@ window.__ModuleLoader__.load({
552
840
  d: "M18.375 2.625a1 1 0 0 1 3 3l-9.013 9.014a2 2 0 0 1-.853.505l-2.873.84a.5.5 0 0 1-.62-.62l.84-2.873a2 2 0 0 1 .506-.852z",
553
841
  key: "ohrbg2"
554
842
  }]]);
843
+ /**
844
+ * @license lucide-react v1.39.0 - ISC
845
+ *
846
+ * This source code is licensed under the ISC license.
847
+ * See the LICENSE file in the root directory of this source tree.
848
+ */
849
+ const Store = createLucideIcon("store", [
850
+ ["path", {
851
+ d: "M15 21v-5a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v5",
852
+ key: "slp6dd"
853
+ }],
854
+ ["path", {
855
+ d: "M17.774 10.31a1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.451 0 1.12 1.12 0 0 0-1.548 0 2.5 2.5 0 0 1-3.452 0 1.12 1.12 0 0 0-1.549 0 2.5 2.5 0 0 1-3.77-3.248l2.889-4.184A2 2 0 0 1 7 2h10a2 2 0 0 1 1.653.873l2.895 4.192a2.5 2.5 0 0 1-3.774 3.244",
856
+ key: "o0xfot"
857
+ }],
858
+ ["path", {
859
+ d: "M4 10.95V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8.05",
860
+ key: "wn3emo"
861
+ }]
862
+ ]);
863
+ /**
864
+ * @license lucide-react v1.39.0 - ISC
865
+ *
866
+ * This source code is licensed under the ISC license.
867
+ * See the LICENSE file in the root directory of this source tree.
868
+ */
869
+ const User = createLucideIcon("user", [["path", {
870
+ d: "M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2",
871
+ key: "975kel"
872
+ }], ["circle", {
873
+ cx: "12",
874
+ cy: "7",
875
+ r: "4",
876
+ key: "17ys0d"
877
+ }]]);
555
878
  //#endregion
556
879
  //#region src/client/session-tree.tsx
557
880
  function PinIcon() {
@@ -5257,15 +5580,18 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5257
5580
  const next = `${width}px ${tracks.middle} ${tracks.details}px`;
5258
5581
  const changed = frame.style.gridTemplateColumns !== next;
5259
5582
  if (changed) frame.style.gridTemplateColumns = next;
5583
+ const contentWidth = `${width}px`;
5584
+ if (frame.style.getPropertyValue("--dcu-sidebar-expanded-width") !== contentWidth) frame.style.setProperty("--dcu-sidebar-expanded-width", contentWidth);
5260
5585
  const handle = frame.querySelector("[data-side=\"sidebar\"]");
5261
- if (handle !== null) handle.style.left = `${width}px`;
5586
+ if (handle !== null && handle.style.left !== contentWidth) handle.style.left = contentWidth;
5262
5587
  return changed;
5263
5588
  }
5264
5589
  function applySlimSidebar(frame) {
5265
5590
  if (frame.hasAttribute("data-dragging")) return false;
5266
5591
  if (parseSidebarGrid(frame.style.gridTemplateColumns) === void 0 || frame.hasAttribute("data-sidebar-collapsed")) return false;
5267
- const changed = applySidebarWidth(frame, frame.hasAttribute("data-dcu-codex-sidebar-initialized") ? visibleSidebarWidths.get(frame) ?? 240 : 240);
5268
- frame.setAttribute("data-dcu-codex-sidebar-initialized", "");
5592
+ const initialized = frame.hasAttribute("data-dcu-codex-sidebar-initialized");
5593
+ const changed = applySidebarWidth(frame, initialized ? visibleSidebarWidths.get(frame) ?? 240 : 240);
5594
+ if (!initialized) frame.setAttribute("data-dcu-codex-sidebar-initialized", "");
5269
5595
  return changed;
5270
5596
  }
5271
5597
  /** 仅在首帧覆盖宿主默认宽度时关闭过渡,避免刷新出现收缩动画。 */
@@ -5291,7 +5617,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5291
5617
  frameObserver?.disconnect();
5292
5618
  frame = next;
5293
5619
  if (frame === void 0) return;
5294
- frameObserver = new MutationObserver(schedule);
5620
+ frameObserver = new MutationObserver(apply);
5295
5621
  frameObserver.observe(frame, {
5296
5622
  attributes: true,
5297
5623
  attributeFilter: [
@@ -5391,7 +5717,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5391
5717
  //#region src/client/CodexSidebar.tsx
5392
5718
  const subscribeEmptyCompanionTabs = () => () => {};
5393
5719
  const getEmptyCompanionTabs = () => EMPTY_COMPANION_TABS;
5394
- const SIDEBAR_COLLAPSE_SETTLE_MS = 140;
5720
+ const SIDEBAR_COLLAPSE_SETTLE_MS = 500;
5395
5721
  const SIDEBAR_EXPANSION_STORAGE_KEY = "dsh-codex-ui.sidebar-expansion.v1";
5396
5722
  const EXTENSIONS_EXPANSION_KEY = "extensions";
5397
5723
  function readExtensionsOpen() {
@@ -5410,14 +5736,14 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5410
5736
  /* 滤镜只作用于背景,避免为设置和搜索等 fixed 后代创建侧栏包含块。 */
5411
5737
  body[data-we-sidebar-glass] .dcu-root{position:relative;background:transparent}body[data-we-sidebar-glass] .dcu-root::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background-color:color-mix(in srgb,var(--we-sidebar-color,#fff) calc(var(--we-sidebar-alpha,.15)*.66*100%),transparent);background-image:linear-gradient(180deg,rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.14)),rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.04)) 38%,rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.01)));-webkit-backdrop-filter:blur(var(--we-sidebar-blur,16px)) saturate(var(--we-sidebar-saturate,1.8)) brightness(var(--we-glass-brightness,1.04)) contrast(1.01);backdrop-filter:blur(var(--we-sidebar-blur,16px)) saturate(var(--we-sidebar-saturate,1.8)) brightness(var(--we-glass-brightness,1.04)) contrast(1.01);box-shadow:inset 0 1px 0 rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.32)),inset 0 -1px 0 rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.08)),inset 0 0 0 .5px rgba(255,255,255,calc(var(--we-sidebar-sheen,1)*.06))}body[data-ds-dark-theme][data-we-sidebar-glass] .dcu-root::before{background-color:color-mix(in srgb,var(--we-sidebar-color,#fff) calc(var(--we-sidebar-alpha,.15)*.33*100%),transparent)}body[data-we-appwindow][data-we-sidebar-glass] .dcu-root::before{-webkit-backdrop-filter:none;backdrop-filter:none}@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){body[data-we-sidebar-glass] .dcu-root{background:#eef7f5}body[data-ds-dark-theme][data-we-sidebar-glass] .dcu-root{background:#1d2120}body[data-we-sidebar-glass] .dcu-root::before{display:none}}
5412
5738
  body[data-we-sidebar-glass] .dcu-expanded-shell,body[data-we-sidebar-glass] .dcu-compact-shell,body[data-we-sidebar-glass] .dcu-foot{position:relative}
5413
- .dcu-expanded-shell{display:flex;width:100%;min-height:0;flex:1 1 0;overflow:hidden;flex-direction:column;transform-origin:left center;transition:opacity 140ms ease-out,transform 180ms cubic-bezier(.16,1,.3,1);animation:dcu-sidebar-expanded-in 180ms cubic-bezier(.16,1,.3,1)}.dcu-compact-shell{display:none;width:56px}.dcu-root.dcu-collapsing .dcu-expanded-shell{opacity:0;transform:translateX(-6px);pointer-events:none}.dcu-root.dcu-compact .dcu-expanded-shell{display:none}.dcu-root.dcu-compact .dcu-compact-shell{display:flex;min-height:0;flex:1;flex-direction:column;align-items:center;animation:dcu-sidebar-compact-in 140ms ease-out}@keyframes dcu-sidebar-expanded-in{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}@keyframes dcu-sidebar-compact-in{from{opacity:0;transform:translateX(-4px)}to{opacity:1;transform:none}}
5739
+ .dcu-expanded-shell{display:flex;width:100%;min-height:0;flex:1 1 0;overflow:hidden;flex-direction:column;transform-origin:left center;transition:opacity 500ms cubic-bezier(.16,1,.3,1),transform 500ms cubic-bezier(.16,1,.3,1);animation:dcu-sidebar-expanded-in 500ms cubic-bezier(.16,1,.3,1)}.dcu-compact-shell{display:none;width:56px}.dcu-root.dcu-collapsing .dcu-expanded-shell{opacity:0;transform:translateX(-6px);pointer-events:none}.dcu-root.dcu-compact .dcu-expanded-shell{display:none}.dcu-root.dcu-compact .dcu-compact-shell{display:flex;min-height:0;flex:1;flex-direction:column;align-items:center;animation:dcu-sidebar-compact-in 140ms ease-out}@keyframes dcu-sidebar-expanded-in{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}@keyframes dcu-sidebar-compact-in{from{opacity:0;transform:translateX(-4px)}to{opacity:1;transform:none}}
5414
5740
  .dcu-root *{box-sizing:border-box}.dcu-head{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:8px;height:60px;padding:8px 8px 8px 12px}.dcu-brand{border:0;background:transparent;color:inherit;padding:0;display:flex;align-items:center;min-width:0;overflow:hidden}.dcu-brand svg{display:block;width:auto;max-width:100%;height:24px;min-width:0}.dcu-head-actions{display:grid;grid-auto-flow:column;grid-auto-columns:28px;align-items:center;column-gap:8px;height:28px}
5415
5741
  .dcu-icon,.dcu-menu button,.dcu-footer-link{appearance:none;border:0;background:transparent;color:inherit;font:inherit;cursor:pointer}.dcu-icon{display:grid;place-items:center;width:36px;height:36px;border-radius:8px;color:var(--dcu-sidebar-icon)}.dcu-head .dcu-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin:0;padding:0;border-radius:50%;line-height:0}.dcu-head .dcu-icon svg{display:block;width:16px;height:16px}
5416
5742
  .dcu-icon:hover,.dcu-menu button:hover:not(:disabled),.dcu-footer-link:hover{background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary)}
5417
5743
  .dcu-menu{padding:0 6px 8px;display:grid;gap:2px}.dcu-menu button,.dcu-footer-link{display:grid;grid-template-columns:20px minmax(0,1fr);column-gap:8px;align-items:center;width:100%;min-height:36px;padding:0 4px;border-radius:8px;color:var(--dcu-sidebar-navigation);font-size:14px;line-height:20px;text-align:left;font-weight:400}
5418
5744
  .dcu-menu-icon{display:grid;place-items:center start;width:20px;height:20px}.dcu-menu-icon svg,.dcu-footer-link svg{display:block;width:16px;height:16px;color:var(--dcu-sidebar-icon)}.dcu-menu button:disabled{color:var(--dcu-sidebar-secondary);cursor:default;opacity:1}.dcu-menu button:disabled svg{color:var(--dcu-sidebar-secondary)}
5419
5745
  .dcu-extensions-group{display:grid}.dcu-extension-leading{position:relative;display:block;width:16px;height:16px}.dcu-extension-leading svg{position:absolute;inset:0;transition:opacity 140ms ease-out,transform 220ms cubic-bezier(.16,1,.3,1)}.dcu-extension-default-icon{opacity:1}.dcu-extension-state-arrow{opacity:0;transform:rotate(0)}.dcu-extensions-group:hover .dcu-extension-default-icon,.dcu-extensions-toggle:focus-visible .dcu-extension-default-icon{opacity:0}.dcu-extensions-group:hover .dcu-extension-state-arrow,.dcu-extensions-toggle:focus-visible .dcu-extension-state-arrow{opacity:1}.dcu-extensions-toggle[aria-expanded=true] .dcu-extension-state-arrow{transform:rotate(90deg)}.dcu-extension-panel{display:grid;grid-template-rows:1fr;opacity:1;transition:grid-template-rows 220ms cubic-bezier(.16,1,.3,1),opacity 160ms ease-out}.dcu-extension-panel[data-open=false]{grid-template-rows:0fr;opacity:0;pointer-events:none}.dcu-extension-panel-inner{position:relative;min-height:0;overflow:hidden}.dcu-extension-items{position:relative;display:grid;gap:1px;margin:1px 0 4px 28px}.dcu-extension-items::before{content:"";position:absolute;left:-16px;top:0;bottom:4px;width:1px;background:var(--dcu-sidebar-border)}.dcu-extension-items button{grid-template-columns:minmax(0,1fr);min-height:32px;color:var(--dcu-sidebar-secondary);font-size:13px;font-weight:400}.dcu-extension-items .dcu-menu-icon{display:none}
5420
- .dcu-workspaces{display:flex;min-height:0;flex:1;flex-direction:column;margin-top:2px;padding-top:8px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-workspaces.dcu-workspaces-tabs{padding-top:0;border-top:0}.dcu-im-tabs{display:flex;gap:16px;margin:0 8px 12px;padding:0;border-bottom:1px solid var(--dcu-sidebar-border)}.dcu-im-tab{appearance:none;border:0;background:transparent;color:var(--dcu-sidebar-secondary);padding:8px 0 7px;font:14px/22px var(--dcu-font);font-weight:500;cursor:pointer}.dcu-im-tab[data-on=true]{color:var(--dcu-sidebar-primary);font-weight:600;box-shadow:inset 0 -2px 0 currentColor}.dcu-native-workspaces{display:flex;min-height:0;flex:1}.dcu-native-workspaces>*{min-width:0;flex:1}.dcu-native-workspaces .ima-tabs,.dcu-native-workspaces [role=tablist]{display:none!important}.dcu-schedule-browser{display:flex;min-height:0;flex:1;flex-direction:column}.dcu-native-workspaces .dcu-schedule-views{display:flex!important;flex:none;min-height:30px;margin:0 8px 8px;padding:2px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;background:rgba(255,255,255,.025)}.dcu-schedule-views button{appearance:none;flex:1;min-width:0;height:24px;border:0;border-radius:6px;background:transparent;color:var(--dcu-sidebar-secondary);font:600 12px/18px var(--dcu-font);cursor:pointer}.dcu-schedule-views button[aria-selected=true]{background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary);box-shadow:inset 0 0 0 1px var(--dcu-sidebar-border)}.dcu-schedule-pane{display:flex;min-height:0;flex:1}.dcu-schedule-pane>*{min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]{display:flex!important;width:100%;min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]>.dsh-st-rail{width:100%;min-width:0;padding-right:8px;scrollbar-gutter:auto}.dcu-schedule-pane .dsh-st-overview{padding-right:8px}.dcu-foot{display:grid;width:100%;gap:4px;padding:8px 6px 12px;border-top:1px solid var(--dcu-sidebar-border);transition:opacity 120ms ease-out,transform 160ms cubic-bezier(.16,1,.3,1)}.dcu-root.dcu-collapsing>.dcu-foot{opacity:0;transform:translateX(-4px);pointer-events:none}.dcu-footer-actions:empty,.dcu-settings-seat:empty{display:none}.dcu-settings-seat>button{width:100%;min-height:36px;padding-left:4px!important;color:var(--dcu-sidebar-navigation);font:14px/20px var(--dcu-font);font-weight:400}.dcu-compact{width:100%;align-items:flex-start;overflow:hidden;padding:10px 0 8px}.dcu-compact-nav{display:flex;flex:1;min-height:0;flex-direction:column;align-items:center;gap:2px;overflow:auto;padding:6px 0}.dcu-compact .dcu-icon{width:36px;height:36px;flex:none}.dcu-compact .dcu-foot{width:36px;margin-top:auto;margin-left:10px;padding:8px 0;border-top:0}.dcu-compact .dcu-settings-seat{width:36px;overflow:hidden}.dcu-compact .dcu-settings-seat>button{display:grid;place-items:center;width:36px;min-height:36px;padding:0!important;font-size:0!important;line-height:0}.dcu-compact .dcu-settings-seat>button svg{width:16px;height:16px}.dcu-compact .dcu-footer-link{display:flex;justify-content:center;width:36px;padding:0;font-size:0}.dcu-compact .dcu-footer-link svg{width:16px;height:16px}
5746
+ .dcu-workspaces{display:flex;min-height:0;flex:1;flex-direction:column;margin-top:2px;padding-top:8px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-workspaces.dcu-workspaces-tabs{padding-top:0;border-top:0}.dcu-im-tabs{display:flex;gap:16px;margin:0 8px 12px;padding:0;border-bottom:1px solid var(--dcu-sidebar-border)}.dcu-im-tab{appearance:none;border:0;background:transparent;color:var(--dcu-sidebar-secondary);padding:8px 0 7px;font:14px/22px var(--dcu-font);font-weight:500;cursor:pointer}.dcu-im-tab[data-on=true]{color:var(--dcu-sidebar-primary);font-weight:600;box-shadow:inset 0 -2px 0 currentColor}.dcu-native-workspaces{display:flex;min-height:0;flex:1}.dcu-native-workspaces>*{min-width:0;flex:1}.dcu-native-workspaces .ima-tabs,.dcu-native-workspaces [role=tablist]{display:none!important}.dcu-schedule-browser{display:flex;min-height:0;flex:1;flex-direction:column}.dcu-native-workspaces .dcu-schedule-views{display:flex!important;flex:none;min-height:30px;margin:0 8px 8px;padding:2px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;background:rgba(255,255,255,.025)}.dcu-schedule-views button{appearance:none;flex:1;min-width:0;height:24px;border:0;border-radius:6px;background:transparent;color:var(--dcu-sidebar-secondary);font:600 12px/18px var(--dcu-font);cursor:pointer}.dcu-schedule-views button[aria-selected=true]{background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary);box-shadow:inset 0 0 0 1px var(--dcu-sidebar-border)}.dcu-schedule-pane{display:flex;min-height:0;flex:1}.dcu-schedule-pane>*{min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]{display:flex!important;width:100%;min-width:0;flex:1}.dcu-schedule-pane>[data-slot="sidebar.schedule"]>.dsh-st-rail{width:100%;min-width:0;padding-right:8px;scrollbar-gutter:auto}.dcu-schedule-pane .dsh-st-overview{padding-right:8px}.dcu-foot{display:grid;width:100%;gap:4px;padding:8px 6px 12px;border-top:1px solid var(--dcu-sidebar-border);transition:opacity 500ms cubic-bezier(.16,1,.3,1),transform 500ms cubic-bezier(.16,1,.3,1)}.dcu-root.dcu-collapsing>.dcu-foot{opacity:0;transform:translateX(-4px);pointer-events:none}.dcu-footer-actions:empty,.dcu-settings-seat:empty{display:none}.dcu-settings-seat>button{width:100%;min-height:36px;padding-left:4px!important;color:var(--dcu-sidebar-navigation);font:14px/20px var(--dcu-font);font-weight:400}.dcu-compact{width:100%;align-items:flex-start;overflow:hidden;padding:10px 0 8px}.dcu-compact-nav{display:flex;flex:1;min-height:0;flex-direction:column;align-items:center;gap:2px;overflow:auto;padding:6px 0}.dcu-compact .dcu-icon{width:36px;height:36px;flex:none}.dcu-compact .dcu-foot{width:36px;margin-top:auto;margin-left:10px;padding:8px 0;border-top:0}.dcu-compact .dcu-settings-seat{width:36px;overflow:hidden}.dcu-compact .dcu-settings-seat>button{display:grid;place-items:center;width:36px;min-height:36px;padding:0!important;font-size:0!important;line-height:0}.dcu-compact .dcu-settings-seat>button svg{width:16px;height:16px}.dcu-compact .dcu-footer-link{display:flex;justify-content:center;width:36px;padding:0;font-size:0}.dcu-compact .dcu-footer-link svg{width:16px;height:16px}
5421
5747
  /* 仅适配费用插件入口;通过标记及入口结构定位,保留原生统计、浮层和容器查询。 */
5422
5748
  .dcu-footer-actions [data-testid="billing-trigger"]{box-sizing:border-box;width:100%;min-width:0;min-height:52px;padding:8px 6px;gap:8px;border:0;border-radius:6px;background:transparent;color:var(--dcu-sidebar-primary);font-family:var(--dcu-font);box-shadow:none;transform:none;transition:background-color 120ms ease-out,color 120ms ease-out}
5423
5749
  .dcu-footer-actions :is([data-testid="billing-trigger"],[data-testid="billing-rail-button"]):hover{border-color:transparent;background:var(--dcu-sidebar-hover);box-shadow:none;transform:none}
@@ -5435,12 +5761,24 @@ body[data-we-sidebar-glass] .dcu-expanded-shell,body[data-we-sidebar-glass] .dcu
5435
5761
  .dcu-footer-actions [data-testid="billing-rail-button"] svg{flex:none;width:24px;height:24px;stroke-width:1.5px}
5436
5762
  .dcu-settings-seat [data-slot="settings.trigger"]{color:var(--dcu-sidebar-navigation)}
5437
5763
  .dcu-settings-seat [data-slot="settings.trigger"]>svg{color:var(--dcu-sidebar-icon)}
5438
- .dcu-root:not(.dcu-compact) .dcu-settings-seat [data-slot="settings.trigger"]>span{margin-left:4px}
5439
5764
  @media (prefers-reduced-motion:reduce){.dcu-footer-actions :is([data-testid="billing-trigger"],[data-testid="billing-rail-button"]){transition:none}}
5440
- .dcu-expanded-shell,.dcu-foot{width:100%}
5765
+ /* 宿主列负责缩放,宽态内容保持展开宽度,避免中文竖排与工作区逐帧重排。 */
5766
+ .dcu-expanded-shell,.dcu-root:not(.dcu-compact)>.dcu-foot{width:var(--dcu-sidebar-expanded-width,240px);flex-shrink:0}
5767
+ /* 对齐 Codex 的半秒布局节奏;显式声明避免依赖宿主主题的动画 token。 */
5768
+ .dcu-root{position:relative}
5769
+ .dcu-root.dcu-collapsing .dcu-compact-shell{position:absolute;left:0;top:10px;bottom:8px;display:flex;flex-direction:column;align-items:center;animation:dcu-sidebar-compact-in 500ms cubic-bezier(.16,1,.3,1)}
5770
+ .dcu-root.dcu-collapsing .dcu-compact-shell .dcu-icon{width:36px;height:36px;flex:none}
5771
+ /* 收尾仅移除宽态层,窄轨不重复淡入,否则会在半秒处闪烁。 */
5772
+ .dcu-root.dcu-compact .dcu-compact-shell{animation:none}
5773
+ [data-dcu-codex-sidebar-initialized]{transition:grid-template-columns 500ms cubic-bezier(.16,1,.3,1)}
5774
+ /* dsh-better-sidebar 的 #root 布局规则会覆盖 transition 简写;合并两侧过渡而非只争抢左栏。 */
5775
+ #root [data-dcu-codex-sidebar-initialized]:not([data-dragging]){transition:grid-template-columns 500ms cubic-bezier(.16,1,.3,1),padding-right var(--ds-transition-duration-slow,.3s) var(--ds-ease-in-out,cubic-bezier(.4,0,.2,1))}
5776
+ #root [data-dcu-codex-sidebar-initialized][data-dragging]{transition:none}
5777
+ [data-dcu-codex-sidebar-initialized] [data-side="sidebar"]{transition:left 500ms cubic-bezier(.16,1,.3,1)}
5778
+ [data-dcu-codex-sidebar-initialized][data-dragging],[data-dcu-codex-sidebar-initialized][data-dragging] [data-side="sidebar"]{transition:none}
5779
+ @media (prefers-reduced-motion:reduce){[data-dcu-codex-sidebar-initialized],[data-dcu-codex-sidebar-initialized] [data-side="sidebar"],#root [data-dcu-codex-sidebar-initialized]:not([data-dragging]){transition:none}.dcu-root.dcu-collapsing .dcu-compact-shell{animation:none}}
5441
5780
  .dcu-native-workspaces{flex-direction:column}.dcu-native-workspaces>[data-mcp-connector-top-mount=true]{flex:none}.dcu-root .mcpConnectorLauncher,.dcu-root [data-mcp-connector-top-mount=true]{display:none!important}
5442
5781
  .dcu-dependency-notice{margin:0 10px 8px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;padding:8px;color:var(--dcu-sidebar-secondary);font-size:12px;line-height:18px}
5443
- [role="dialog"][aria-labelledby]{width:min(1000px,calc(100vw - 48px));max-width:calc(100vw - 48px);height:min(800px,calc(100vh - 48px))}
5444
5782
  .dcu-search-scrim{position:fixed;z-index:10020;inset:0;display:flex;justify-content:center;align-items:flex-start;padding:72px 20px;background:color-mix(in srgb,#000 48%,transparent);animation:dcu-search-scrim-in 140ms ease-out}.dcu-search-dialog{width:min(560px,100%);max-height:min(640px,calc(100vh - 120px));overflow:auto;border:1px solid var(--dcu-sidebar-border);border-radius:16px;padding:10px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv4);animation:dcu-search-dialog-in 180ms cubic-bezier(.16,1,.3,1)}@keyframes dcu-search-scrim-in{from{opacity:0}to{opacity:1}}@keyframes dcu-search-dialog-in{from{opacity:0;transform:translateY(-6px) scale(.985)}to{opacity:1}}.dcu-search-input{margin-bottom:8px}.dcu-search-section{padding:6px 0}.dcu-search-title{padding:0 8px 4px;color:var(--dcu-sidebar-tertiary);font-size:12px;font-weight:600}.dcu-search-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;width:100%;min-height:34px;border:0;border-radius:8px;padding:6px 8px;background:transparent;color:var(--dcu-sidebar-primary);font:inherit;text-align:left;cursor:pointer}.dcu-search-row:hover,.dcu-search-row[data-active=true]{background:var(--dcu-sidebar-hover)}.dcu-search-main{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-search-detail{max-width:160px;overflow:hidden;color:var(--dcu-sidebar-tertiary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.dcu-search-empty{padding:18px 8px;color:var(--dcu-sidebar-tertiary);font-size:13px}@media (prefers-reduced-motion:reduce){.dcu-expanded-shell,.dcu-root.dcu-compact .dcu-compact-shell,.dcu-foot,.dcu-search-scrim,.dcu-search-dialog,.dcu-extension-panel,.dcu-extension-leading svg{animation:none;transition:none}}
5445
5783
  [data-conversation-scroll]{--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:24px}[data-conversation-scroll] [data-composer-card]{min-height:96px;padding-top:10px;border-radius:16px;box-shadow:var(--dsw-shadow-lv3);transition:border-color 180ms ease,box-shadow 180ms ease}[data-conversation-scroll] [data-composer-card]:focus-within{border-color:var(--dsw-alias-button-info-fill);box-shadow:0 0 0 2px var(--dsw-static-deepseek-50),var(--dsw-shadow-lv3)}[data-conversation-scroll] [data-input-mirror]{min-height:44px}@media (prefers-reduced-motion:reduce){[data-conversation-scroll] [data-composer-card]{transition:none}}
5446
5784
  html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:has([data-dcu-official-turn-navigator]) .dcu-turn-navigator{display:none}
@@ -5528,7 +5866,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
5528
5866
  t
5529
5867
  ]);
5530
5868
  const openSettings = (0, react.useCallback)(() => {
5531
- settingsSeat.current?.querySelector("[aria-haspopup=\"dialog\"]")?.click();
5869
+ openSettingsRoot(settingsSeat.current);
5532
5870
  }, [settingsSeat]);
5533
5871
  const entries = (0, react.useMemo)(() => {
5534
5872
  const archived = new Set(workspaces.archivedSessionIds);
@@ -6839,6 +7177,23 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
6839
7177
  /** 本插件独占的界面文案命名空间。 */
6840
7178
  const NS = "michengai.codexUi";
6841
7179
  const zh = {
7180
+ "settings.title": "设置",
7181
+ "settings.back": "返回应用",
7182
+ "settings.openDocument": "打开配置文件",
7183
+ "settings.openDocumentError": "无法打开配置文件",
7184
+ "settings.search": "搜索设置…",
7185
+ "settings.personal": "个人",
7186
+ "settings.integrations": "集成",
7187
+ "settings.records": "记录与应用",
7188
+ "settings.general": "常规",
7189
+ "settings.permissions": "权限",
7190
+ "settings.editor": "编辑器",
7191
+ "settings.noResults": "没有匹配的设置分类",
7192
+ "settings.filterHint": "仅筛选导航,选择分类后切换当前页面。",
7193
+ "settings.disconnected": "连接异常",
7194
+ "settings.reconnect": "立即重连",
7195
+ "settings.connecting": "连接中",
7196
+ "settings.recovered": "连接成功",
6842
7197
  "input.historyHint": "↑↓ 翻历史",
6843
7198
  "sidebar.label": "DSH 导航",
6844
7199
  "sidebar.expand": "展开侧边栏",
@@ -7051,6 +7406,23 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
7051
7406
  "meta.locale": "zh-CN"
7052
7407
  };
7053
7408
  const en = {
7409
+ "settings.title": "Settings",
7410
+ "settings.back": "Back to app",
7411
+ "settings.openDocument": "Open configuration file",
7412
+ "settings.openDocumentError": "Could not open configuration file",
7413
+ "settings.search": "Search settings…",
7414
+ "settings.personal": "Personal",
7415
+ "settings.integrations": "Integrations",
7416
+ "settings.records": "Records and app",
7417
+ "settings.general": "General",
7418
+ "settings.permissions": "Permissions",
7419
+ "settings.editor": "Editor",
7420
+ "settings.noResults": "No matching settings categories",
7421
+ "settings.filterHint": "Navigation is filtered. Select a category to switch pages.",
7422
+ "settings.disconnected": "Disconnected",
7423
+ "settings.reconnect": "Reconnect now",
7424
+ "settings.connecting": "Connecting",
7425
+ "settings.recovered": "Connected",
7054
7426
  "input.historyHint": "↑↓ History",
7055
7427
  "sidebar.label": "DSH navigation",
7056
7428
  "sidebar.expand": "Expand sidebar",
@@ -7397,6 +7769,600 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
7397
7769
  };
7398
7770
  }
7399
7771
  //#endregion
7772
+ //#region src/client/settings-page-model.ts
7773
+ function settingsGroup(id) {
7774
+ if (/archive|about/.test(id)) return "records";
7775
+ if (/^(general|appearance|theme|language|shortcuts|voice|account)$/.test(id)) return "personal";
7776
+ return "integrations";
7777
+ }
7778
+ function filterSettingsRows(rows, query) {
7779
+ const needle = query.trim().toLocaleLowerCase();
7780
+ return needle === "" ? rows : rows.filter((row) => `${row.label} ${row.id}`.toLocaleLowerCase().includes(needle));
7781
+ }
7782
+ function generalItemGroup(id) {
7783
+ if (/permission|approval|sandbox/.test(id)) return "permissions";
7784
+ if (/composer|font|conversation|chat|enter/.test(id)) return "editor";
7785
+ return "general";
7786
+ }
7787
+ //#endregion
7788
+ //#region src/client/settings-page-styles.ts
7789
+ /** Codex 设置页的局部 tokens 与布局,不覆盖宿主其他弹窗。 */
7790
+ const settingsPageStyles = `
7791
+ .dcu-settings-page{--sp-bg:#fff;--sp-nav:#f5f5f5;--sp-card:#fafafa;--sp-border:#e5e5e5;--sp-text:#303030;--sp-muted:#737373;--sp-hover:#e9e9e9;--sp-active:#e4e4e4;position:fixed;inset:0;z-index:1000;display:grid;grid-template-columns:240px minmax(0,1fr);background:var(--sp-bg);color:var(--sp-text);font:14px/1.5 var(--dcu-font,system-ui);text-align:left;isolation:isolate}
7792
+ body[data-ds-dark-theme] .dcu-settings-page{--sp-bg:#181818;--sp-nav:#202322;--sp-card:#232323;--sp-border:#333;--sp-text:#dedede;--sp-muted:#a1a1a1;--sp-hover:#292c2b;--sp-active:#303332;color-scheme:dark}
7793
+ .dcu-settings-page *{box-sizing:border-box}
7794
+ .dcu-settings-page button,.dcu-settings-page input{font:inherit}
7795
+ .dcu-settings-page button{cursor:pointer}
7796
+ .dcu-settings-page :focus-visible{outline:2px solid #459cff;outline-offset:3px}
7797
+ .dcu-settings-nav{display:flex;flex-direction:column;min-height:0;padding:18px 8px;background:var(--sp-nav);border-right:1px solid var(--sp-border);overflow-y:auto}
7798
+ .dcu-settings-back{display:flex;align-items:center;gap:8px;width:100%;padding:8px;border:0;border-radius:7px;background:transparent;color:var(--sp-text);text-align:left}
7799
+ .dcu-settings-back:hover,.dcu-settings-link:hover{background:var(--sp-hover)}
7800
+ .dcu-settings-search{display:flex;align-items:center;gap:8px;padding:5px 9px;margin:12px 0 18px;background:var(--sp-hover);border:1px solid transparent;border-radius:8px;color:var(--sp-muted)}
7801
+ .dcu-settings-search:focus-within{border-color:#459cff}
7802
+ .dcu-settings-search input{width:100%;min-width:0;border:0;background:transparent;color:var(--sp-text);outline:none;font-size:13px}
7803
+ .dcu-settings-search input[type=search]{appearance:none;padding:0;border-radius:0;box-shadow:none;line-height:20px}
7804
+ .dcu-settings-search input:focus,.dcu-settings-search input:focus-visible{outline:none;box-shadow:none}
7805
+ .dcu-settings-search input::placeholder{color:var(--sp-muted)}
7806
+ .dcu-settings-group{margin:0 0 22px}
7807
+ .dcu-settings-group-label{margin:0 8px 6px;color:var(--sp-muted);font-size:12px;font-weight:500}
7808
+ .dcu-settings-link{display:flex;align-items:center;gap:9px;min-height:32px;width:100%;padding:5px 9px;border:0;border-radius:8px;background:transparent;color:var(--sp-text);text-align:left;font-size:14px!important}
7809
+ .dcu-settings-link[aria-current=page]{background:var(--sp-active)}
7810
+ .dcu-settings-link svg{flex:none;opacity:.9}
7811
+ .dcu-settings-link span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
7812
+ .dcu-settings-empty{padding:8px;color:var(--sp-muted);font-size:13px}
7813
+ .dcu-settings-main{min-width:0;min-height:0;overflow:auto;overscroll-behavior:contain;background:var(--sp-bg);scrollbar-width:thin;scrollbar-color:var(--sp-border) transparent}
7814
+ .dcu-settings-inner{width:min(100%,864px);margin:0 auto;padding:32px 48px}
7815
+ .dcu-settings-heading{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-bottom:24px}
7816
+ .dcu-settings-heading h1{margin:0;font-size:24px;line-height:32px;font-weight:600;letter-spacing:-.4px}
7817
+ .dcu-settings-heading[data-own-title=false]{justify-content:flex-end;margin-bottom:16px}
7818
+ .dcu-settings-heading:not(:has(h1,button,a,[role=button])){display:none}
7819
+ .dcu-settings-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;color:var(--sp-muted)}
7820
+ .dcu-settings-actions button{font-size:12px}
7821
+ .dcu-settings-general-group{margin-bottom:44px}
7822
+ .dcu-settings-general-group h2{margin:0 0 16px;font-size:14px;font-weight:600;color:var(--sp-text)}
7823
+ .dcu-settings-card{border:1px solid var(--sp-border);border-radius:16px;background:var(--sp-card);padding:0 16px;overflow:hidden}
7824
+ .dcu-settings-row+.dcu-settings-row{border-top:1px solid var(--sp-border)}
7825
+ .dcu-settings-row>[data-slot]{display:contents}
7826
+ .dcu-settings-row>[data-slot]>*{padding:12px 0!important;border-bottom:0!important;margin:0!important;min-width:0}
7827
+ .dcu-settings-row button{font-size:13px;border-radius:8px}
7828
+ .dcu-settings-row input{max-width:100%}
7829
+ .dcu-settings-trigger{appearance:none;box-sizing:border-box;display:flex;align-items:center;border:0;border-radius:8px;background:transparent;color:var(--dcu-sidebar-navigation,inherit);height:36px;min-height:36px;padding:0 4px;width:100%;font:400 14px/20px var(--dcu-font,system-ui);text-align:left;cursor:pointer;transition:background-color 160ms ease,color 160ms ease,transform 120ms ease}
7830
+ .dcu-settings-trigger-content{display:grid;grid-template-columns:20px minmax(0,1fr);column-gap:8px;align-items:center;width:100%;min-width:0}
7831
+ .dcu-settings-trigger-content svg{display:block;width:16px;height:16px;color:var(--dcu-sidebar-icon,currentColor);transition:transform 220ms cubic-bezier(.16,1,.3,1)}
7832
+ .dcu-settings-trigger:hover{background:var(--dcu-sidebar-hover,rgba(127,127,127,.12));color:var(--dcu-sidebar-primary,inherit)}
7833
+ .dcu-settings-trigger:hover svg{transform:rotate(18deg)}
7834
+ .dcu-settings-trigger:active{transform:scale(.98)}
7835
+ .dcu-settings-trigger:focus-visible{outline:2px solid #459cff;outline-offset:2px;background:var(--dcu-sidebar-hover,rgba(127,127,127,.12))}
7836
+ .dcu-settings-trigger[data-wide=false]{justify-content:center;width:36px;padding:0!important}
7837
+ .dcu-settings-trigger[data-wide=false] .dcu-settings-trigger-content{grid-template-columns:16px;justify-content:center}
7838
+ .dcu-settings-page{animation:dcu-settings-enter 180ms ease-out}
7839
+ .dcu-settings-nav{animation:dcu-settings-nav-enter 220ms cubic-bezier(.16,1,.3,1)}
7840
+ .dcu-settings-inner{animation:dcu-settings-content-enter 240ms cubic-bezier(.16,1,.3,1)}
7841
+ .dcu-settings-back,.dcu-settings-link{transition:background-color 160ms ease,color 160ms ease}
7842
+ @keyframes dcu-settings-enter{from{opacity:0}to{opacity:1}}
7843
+ @keyframes dcu-settings-nav-enter{from{opacity:0;transform:translateX(-6px)}to{opacity:1;transform:none}}
7844
+ @keyframes dcu-settings-content-enter{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
7845
+ @media(prefers-reduced-motion:reduce){.dcu-settings-trigger,.dcu-settings-trigger-content svg,.dcu-settings-back,.dcu-settings-link{transition:none}.dcu-settings-trigger:hover svg,.dcu-settings-trigger:active{transform:none}.dcu-settings-page,.dcu-settings-nav,.dcu-settings-inner{animation:none}}
7846
+ .dcu-settings-page [data-slot="settings.section"]{min-width:0}
7847
+ .dcu-settings-inner:has(.dcu-connector-frame){height:100%;display:flex;flex-direction:column}
7848
+ .dcu-settings-inner:has(.dcu-connector-frame)>.dcu-settings-heading{flex:none}
7849
+ .dcu-settings-page .dcu-connectors:has(>.dcu-connector-frame){display:flex;flex-direction:column;flex:1 1 0;min-height:0}
7850
+ .dcu-settings-page .dcu-connector-frame{flex:1 1 0;min-height:0;height:100%}
7851
+
7852
+ @media(max-width:900px){.dcu-settings-page{grid-template-columns:200px minmax(0,1fr)}.dcu-settings-inner{padding:24px 28px}.dcu-settings-heading{align-items:flex-start;flex-direction:column;gap:12px}}
7853
+ @media(max-width:600px){.dcu-settings-page{grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr)}.dcu-settings-nav{padding:8px 12px;max-height:220px;border-right:0;border-bottom:1px solid var(--sp-border)}.dcu-settings-search{margin:6px 0}.dcu-settings-groups{display:flex;gap:8px;overflow-x:auto;flex:none}.dcu-settings-group{display:flex;gap:4px;margin:0;flex:none}.dcu-settings-group-label{display:none}.dcu-settings-link{width:auto;min-height:40px;flex:none}.dcu-settings-inner{padding:24px 16px}.dcu-settings-heading{margin-bottom:28px}.dcu-settings-heading h1{font-size:22px}.dcu-settings-card{padding:0 12px}.dcu-settings-row>[data-slot]>*{flex-wrap:wrap;gap:12px!important}.dcu-settings-general-group{margin-bottom:32px}}
7854
+ `;
7855
+ //#endregion
7856
+ //#region src/client/settings-focus.ts
7857
+ /** 设置页与宿主浮层共享的可交互判断,忽略隐藏及已被隔离的对话框。 */
7858
+ function settingsElementAvailable(element) {
7859
+ for (let node = element; node !== null; node = node.parentElement) {
7860
+ const style = getComputedStyle(node);
7861
+ if (node.inert || node.hidden || node.getAttribute("aria-hidden") === "true" || style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") return false;
7862
+ }
7863
+ return true;
7864
+ }
7865
+ function settingsOverlays(selector = "[role=\"dialog\"],[role=\"alertdialog\"],[role=\"menu\"],[role=\"listbox\"]") {
7866
+ return [...document.querySelectorAll(selector)].filter(settingsElementAvailable);
7867
+ }
7868
+ //#endregion
7869
+ //#region src/client/CodexSettingsPage.tsx
7870
+ const groupLabels = {
7871
+ personal: "settings.personal",
7872
+ integrations: "settings.integrations",
7873
+ records: "settings.records",
7874
+ permissions: "settings.permissions",
7875
+ general: "settings.general",
7876
+ editor: "settings.editor"
7877
+ };
7878
+ function sectionIcon(id) {
7879
+ if (id === "market" || id === "plugin-marketplace") return Store;
7880
+ if (id === "better-sidebar" || id === "sidebar-cards") return PanelRight;
7881
+ if (/model/.test(id)) return Cpu;
7882
+ if (/archive/.test(id)) return Archive;
7883
+ if (/about/.test(id)) return CircleQuestionMark;
7884
+ if (/expert|agency/.test(id)) return User;
7885
+ if (/skill/.test(id)) return Sparkles;
7886
+ if (/connector|mcp/.test(id)) return Link;
7887
+ if (/schedule|automation/.test(id)) return Clock;
7888
+ if (/im|assistant/.test(id)) return MessageSquare;
7889
+ if (id === "general") return Settings;
7890
+ if (/plugin/.test(id)) return SlidersHorizontal;
7891
+ return Box;
7892
+ }
7893
+ /** 独立设置视图复用原始 section/close 合约,退出时保留底层会话与输入状态。 */
7894
+ function CodexSettingsPage({ wide, sections, onboarding, connectionState, reconnect, useSessions, renderSlot, t }) {
7895
+ const rows = (0, react.useSyncExternalStore)(sections.subscribe, sections.getSnapshot);
7896
+ const steps = (0, react.useSyncExternalStore)(onboarding.subscribe, onboarding.getSnapshot);
7897
+ const connection = (0, react.useSyncExternalStore)(connectionState.subscribe, connectionState.getSnapshot);
7898
+ const onboardingActive = useSessions((state) => state.phase === "ready" && (state.current === void 0 || state.byId[state.current]?.blank === true));
7899
+ const [completed, setCompleted] = (0, react.useState)(() => /* @__PURE__ */ new Set());
7900
+ const [open, setOpen] = (0, react.useState)(false);
7901
+ const [activeId, setActiveId] = (0, react.useState)("general");
7902
+ const [query, setQuery] = (0, react.useState)("");
7903
+ const [recovered, setRecovered] = (0, react.useState)(false);
7904
+ const previousConnection = (0, react.useRef)(connection);
7905
+ const trigger = (0, react.useRef)(null);
7906
+ const page = (0, react.useRef)(null);
7907
+ const back = (0, react.useRef)(null);
7908
+ const onboardingRoot = (0, react.useRef)(null);
7909
+ const main = (0, react.useRef)(null);
7910
+ const wasOpen = (0, react.useRef)(false);
7911
+ const exitAnimation = (0, react.useRef)(null);
7912
+ const active = rows.find((row) => row.id === activeId) ?? rows[0];
7913
+ const step = onboardingActive ? steps.find((item) => !completed.has(item.id)) : void 0;
7914
+ const close = (0, react.useCallback)(() => {
7915
+ if (exitAnimation.current !== null) return;
7916
+ const finish = () => {
7917
+ exitAnimation.current = null;
7918
+ setOpen(false);
7919
+ setQuery("");
7920
+ };
7921
+ const element = page.current;
7922
+ if (element?.animate === void 0 || window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) {
7923
+ finish();
7924
+ return;
7925
+ }
7926
+ const animation = element.animate([{ opacity: getComputedStyle(element).opacity }, { opacity: 0 }], {
7927
+ duration: 140,
7928
+ easing: "ease-out",
7929
+ fill: "forwards"
7930
+ });
7931
+ exitAnimation.current = animation;
7932
+ animation.onfinish = finish;
7933
+ }, []);
7934
+ const openSection = (0, react.useCallback)((id) => {
7935
+ exitAnimation.current?.cancel();
7936
+ exitAnimation.current = null;
7937
+ setActiveId(id);
7938
+ setOpen(true);
7939
+ }, []);
7940
+ (0, react.useEffect)(() => () => {
7941
+ exitAnimation.current?.cancel();
7942
+ }, []);
7943
+ (0, react.useEffect)(() => {
7944
+ if (!onboardingActive) setCompleted(/* @__PURE__ */ new Set());
7945
+ }, [onboardingActive]);
7946
+ (0, react.useEffect)(() => {
7947
+ const previous = previousConnection.current;
7948
+ previousConnection.current = connection;
7949
+ setRecovered(connection === "connected" && (previous === "disconnected" || previous === "connecting"));
7950
+ if (connection !== "connected") return;
7951
+ const timer = window.setTimeout(() => {
7952
+ setRecovered(false);
7953
+ }, 3e3);
7954
+ return () => {
7955
+ window.clearTimeout(timer);
7956
+ };
7957
+ }, [connection]);
7958
+ (0, react.useEffect)(() => {
7959
+ if (wasOpen.current && !open) trigger.current?.focus();
7960
+ wasOpen.current = open;
7961
+ if (!open || page.current === null) return;
7962
+ if (settingsElementAvailable(page.current) && settingsOverlays().length === 0) back.current?.focus();
7963
+ const hidden = /* @__PURE__ */ new Map();
7964
+ const guideModals = step === void 0 ? [] : settingsOverlays("[role=\"dialog\"][aria-modal=\"true\"],[role=\"alertdialog\"][aria-modal=\"true\"]");
7965
+ const isolate = (element) => {
7966
+ if (element === onboardingRoot.current || guideModals.includes(element)) return;
7967
+ if (guideModals.some((modal) => element.contains(modal))) {
7968
+ for (const child of element.children) if (child instanceof HTMLElement && !/^(STYLE|SCRIPT|LINK)$/.test(child.tagName)) isolate(child);
7969
+ return;
7970
+ }
7971
+ hidden.set(element, element.inert);
7972
+ element.inert = true;
7973
+ };
7974
+ let branch = page.current;
7975
+ while (branch.parentElement !== null) {
7976
+ for (const sibling of branch.parentElement.children) {
7977
+ if (!(sibling instanceof HTMLElement) || sibling === branch || /^(STYLE|SCRIPT|LINK)$/.test(sibling.tagName)) continue;
7978
+ isolate(sibling);
7979
+ }
7980
+ branch = branch.parentElement;
7981
+ if (branch === document.body) break;
7982
+ }
7983
+ const onKeyDown = (event) => {
7984
+ if (event.key === "Escape" && !event.defaultPrevented && settingsOverlays().length === 0) {
7985
+ event.preventDefault();
7986
+ close();
7987
+ }
7988
+ };
7989
+ const keepFocus = (event) => {
7990
+ const target = event.target;
7991
+ if (!(target instanceof Node) || page.current === null || !settingsElementAvailable(page.current)) return;
7992
+ if (page.current.contains(target) || onboardingRoot.current?.contains(target) || settingsOverlays().some((overlay) => overlay.contains(target))) return;
7993
+ back.current?.focus();
7994
+ };
7995
+ const wrapFocus = (event) => {
7996
+ if (event.key !== "Tab" || event.defaultPrevented || page.current === null || !settingsElementAvailable(page.current) || settingsOverlays().length > 0) return;
7997
+ const items = [page.current, onboardingRoot.current].filter((root) => root !== null).flatMap((root) => [...root.querySelectorAll("button,input,select,textarea,a[href],[tabindex]")]).filter((element) => element.tabIndex >= 0 && !element.matches(":disabled") && settingsElementAvailable(element));
7998
+ const next = event.shiftKey ? items.at(-1) : items[0];
7999
+ if (document.activeElement === (event.shiftKey ? items[0] : items.at(-1))) {
8000
+ event.preventDefault();
8001
+ next?.focus();
8002
+ }
8003
+ };
8004
+ document.addEventListener("keydown", onKeyDown, true);
8005
+ document.addEventListener("keydown", wrapFocus);
8006
+ document.addEventListener("focusin", keepFocus);
8007
+ return () => {
8008
+ document.removeEventListener("keydown", onKeyDown, true);
8009
+ document.removeEventListener("keydown", wrapFocus);
8010
+ document.removeEventListener("focusin", keepFocus);
8011
+ for (const [element, inert] of hidden) element.inert = inert;
8012
+ };
8013
+ }, [
8014
+ open,
8015
+ close,
8016
+ step?.id
8017
+ ]);
8018
+ (0, react.useEffect)(() => {
8019
+ if (main.current !== null) main.current.scrollTop = 0;
8020
+ }, [active?.id]);
8021
+ const visible = filterSettingsRows(rows, query);
8022
+ const connectionIndicator = connection === "disconnected" ? "disconnected" : connection === "connecting" ? "connecting" : recovered ? "recovered" : void 0;
8023
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
8024
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: settingsPageStyles }),
8025
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8026
+ ref: trigger,
8027
+ type: "button",
8028
+ className: "dcu-settings-trigger",
8029
+ "data-dcu-settings-trigger": true,
8030
+ "data-wide": wide,
8031
+ "aria-expanded": open,
8032
+ "aria-label": t("settings.title"),
8033
+ onClick: () => {
8034
+ setOpen(true);
8035
+ },
8036
+ children: renderSlot("settings.trigger", { wide })
8037
+ }),
8038
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.ConnectionIndicator, {
8039
+ state: wide ? connectionIndicator : void 0,
8040
+ disconnectedLabel: t("settings.disconnected"),
8041
+ reconnectLabel: t("settings.reconnect"),
8042
+ connectingLabel: t("settings.connecting"),
8043
+ recoveredLabel: t("settings.recovered"),
8044
+ reconnectActionLabel: t("settings.reconnect"),
8045
+ restartActionLabel: t("settings.reconnect"),
8046
+ onReconnect: reconnect
8047
+ }),
8048
+ open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8049
+ ref: page,
8050
+ className: "dcu-settings-page",
8051
+ "data-dcu-settings-page": true,
8052
+ role: "region",
8053
+ "aria-label": t("settings.title"),
8054
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
8055
+ className: "dcu-settings-nav",
8056
+ "aria-label": t("settings.title"),
8057
+ children: [
8058
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8059
+ ref: back,
8060
+ type: "button",
8061
+ className: "dcu-settings-back",
8062
+ onClick: close,
8063
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ArrowLeft, { size: 16 }), renderSlot("settings.close", {}) ?? t("settings.back")]
8064
+ }),
8065
+ renderSlot("settings.header", {}),
8066
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
8067
+ className: "dcu-settings-search",
8068
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Search, {
8069
+ size: 15,
8070
+ "aria-hidden": "true"
8071
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
8072
+ type: "search",
8073
+ value: query,
8074
+ "aria-label": t("settings.search"),
8075
+ placeholder: t("settings.search"),
8076
+ onChange: (event) => {
8077
+ setQuery(event.target.value);
8078
+ }
8079
+ })]
8080
+ }),
8081
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8082
+ className: "dcu-settings-groups",
8083
+ children: [
8084
+ "personal",
8085
+ "integrations",
8086
+ "records"
8087
+ ].map((group) => {
8088
+ const entries = visible.filter((row) => settingsGroup(row.id) === group);
8089
+ return entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
8090
+ className: "dcu-settings-group",
8091
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
8092
+ className: "dcu-settings-group-label",
8093
+ children: t(groupLabels[group])
8094
+ }), entries.map((row) => {
8095
+ const Icon = sectionIcon(row.id);
8096
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
8097
+ type: "button",
8098
+ className: "dcu-settings-link",
8099
+ "aria-current": row.id === active?.id ? "page" : void 0,
8100
+ onClick: () => {
8101
+ setActiveId(row.id);
8102
+ },
8103
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
8104
+ size: 16,
8105
+ strokeWidth: 1.6,
8106
+ "aria-hidden": "true"
8107
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: row.id === "general" ? t("settings.general") : row.label })]
8108
+ }, row.id);
8109
+ })]
8110
+ }, group);
8111
+ })
8112
+ }),
8113
+ visible.length > 0 && !visible.some((row) => row.id === active?.id) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8114
+ className: "dcu-settings-empty",
8115
+ role: "status",
8116
+ children: t("settings.filterHint")
8117
+ }),
8118
+ visible.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8119
+ className: "dcu-settings-empty",
8120
+ role: "status",
8121
+ children: t("settings.noResults")
8122
+ })
8123
+ ]
8124
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8125
+ ref: main,
8126
+ className: "dcu-settings-main",
8127
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8128
+ className: "dcu-settings-inner",
8129
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
8130
+ className: "dcu-settings-heading",
8131
+ "data-own-title": active?.id === "general",
8132
+ children: [active?.id === "general" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h1", { children: t("settings.general") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8133
+ className: "dcu-settings-actions",
8134
+ children: renderSlot("settings.action", {})
8135
+ })]
8136
+ }), active !== void 0 && renderSlot("settings.section", { close }, { only: active.id })]
8137
+ })
8138
+ })]
8139
+ }),
8140
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8141
+ ref: onboardingRoot,
8142
+ style: { display: "contents" },
8143
+ children: step !== void 0 && renderSlot("settings.onboarding", {
8144
+ stepId: step.id,
8145
+ complete: () => {
8146
+ setCompleted((previous) => /* @__PURE__ */ new Set([...previous, step.id]));
8147
+ },
8148
+ openSection
8149
+ }, { only: step.id })
8150
+ })
8151
+ ] });
8152
+ }
8153
+ /** 每条偏好仍由原插件渲染和保存,只为公共条目添加可扩展的分组容器。 */
8154
+ function CodexGeneralSettings({ items, renderSlot, t }) {
8155
+ const rows = (0, react.useSyncExternalStore)(items.subscribe, items.getSnapshot);
8156
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8157
+ className: "dcu-settings-general",
8158
+ children: [
8159
+ "permissions",
8160
+ "general",
8161
+ "editor"
8162
+ ].map((group) => {
8163
+ const entries = rows.filter((row) => generalItemGroup(row.id) === group);
8164
+ return entries.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
8165
+ className: "dcu-settings-general-group",
8166
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t(groupLabels[group]) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8167
+ className: "dcu-settings-card",
8168
+ children: entries.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8169
+ className: "dcu-settings-row",
8170
+ children: renderSlot("settings.general.item", {}, { only: row.id })
8171
+ }, row.id))
8172
+ })]
8173
+ }, group);
8174
+ })
8175
+ });
8176
+ }
8177
+ //#endregion
8178
+ //#region src/client/SettingsDocumentAction.tsx
8179
+ /** 通过宿主公开接口打开配置文件,沿用共享元数据和路径无关的操作。 */
8180
+ function SettingsDocumentAction({ describe, openDocument, t }) {
8181
+ const snapshot = (0, react.useSyncExternalStore)((listener) => describe.subscribe(listener), () => describe.getSnapshot());
8182
+ const busy = (0, react.useRef)(false);
8183
+ const [opening, setOpening] = (0, react.useState)(false);
8184
+ const [error, setError] = (0, react.useState)(false);
8185
+ (0, react.useEffect)(() => {
8186
+ let active = true;
8187
+ setError(false);
8188
+ describe.ensure().catch(() => {
8189
+ if (active) setError(true);
8190
+ });
8191
+ return () => {
8192
+ active = false;
8193
+ };
8194
+ }, [describe]);
8195
+ if (!snapshot.view?.hasDocument) return error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8196
+ role: "alert",
8197
+ children: t("settings.openDocumentError")
8198
+ }) : null;
8199
+ const open = async () => {
8200
+ if (busy.current) return;
8201
+ busy.current = true;
8202
+ setOpening(true);
8203
+ setError(false);
8204
+ try {
8205
+ setError(!(await openDocument()).ok);
8206
+ } catch {
8207
+ setError(true);
8208
+ } finally {
8209
+ busy.current = false;
8210
+ setOpening(false);
8211
+ }
8212
+ };
8213
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8214
+ role: "alert",
8215
+ children: t("settings.openDocumentError")
8216
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8217
+ type: "button",
8218
+ disabled: opening,
8219
+ onClick: () => {
8220
+ open();
8221
+ },
8222
+ children: t("settings.openDocument")
8223
+ })] });
8224
+ }
8225
+ //#endregion
8226
+ //#region src/client/settings-page-registration.ts
8227
+ /** 用公开插槽替换设置壳,保留宿主的设置写入、连接恢复和首次使用引导。 */
8228
+ function registerSettingsPage(ctx) {
8229
+ const children = [
8230
+ "settings.trigger",
8231
+ "settings.header",
8232
+ "settings.action",
8233
+ "settings.close",
8234
+ "settings.section",
8235
+ "settings.onboarding",
8236
+ "settings.general.item"
8237
+ ];
8238
+ const occupied = () => ctx.slots.entriesOfSlot("sidebar.settings").length > 0 || children.some((name) => ctx.slots.snapshot(name).length > 0);
8239
+ const warn = () => console.warn("[michengai-codex-ui] 已存在设置外壳,保留宿主设置;独立设置页需要 bundle patch 停用 ui-settings-general。");
8240
+ if (occupied()) {
8241
+ warn();
8242
+ return;
8243
+ }
8244
+ let owned = false;
8245
+ const t = ctx.locale.bind(NS);
8246
+ const connection = ctx.get("connection");
8247
+ const source = (name) => {
8248
+ let revision = "";
8249
+ let cached = [];
8250
+ return {
8251
+ getSnapshot: () => {
8252
+ const next = `${ctx.slots.getVersion(name)}:${ctx.locale.getSnapshot().revision}`;
8253
+ if (revision !== next) {
8254
+ revision = next;
8255
+ cached = ctx.slots.entriesOfSlot(name).map((entry) => ({
8256
+ id: entry.options.id ?? "",
8257
+ order: entry.options.order ?? 0,
8258
+ label: (typeof entry.options.label === "function" ? entry.options.label() : entry.options.label) ?? ""
8259
+ })).sort((a, b) => a.order - b.order);
8260
+ }
8261
+ return cached;
8262
+ },
8263
+ subscribe: (listener) => {
8264
+ const offSlots = ctx.slots.subscribe(name, listener);
8265
+ const offLocale = ctx.locale.subscribe(listener);
8266
+ return () => {
8267
+ offSlots();
8268
+ offLocale();
8269
+ };
8270
+ }
8271
+ };
8272
+ };
8273
+ const sections = source("settings.section");
8274
+ const onboarding = source("settings.onboarding");
8275
+ const items = source("settings.general.item");
8276
+ ctx.slots.inject("settings.trigger", () => !owned ? () => {} : ctx.slots.register({
8277
+ name: "settings.trigger",
8278
+ locale: NS
8279
+ }, ({ wide }) => (0, react.createElement)("span", { className: "dcu-settings-trigger-content" }, (0, react.createElement)(Settings, {
8280
+ size: 16,
8281
+ strokeWidth: 1.6
8282
+ }), wide ? (0, react.createElement)("span", null, t("settings.title")) : null)));
8283
+ ctx.slots.inject("settings.close", () => !owned ? () => {} : ctx.slots.register({
8284
+ name: "settings.close",
8285
+ locale: NS
8286
+ }, () => t("settings.back")));
8287
+ ctx.inject(["settingsScope", "remote.settings"], (settingsCtx) => {
8288
+ const remote = settingsCtx.get("remote");
8289
+ if (!remote.$host.isLoopback) return;
8290
+ const describe = settingsCtx.settingsScope.describe();
8291
+ settingsCtx.slots.inject("settings.action", () => !owned ? () => {} : settingsCtx.slots.register({
8292
+ name: "settings.action",
8293
+ id: "open-document",
8294
+ locale: NS,
8295
+ inject: () => ({
8296
+ describe,
8297
+ openDocument: () => remote.settings.openSettingsDocument()
8298
+ })
8299
+ }, SettingsDocumentAction));
8300
+ });
8301
+ ctx.slots.inject("sidebar.settings", () => {
8302
+ if (occupied()) {
8303
+ warn();
8304
+ return () => {};
8305
+ }
8306
+ owned = true;
8307
+ const remove = ctx.slots.register({
8308
+ name: "sidebar.settings",
8309
+ priority: -1,
8310
+ locale: NS,
8311
+ children: {
8312
+ "settings.trigger": {
8313
+ kind: "single",
8314
+ scope: "root"
8315
+ },
8316
+ "settings.header": {
8317
+ kind: "single",
8318
+ scope: "root"
8319
+ },
8320
+ "settings.action": {
8321
+ kind: "list",
8322
+ scope: "root"
8323
+ },
8324
+ "settings.close": {
8325
+ kind: "single",
8326
+ scope: "root"
8327
+ },
8328
+ "settings.section": {
8329
+ kind: "list",
8330
+ scope: "root"
8331
+ },
8332
+ "settings.onboarding": {
8333
+ kind: "list",
8334
+ scope: "root"
8335
+ }
8336
+ },
8337
+ inject: () => ({
8338
+ sections,
8339
+ onboarding,
8340
+ connectionState: connection.state,
8341
+ reconnect: () => {
8342
+ connection.reconnect();
8343
+ }
8344
+ })
8345
+ }, CodexSettingsPage);
8346
+ return () => {
8347
+ owned = false;
8348
+ remove();
8349
+ };
8350
+ });
8351
+ ctx.slots.inject("settings.section", () => !owned ? () => {} : ctx.slots.register({
8352
+ name: "settings.section",
8353
+ id: "general",
8354
+ priority: -1,
8355
+ order: 0,
8356
+ locale: NS,
8357
+ label: () => t("settings.general"),
8358
+ children: { "settings.general.item": {
8359
+ kind: "list",
8360
+ scope: "root"
8361
+ } },
8362
+ inject: () => ({ items })
8363
+ }, CodexGeneralSettings));
8364
+ }
8365
+ //#endregion
7400
8366
  //#region src/client/permission-labels.ts
7401
8367
  const PERMISSION_LABELS = [
7402
8368
  {
@@ -8166,6 +9132,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
8166
9132
  }), "michengai-codex-ui: dictionaries");
8167
9133
  const t = ctx.locale.bind(NS);
8168
9134
  registerInputHistory(ctx);
9135
+ registerSettingsPage(ctx);
8169
9136
  const connection = ctx.get("connection");
8170
9137
  const openPath = (path) => openPathInHost(connection, path);
8171
9138
  ctx.effect(() => observeSlimSidebar(), "michengai-codex-ui: slim sidebar");