dsh-more 0.0.5 → 0.0.7

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 (32) hide show
  1. package/README.md +15 -7
  2. package/README.zh-CN.md +15 -7
  3. package/dist/client.js +1149 -293
  4. package/dist/index.js +406 -156
  5. package/dist/types/generated/host-settings-schema.d.ts +4 -2
  6. package/dist/types/generated/patch-catalog.d.ts +12 -4
  7. package/dist/types/patches/conversation-markdown-export/client/menu.d.ts +5 -0
  8. package/dist/types/patches/model-capabilities/client/api.d.ts +4 -0
  9. package/dist/types/patches/model-capabilities/client/editor.d.ts +26 -0
  10. package/dist/types/patches/model-capabilities/client/index.d.ts +10 -0
  11. package/dist/types/patches/model-capabilities/client/model-entries.d.ts +15 -0
  12. package/dist/types/patches/model-capabilities/client/styles.d.ts +1 -0
  13. package/dist/types/patches/model-capabilities/host/deepseek.d.ts +11 -0
  14. package/dist/types/patches/{model-reasoning-efforts → model-capabilities}/host/validate.d.ts +3 -2
  15. package/dist/types/patches/model-capabilities/shared.d.ts +38 -0
  16. package/dist/types/patches/projectless-tasks/client/adapter.d.ts +17 -0
  17. package/dist/types/patches/projectless-tasks/client/create-task.d.ts +7 -0
  18. package/dist/types/patches/projectless-tasks/client/draft.d.ts +23 -0
  19. package/dist/types/patches/projectless-tasks/client/group-menu.d.ts +2 -0
  20. package/dist/types/patches/projectless-tasks/client/groups.d.ts +21 -0
  21. package/dist/types/patches/projectless-tasks/client/index.d.ts +2 -0
  22. package/dist/types/patches/projectless-tasks/client/new-session.d.ts +34 -0
  23. package/dist/types/patches/projectless-tasks/client/picker.d.ts +26 -0
  24. package/dist/types/patches/projectless-tasks/groups.d.ts +6 -0
  25. package/dist/types/patches/projectless-tasks/host/groups.d.ts +9 -0
  26. package/dist/types/patches/projectless-tasks/host/index.d.ts +5 -0
  27. package/dist/types/patches/projectless-tasks/shared.d.ts +6 -0
  28. package/dsh.plugin.json +1 -1
  29. package/package.json +1 -1
  30. package/dist/types/patches/model-reasoning-efforts/client/index.d.ts +0 -54
  31. package/dist/types/patches/model-reasoning-efforts/shared.d.ts +0 -51
  32. /package/dist/types/patches/{model-reasoning-efforts → model-capabilities}/host/index.d.ts +0 -0
package/dist/client.js CHANGED
@@ -25,7 +25,7 @@ __export(index_exports, {
25
25
  inject: () => inject
26
26
  });
27
27
  module.exports = __toCommonJS(index_exports);
28
- var import_react8 = require("react");
28
+ var import_react12 = require("react");
29
29
  var import_react_dom = require("react-dom");
30
30
 
31
31
  // src/generated/patch-catalog.ts
@@ -34,16 +34,18 @@ var PATCH_CATALOG = [
34
34
  { "id": "message-delete", "name": "\u5355\u6761\u6D88\u606F\u5220\u9664", "description": "\u5220\u9664\u6307\u5B9A\u6D88\u606F\u5E76\u4FDD\u7559\u524D\u540E\u5386\u53F2\u8BB0\u5F55", "defaultEnabled": true, "order": 200, "clientKind": "message-action" },
35
35
  { "id": "session-delete", "name": "\u6C38\u4E45\u5220\u9664\u4F1A\u8BDD", "description": "\u505C\u6B62\u76EE\u6807\u4F1A\u8BDD\u5E76\u4ECE\u78C1\u76D8\u6C38\u4E45\u5220\u9664\uFF0C\u4E0D\u5F71\u54CD\u539F\u751F\u5F52\u6863", "defaultEnabled": true, "order": 300, "clientKind": "standalone" },
36
36
  { "id": "conversation-markdown-export", "name": "\u5BFC\u51FA\u5B8C\u6574\u804A\u5929\u8BB0\u5F55", "description": "\u5C06\u5F53\u524D\u4F1A\u8BDD\u7684\u5B8C\u6574\u804A\u5929\u8BB0\u5F55\u4E0B\u8F7D\u4E3A Markdown \u6587\u4EF6", "defaultEnabled": true, "order": 400, "clientKind": "standalone" },
37
- { "id": "model-reasoning-efforts", "name": "\u6A21\u578B\u601D\u8003\u5F3A\u5EA6", "description": "\u5728\u6A21\u578B\u914D\u7F6E\u754C\u9762\u4E3A\u6BCF\u4E2A\u6A21\u578B\u914D\u7F6E\u652F\u6301\u7684\u601D\u8003\u5F3A\u5EA6\u5E76\u5199\u5165 settings.yaml \u7684 reasoningEfforts", "defaultEnabled": true, "order": 500, "clientKind": "standalone" },
38
- { "id": "session-auto-title", "name": "\u4F1A\u8BDD\u81EA\u52A8\u547D\u540D", "description": "\u65B0\u4F1A\u8BDD\u9996\u6761\u9700\u6C42\u540E\uFF0C\u4F7F\u7528\u5F53\u524D\u6A21\u578B\u751F\u6210\u300C\u7C7B\u578B \xB7 \u5177\u4F53\u4EFB\u52A1\u300D\u6807\u9898\uFF1B\u4FDD\u7559\u624B\u52A8\u547D\u540D\uFF0C\u5931\u8D25\u65F6\u4FDD\u7559\u539F\u6709\u6807\u9898", "defaultEnabled": true, "order": 600, "clientKind": "standalone" }
37
+ { "id": "model-capabilities", "name": "\u6A21\u578B\u80FD\u529B\u914D\u7F6E", "description": "\u5728\u6A21\u578B\u914D\u7F6E\u9875\u8BBE\u7F6E\u6BCF\u4E2A\u6A21\u578B\u7684\u8BC6\u56FE\u80FD\u529B\u3001\u53EF\u9009\u601D\u8003\u7C7B\u578B\u4E0E\u601D\u8003\u53C2\u6570\u683C\u5F0F", "defaultEnabled": true, "order": 500, "clientKind": "standalone" },
38
+ { "id": "session-auto-title", "name": "\u4F1A\u8BDD\u81EA\u52A8\u547D\u540D", "description": "\u65B0\u4F1A\u8BDD\u9996\u6761\u9700\u6C42\u540E\uFF0C\u4F7F\u7528\u5F53\u524D\u6A21\u578B\u751F\u6210\u300C\u7C7B\u578B \xB7 \u5177\u4F53\u4EFB\u52A1\u300D\u6807\u9898\uFF1B\u4FDD\u7559\u624B\u52A8\u547D\u540D\uFF0C\u5931\u8D25\u65F6\u4FDD\u7559\u539F\u6709\u6807\u9898", "defaultEnabled": true, "order": 600, "clientKind": "standalone" },
39
+ { "id": "projectless-tasks", "name": "\u72EC\u7ACB\u4EFB\u52A1", "description": "\u5728\u5DE5\u4F5C\u533A\u4E0B\u62C9\u6846\u521B\u5EFA\u72EC\u7ACB\u4EFB\u52A1\u5E76\u4FDD\u7559\u8349\u7A3F\uFF0C\u4E5F\u53EF\u5C06\u672A\u5206\u7EC4\u4F1A\u8BDD\u79FB\u5165\u5DE5\u4F5C\u533A\u5217\u8868", "defaultEnabled": true, "order": 700, "clientKind": "standalone" }
39
40
  ];
40
41
  var DEFAULT_PATCH_SETTINGS = {
41
42
  "message-edit": true,
42
43
  "message-delete": true,
43
44
  "session-delete": true,
44
45
  "conversation-markdown-export": true,
45
- "model-reasoning-efforts": true,
46
- "session-auto-title": true
46
+ "model-capabilities": true,
47
+ "session-auto-title": true,
48
+ "projectless-tasks": true
47
49
  };
48
50
  function decodePatchSettings(value) {
49
51
  if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
@@ -676,10 +678,83 @@ function markdownFilename(title, sessionId) {
676
678
  return `${safeStem(title) || fallback}.md`;
677
679
  }
678
680
 
681
+ // src/patches/conversation-markdown-export/client/menu.ts
682
+ var MENU_ITEM_ATTRIBUTE = "data-dshmore-markdown-export";
683
+ var MORE_BUTTON_SELECTOR = 'button[class*="_moreButton"][aria-haspopup="menu"]';
684
+ function installMarkdownExportMenu(fallback, options) {
685
+ const header = fallback.closest("header");
686
+ if (header === null) return () => {
687
+ };
688
+ let item = null;
689
+ let source = null;
690
+ let frame = null;
691
+ const removeItem = () => {
692
+ item?.remove();
693
+ item = null;
694
+ source = null;
695
+ };
696
+ const sync = () => {
697
+ frame = null;
698
+ const trigger = Array.from(header.querySelectorAll(MORE_BUTTON_SELECTOR)).find((button2) => ["\u66F4\u591A\u64CD\u4F5C", "More actions"].includes(button2.getAttribute("aria-label") ?? ""));
699
+ fallback.hidden = trigger !== void 0;
700
+ const download = trigger?.parentElement?.querySelector('button[role="menuitem"]');
701
+ const text = download?.textContent?.trim();
702
+ if (download === void 0 || download === null || !["\u4E0B\u8F7D Session \u65E5\u5FD7", "Download session log"].includes(text ?? "")) {
703
+ removeItem();
704
+ return;
705
+ }
706
+ if (source === download && item?.isConnected === true) return;
707
+ removeItem();
708
+ const wrapper = download.parentElement;
709
+ if (wrapper === null || wrapper.getAttribute("role") === "menu") return;
710
+ const clone = wrapper.cloneNode(true);
711
+ if (!(clone instanceof HTMLElement)) return;
712
+ const button = clone.querySelector('button[role="menuitem"]');
713
+ if (button === null) return;
714
+ const label = options.busy ? "\u6B63\u5728\u5BFC\u51FA\u2026" : "\u5BFC\u51FA Markdown";
715
+ const walker = document.createTreeWalker(button, NodeFilter.SHOW_TEXT);
716
+ for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
717
+ if (node.nodeValue?.trim() === text) node.nodeValue = label;
718
+ }
719
+ clone.setAttribute(MENU_ITEM_ATTRIBUTE, "");
720
+ button.disabled = options.busy;
721
+ button.setAttribute("aria-busy", String(options.busy));
722
+ button.setAttribute("aria-label", "\u5BFC\u51FA\u5B8C\u6574\u804A\u5929\u8BB0\u5F55\u4E3A Markdown");
723
+ button.addEventListener("click", (event) => {
724
+ event.preventDefault();
725
+ event.stopPropagation();
726
+ if (options.busy) return;
727
+ options.download();
728
+ if (trigger?.getAttribute("aria-expanded") === "true") trigger.click();
729
+ });
730
+ source = download;
731
+ item = clone;
732
+ wrapper.after(clone);
733
+ };
734
+ sync();
735
+ const observer = new MutationObserver(() => {
736
+ frame ??= window.requestAnimationFrame(sync);
737
+ });
738
+ observer.observe(header, {
739
+ childList: true,
740
+ subtree: true,
741
+ attributes: true,
742
+ attributeFilter: ["aria-label", "aria-expanded"],
743
+ characterData: true
744
+ });
745
+ return () => {
746
+ observer.disconnect();
747
+ if (frame !== null) window.cancelAnimationFrame(frame);
748
+ removeItem();
749
+ fallback.hidden = false;
750
+ };
751
+ }
752
+
679
753
  // src/patches/conversation-markdown-export/client/index.tsx
680
754
  var import_jsx_runtime4 = require("react/jsx-runtime");
681
755
  var exportStyles = `
682
756
  .dshmore-markdown-export-button { box-sizing: border-box; min-width: 128px; height: 32px; color: var(--dsw-alias-label-primary); cursor: pointer; background: transparent; border: 1px solid var(--dsw-alias-border-l2); border-radius: 18px; display: inline-flex; align-items: center; justify-content: center; gap: 5px; padding: 6px 12px; font-family: var(--dsw-font-family); font-size: 13px; line-height: 20px; }
757
+ .dshmore-markdown-export-button[hidden] { display: none; }
683
758
  .dshmore-markdown-export-button:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
684
759
  .dshmore-markdown-export-button:disabled { color: var(--dsw-alias-label-dimmed); cursor: wait; }
685
760
  .dshmore-markdown-export-button > span, .dshmore-markdown-export-button > svg { flex: none; }
@@ -703,15 +778,23 @@ function ConversationMarkdownExportButton(props) {
703
778
  const title = props.useSessions((state) => state.byId[props.sessionId]?.displayTitle ?? String(props.sessionId));
704
779
  const [busy, setBusy] = (0, import_react4.useState)(false);
705
780
  const [error, setError] = (0, import_react4.useState)(null);
781
+ const button = (0, import_react4.useRef)(null);
782
+ const inFlight = (0, import_react4.useRef)(false);
706
783
  const generation = (0, import_react4.useRef)(0);
707
784
  const activeSession = (0, import_react4.useRef)(null);
708
785
  activeSession.current = enabled ? String(props.sessionId) : null;
709
786
  (0, import_react4.useEffect)(() => {
710
787
  generation.current += 1;
788
+ inFlight.current = false;
711
789
  setBusy(false);
712
790
  setError(null);
791
+ return () => {
792
+ generation.current += 1;
793
+ };
713
794
  }, [enabled, props.sessionId]);
714
795
  const download = async () => {
796
+ if (inFlight.current) return;
797
+ inFlight.current = true;
715
798
  const requestSessionId = String(props.sessionId);
716
799
  const requestGeneration = ++generation.current;
717
800
  setBusy(true);
@@ -727,15 +810,25 @@ function ConversationMarkdownExportButton(props) {
727
810
  } catch (caught) {
728
811
  if (generation.current === requestGeneration && activeSession.current === requestSessionId) setError(apiErrorText(caught));
729
812
  } finally {
730
- if (generation.current === requestGeneration && activeSession.current === requestSessionId) setBusy(false);
813
+ if (generation.current === requestGeneration && activeSession.current === requestSessionId) {
814
+ inFlight.current = false;
815
+ setBusy(false);
816
+ }
731
817
  }
732
818
  };
819
+ (0, import_react4.useEffect)(() => {
820
+ if (!enabled || button.current === null) return;
821
+ return installMarkdownExportMenu(button.current, { busy, download: () => {
822
+ void download();
823
+ } });
824
+ }, [enabled, props.sessionId, title, busy]);
733
825
  if (!enabled) return null;
734
826
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
735
827
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: exportStyles }),
736
828
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
737
829
  "button",
738
830
  {
831
+ ref: button,
739
832
  type: "button",
740
833
  className: "dshmore-markdown-export-button",
741
834
  disabled: busy,
@@ -774,18 +867,53 @@ var clientPatch2 = {
774
867
  }
775
868
  };
776
869
 
777
- // src/patches/model-reasoning-efforts/client/index.tsx
778
- var import_react5 = require("react");
779
- var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
870
+ // src/patches/model-capabilities/client/index.tsx
871
+ var import_react6 = require("react");
780
872
 
781
- // src/patches/model-reasoning-efforts/shared.ts
782
- var MODEL_REASONING_EFFORTS_PATCH_ID = "model-reasoning-efforts";
873
+ // src/patches/model-capabilities/shared.ts
874
+ var MODEL_CAPABILITIES_PATCH_ID = "model-capabilities";
783
875
  var LLM_PI_AI_SETTINGS_NAMESPACE = "llm-pi-ai";
876
+ var LLM_DEEPSEEK_SETTINGS_NAMESPACE = "llm-deepseek";
877
+ var DEEPSEEK_PROVIDER = "deepseek-official";
878
+ var CAPABILITIES_PROTOCOL_VERSION = 2;
879
+ var DEEPSEEK_THINKING_LEVELS = ["off", "low", "high", "max"];
784
880
  var THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
881
+ var THINKING_FORMATS = [
882
+ "openai",
883
+ "deepseek",
884
+ "openrouter",
885
+ "together",
886
+ "baseten",
887
+ "zai",
888
+ "qwen",
889
+ "chat-template",
890
+ "qwen-chat-template",
891
+ "string-thinking",
892
+ "ant-ling"
893
+ ];
785
894
 
786
- // src/patches/model-reasoning-efforts/client/index.tsx
895
+ // src/patches/model-capabilities/client/api.ts
896
+ function decodeSnapshot(value) {
897
+ if (typeof value !== "object" || value === null) throw mismatch();
898
+ const snapshot = value;
899
+ if (snapshot.protocolVersion !== CAPABILITIES_PROTOCOL_VERSION || typeof snapshot.writable !== "boolean" || !Array.isArray(snapshot.rows) || !snapshot.rows.every((row) => {
900
+ if (typeof row !== "object" || row === null) return false;
901
+ const entry = row;
902
+ return (entry.namespace === "llm-deepseek" || entry.namespace === "llm-pi-ai") && Number.isSafeInteger(entry.revision) && Number(entry.revision) >= 0 && typeof entry.provider === "string" && typeof entry.modelId === "string" && (entry.vision === null || typeof entry.vision === "boolean") && Object.hasOwn(entry, "reasoningEfforts") && Object.hasOwn(entry, "thinkingFormat");
903
+ })) throw mismatch();
904
+ return snapshot;
905
+ }
906
+ function mismatch() {
907
+ return new Error("\u6A21\u578B\u80FD\u529B\u754C\u9762\u4E0E\u540E\u53F0\u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u542F DSH \u670D\u52A1\u540E\u5237\u65B0\u9875\u9762\uFF0C\u518D\u4FDD\u5B58\u914D\u7F6E\u3002");
908
+ }
909
+ async function readCapabilities() {
910
+ return decodeSnapshot(await callPatchApi(MODEL_CAPABILITIES_PATCH_ID, "read", {}));
911
+ }
912
+
913
+ // src/patches/model-capabilities/client/editor.tsx
914
+ var import_react5 = require("react");
915
+ var import_dsh_client_ui_primitives5 = require("@deepseek-ai/dsh-client-ui-primitives");
787
916
  var import_jsx_runtime5 = require("react/jsx-runtime");
788
- var EFFORT_BUTTON_ATTR = "data-dshmore-effort";
789
917
  var LEVEL_LABELS = {
790
918
  off: "\u4E0D\u601D\u8003",
791
919
  minimal: "\u6781\u7B80",
@@ -795,265 +923,355 @@ var LEVEL_LABELS = {
795
923
  xhigh: "\u6781\u9AD8",
796
924
  max: "\u6700\u9AD8"
797
925
  };
798
- function emptyDraft() {
799
- return { nonReasoning: false, levels: {} };
800
- }
801
- function draftFromServer(efforts) {
802
- if (efforts === false) return { nonReasoning: true, levels: {} };
803
- if (efforts !== null && typeof efforts === "object") {
804
- const levels = {};
926
+ function draftFromServer(capabilities) {
927
+ const efforts = capabilities.reasoningEfforts;
928
+ const levels = {};
929
+ if (efforts !== false && efforts !== null) {
805
930
  for (const level of THINKING_LEVELS) {
806
- const wire = efforts[level];
807
- if (wire !== void 0) levels[level] = { enabled: true, wire: wire ?? "" };
931
+ if (Object.hasOwn(efforts, level)) levels[level] = { enabled: true, wire: efforts[level] ?? "" };
808
932
  }
809
- return { nonReasoning: false, levels };
810
933
  }
811
- return emptyDraft();
812
- }
813
- function buildDict(draft) {
814
- const dict = {};
815
- for (const level of THINKING_LEVELS) {
816
- const entry = draft.levels[level];
817
- if (entry === void 0 || !entry.enabled) continue;
818
- dict[level] = level === "off" ? null : entry.wire;
819
- }
820
- return dict;
821
- }
822
- function summaryLabel(efforts) {
823
- if (efforts === false) return "\u4E0D\u652F\u6301\u601D\u8003";
824
- if (efforts === null || typeof efforts !== "object") return "\u672A\u914D\u7F6E";
825
- const parts = THINKING_LEVELS.filter((level) => level !== "off" && efforts[level] !== void 0).map((level) => LEVEL_LABELS[level]);
826
- return parts.length === 0 ? "\u672A\u914D\u7F6E" : parts.join("\u3001");
934
+ return {
935
+ vision: capabilities.vision === null ? "default" : capabilities.vision ? "yes" : "no",
936
+ thinking: efforts === null ? "default" : efforts === false ? "disabled" : "custom",
937
+ levels,
938
+ thinkingFormat: capabilities.thinkingFormat ?? "default"
939
+ };
827
940
  }
828
- function findModelEntries() {
829
- const entries = [];
830
- const catalogs = document.querySelectorAll('[class*="modelCatalog"]');
831
- for (const catalog of catalogs) {
832
- for (const entry of catalog.querySelectorAll('[class*="modelEntry"]')) entries.push(entry);
941
+ function capabilitiesFromDraft(draft) {
942
+ let reasoningEfforts = null;
943
+ if (draft.thinking === "disabled") reasoningEfforts = false;
944
+ if (draft.thinking === "custom") {
945
+ reasoningEfforts = {};
946
+ for (const level of THINKING_LEVELS) {
947
+ const entry = draft.levels[level];
948
+ if (!entry?.enabled) continue;
949
+ const wire = entry.wire.trim();
950
+ if (level !== "off" && wire === "") throw new Error(`\u8BF7\u586B\u5199\u300C${LEVEL_LABELS[level]}\u300D\u7684\u53C2\u6570\u503C\u3002`);
951
+ reasoningEfforts[level] = level === "off" && wire === "" ? null : wire;
952
+ }
953
+ if (!THINKING_LEVELS.some((level) => level !== "off" && draft.levels[level]?.enabled)) {
954
+ throw new Error("\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u79CD\u601D\u8003\u7B49\u7EA7\uFF1B\u4EC5\u9700\u4E0D\u601D\u8003\u65F6\uFF0C\u8BF7\u9009\u62E9\u300C\u4E0D\u652F\u6301\u601D\u8003\u300D\u3002");
955
+ }
833
956
  }
834
- return entries;
835
- }
836
- function providerRouteOf(entry) {
837
- const editor = entry.closest('[class*="editor"]');
838
- if (editor === null) return null;
839
- const routeSpan = editor.querySelector('[class*="editorRoute"]');
840
- const route = routeSpan?.textContent?.trim();
841
- if (route !== void 0 && route !== "") return route;
842
- const rowCard = editor.closest('[class*="rowCard"]');
843
- const name = rowCard?.querySelector('[class*="rowName"]')?.textContent?.trim();
844
- return name !== void 0 && name !== "" ? name : null;
957
+ return {
958
+ vision: draft.vision === "default" ? null : draft.vision === "yes",
959
+ reasoningEfforts,
960
+ thinkingFormat: draft.thinkingFormat === "default" ? null : draft.thinkingFormat
961
+ };
845
962
  }
846
- function modelIdOf(entry) {
847
- const input = entry.querySelector('[class*="modelRow"] input[type="text"]');
848
- const id = input?.value.trim();
849
- return id !== void 0 && id !== "" ? id : null;
963
+ function summaryLabel(capabilities) {
964
+ const vision = capabilities.vision === null ? "\u8BC6\u56FE\uFF1A\u9ED8\u8BA4" : capabilities.vision ? "\u652F\u6301\u8BC6\u56FE" : "\u4E0D\u652F\u6301\u8BC6\u56FE";
965
+ const efforts = capabilities.reasoningEfforts;
966
+ const thinking = efforts === null ? "\u601D\u8003\uFF1A\u9ED8\u8BA4" : efforts === false ? "\u4E0D\u652F\u6301\u601D\u8003" : THINKING_LEVELS.filter((level) => Object.hasOwn(efforts, level)).map((level) => LEVEL_LABELS[level]).join("\u3001");
967
+ return `${vision} \xB7 ${thinking}`;
850
968
  }
851
- function EffortEditorBody({ draft, setDraft, writable, busy }) {
852
- const toggleLevel = (level, enabled) => {
853
- setDraft((current) => {
854
- const existing = current.levels[level];
855
- const levels = { ...current.levels };
856
- levels[level] = existing === void 0 ? { enabled, wire: level === "off" ? "" : level } : { ...existing, enabled };
857
- return { ...current, levels };
858
- });
859
- };
860
- const setWire = (level, wire) => {
861
- setDraft((current) => {
862
- const existing = current.levels[level];
863
- if (existing === void 0) return current;
864
- return { ...current, levels: { ...current.levels, [level]: { ...existing, wire } } };
865
- });
866
- };
867
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-effort-editor", children: [
868
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-effort-switch", children: [
869
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
870
- "input",
871
- {
872
- type: "checkbox",
873
- role: "switch",
874
- checked: draft.nonReasoning,
875
- disabled: !writable || busy,
876
- onChange: (event) => {
877
- setDraft((current) => ({ ...current, nonReasoning: event.currentTarget.checked }));
878
- }
879
- }
880
- ),
881
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u8BE5\u6A21\u578B\u4E0D\u652F\u6301\u601D\u8003\uFF08reasoningEfforts: false\uFF09" })
969
+ function CapabilitiesEditorBody({ draft, setDraft, disabled, api: api3 }) {
970
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-capabilities-fields", children: [
971
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-capabilities-field", children: [
972
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u8BC6\u56FE\u80FD\u529B" }),
973
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u8BC6\u56FE\u80FD\u529B", value: draft.vision, disabled, onChange: (event) => {
974
+ const vision = event.currentTarget.value;
975
+ setDraft((current) => ({ ...current, vision }));
976
+ }, children: [
977
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "default", children: "\u6CBF\u7528\u9ED8\u8BA4" }),
978
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "yes", children: "\u652F\u6301\u8BC6\u56FE" }),
979
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "no", children: "\u4E0D\u652F\u6301\u8BC6\u56FE\uFF08\u4EC5\u6587\u5B57\uFF09" })
980
+ ] })
882
981
  ] }),
883
- !draft.nonReasoning && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dshmore-effort-levels", children: THINKING_LEVELS.map((level) => {
884
- const entry = draft.levels[level];
885
- const enabled = entry?.enabled === true;
886
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-effort-level", children: [
887
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
888
- "input",
889
- {
890
- type: "checkbox",
891
- checked: enabled,
892
- disabled: !writable || busy,
893
- onChange: (event) => {
894
- toggleLevel(level, event.currentTarget.checked);
895
- }
896
- }
897
- ),
898
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dshmore-effort-level-label", children: LEVEL_LABELS[level] }),
899
- enabled && level !== "off" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
900
- "input",
901
- {
902
- className: "dshmore-effort-wire",
903
- type: "text",
904
- value: entry?.wire ?? "",
905
- disabled: !writable || busy,
906
- placeholder: "\u7EBF\u4E0A\u503C",
907
- "aria-label": `${LEVEL_LABELS[level]} \u7684\u7EBF\u4E0A\u503C`,
908
- onChange: (event) => {
909
- setWire(level, event.currentTarget.value);
982
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-capabilities-field", children: [
983
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u601D\u8003\u7C7B\u578B" }),
984
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u601D\u8003\u7C7B\u578B", value: draft.thinking, disabled, onChange: (event) => {
985
+ const thinking = event.currentTarget.value;
986
+ setDraft((current) => ({ ...current, thinking }));
987
+ }, children: [
988
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "default", children: "\u6CBF\u7528\u9ED8\u8BA4" }),
989
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "disabled", children: "\u4E0D\u652F\u6301\u601D\u8003" }),
990
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "custom", children: "\u81EA\u5B9A\u4E49\u53EF\u9009\u7C7B\u578B" })
991
+ ] })
992
+ ] }),
993
+ draft.thinking === "custom" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("fieldset", { className: "dshmore-capabilities-levels", disabled, children: [
994
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("legend", { children: "\u6A21\u578B\u652F\u6301\u7684\u601D\u8003\u7B49\u7EA7" }),
995
+ (api3 === "deepseek-native" ? DEEPSEEK_THINKING_LEVELS : THINKING_LEVELS).map((level) => {
996
+ const entry = draft.levels[level];
997
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-capabilities-level", children: [
998
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
999
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", checked: entry?.enabled === true, onChange: (event) => {
1000
+ const enabled = event.currentTarget.checked;
1001
+ setDraft((current) => ({ ...current, levels: {
1002
+ ...current.levels,
1003
+ [level]: { wire: level === "off" ? "" : level, ...current.levels[level], enabled }
1004
+ } }));
1005
+ } }),
1006
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
1007
+ LEVEL_LABELS[level],
1008
+ " ",
1009
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: level })
1010
+ ] })
1011
+ ] }),
1012
+ entry?.enabled && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1013
+ "input",
1014
+ {
1015
+ type: "text",
1016
+ "aria-label": `${LEVEL_LABELS[level]}\u7684\u53C2\u6570\u503C`,
1017
+ value: entry.wire,
1018
+ readOnly: api3 === "deepseek-native",
1019
+ placeholder: level === "off" ? "\u7559\u7A7A\uFF1A\u4E0D\u53D1\u9001\u53C2\u6570" : "\u53D1\u9001\u7ED9\u63A5\u53E3\u7684\u53C2\u6570\u503C",
1020
+ onChange: (event) => {
1021
+ const wire = event.currentTarget.value;
1022
+ setDraft((current) => ({ ...current, levels: {
1023
+ ...current.levels,
1024
+ [level]: { enabled: true, wire }
1025
+ } }));
1026
+ }
910
1027
  }
911
- }
912
- )
913
- ] }, level);
914
- }) })
1028
+ )
1029
+ ] }, level);
1030
+ })
1031
+ ] }),
1032
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("details", { className: "dshmore-capabilities-advanced", children: [
1033
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("summary", { children: [
1034
+ "\u601D\u8003\u53C2\u6570\u683C\u5F0F",
1035
+ draft.thinkingFormat === "default" ? "" : ` \xB7 ${draft.thinkingFormat}`
1036
+ ] }),
1037
+ api3 === null || api3 === "openai-completions" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "dshmore-capabilities-field", children: [
1038
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u63A5\u53E3\u63A5\u53D7\u7684\u683C\u5F0F" }),
1039
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u601D\u8003\u53C2\u6570\u683C\u5F0F", disabled, value: draft.thinkingFormat, onChange: (event) => {
1040
+ const thinkingFormat = event.currentTarget.value;
1041
+ setDraft((current) => ({ ...current, thinkingFormat }));
1042
+ }, children: [
1043
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "default", children: "\u6CBF\u7528\u9ED8\u8BA4\uFF08\u63D0\u4F9B\u65B9 / \u81EA\u52A8\u8BC6\u522B\uFF09" }),
1044
+ THINKING_FORMATS.map((format) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: format, children: format }, format))
1045
+ ] }),
1046
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "dshmore-capabilities-note", children: "\u7528\u4E8E OpenAI \u517C\u5BB9\u63A5\u53E3\uFF1B\u6309\u63A5\u53E3\u8981\u6C42\u9009\u62E9 OpenAI\u3001DeepSeek\u3001Qwen \u7B49\u683C\u5F0F\u3002" })
1047
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u5F53\u524D\u63A5\u53E3\u4F7F\u7528\u539F\u751F\u601D\u8003\u534F\u8BAE\uFF0C\u65E0\u9700\u914D\u7F6E\u6B64\u9879\u3002" })
1048
+ ] }),
1049
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u6CBF\u7528\u9ED8\u8BA4\u4F1A\u79FB\u9664\u8BE5\u6A21\u578B\u7684\u5BF9\u5E94\u58F0\u660E\u3002\u8BF7\u6309\u6A21\u578B\u5B9E\u9645\u80FD\u529B\u914D\u7F6E\u3002" })
915
1050
  ] });
916
1051
  }
917
- function EffortEditorModal({ provider, modelId, initial, writable, onClose }) {
918
- const [draft, setDraft] = (0, import_react5.useState)(() => draftFromServer(initial ?? null));
919
- const [busy, setBusy] = (0, import_react5.useState)(false);
1052
+ function CapabilitiesEditorModal({ provider, modelId, namespace, onClose, onSaved }) {
1053
+ const [snapshot, setSnapshot] = (0, import_react5.useState)(null);
1054
+ const [draft, setDraft] = (0, import_react5.useState)(null);
920
1055
  const [error, setError] = (0, import_react5.useState)(null);
1056
+ const [busy, setBusy] = (0, import_react5.useState)(false);
1057
+ const [attempt, setAttempt] = (0, import_react5.useState)(0);
1058
+ const saving = (0, import_react5.useRef)(false);
1059
+ const mounted = (0, import_react5.useRef)(false);
1060
+ (0, import_react5.useEffect)(() => {
1061
+ mounted.current = true;
1062
+ return () => {
1063
+ mounted.current = false;
1064
+ };
1065
+ }, []);
921
1066
  (0, import_react5.useEffect)(() => {
922
- setDraft(draftFromServer(initial ?? null));
923
- }, [initial]);
924
- const known = initial !== void 0;
1067
+ let cancelled = false;
1068
+ setError(null);
1069
+ void readCapabilities().then((next) => {
1070
+ if (cancelled) return;
1071
+ setSnapshot(next);
1072
+ const row2 = next.rows.find((entry) => entry.namespace === namespace && entry.provider === provider && entry.modelId === modelId);
1073
+ setDraft(row2 === void 0 ? null : draftFromServer(row2));
1074
+ }).catch((caught) => {
1075
+ if (!cancelled) setError(apiErrorText(caught));
1076
+ });
1077
+ return () => {
1078
+ cancelled = true;
1079
+ };
1080
+ }, [namespace, provider, modelId, attempt]);
1081
+ const row = snapshot?.rows.find((entry) => entry.provider === provider && entry.modelId === modelId);
925
1082
  const save = async () => {
926
- if (!known) return;
927
- const payload = draft.nonReasoning ? false : buildDict(draft);
928
- if (payload !== false && !THINKING_LEVELS.some((level) => level !== "off" && payload[level] !== void 0)) {
929
- setError("\u81F3\u5C11\u9700\u8981\u5F00\u542F\u4E00\u4E2A\u975E\u300C\u4E0D\u601D\u8003\u300D\u7684\u601D\u8003\u7EA7\u522B\uFF0C\u6216\u4F7F\u7528\u300C\u6E05\u9664\u914D\u7F6E\u300D\u3002");
1083
+ if (saving.current) return;
1084
+ if (draft === null || row === void 0 || !snapshot?.writable || !Number.isSafeInteger(row.revision)) {
1085
+ setError("\u6A21\u578B\u914D\u7F6E\u5C1A\u672A\u5C31\u7EEA\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5F39\u7A97\u540E\u91CD\u8BD5\u3002");
930
1086
  return;
931
1087
  }
932
- setBusy(true);
933
- setError(null);
1088
+ let capabilities;
934
1089
  try {
935
- await callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "save", {
936
- provider,
937
- modelId,
938
- reasoningEfforts: payload
939
- });
940
- onClose();
1090
+ capabilities = capabilitiesFromDraft(draft);
941
1091
  } catch (caught) {
942
1092
  setError(apiErrorText(caught));
943
- } finally {
944
- setBusy(false);
1093
+ return;
945
1094
  }
946
- };
947
- const clear = async () => {
948
- if (!known) return;
1095
+ saving.current = true;
949
1096
  setBusy(true);
950
1097
  setError(null);
951
1098
  try {
952
- await callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "save", {
1099
+ const next = decodeSnapshot(await callPatchApi(MODEL_CAPABILITIES_PATCH_ID, "save", {
1100
+ namespace,
953
1101
  provider,
954
1102
  modelId,
955
- reasoningEfforts: null
956
- });
957
- onClose();
1103
+ expectedRevision: row.revision,
1104
+ ...capabilities
1105
+ }));
1106
+ if (mounted.current) {
1107
+ onSaved(next);
1108
+ onClose();
1109
+ }
958
1110
  } catch (caught) {
959
- setError(apiErrorText(caught));
1111
+ if (mounted.current) setError(apiErrorText(caught));
960
1112
  } finally {
961
- setBusy(false);
1113
+ saving.current = false;
1114
+ if (mounted.current) setBusy(false);
962
1115
  }
963
1116
  };
964
1117
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
965
1118
  import_dsh_client_ui_primitives5.Modal,
966
1119
  {
967
1120
  open: true,
968
- onClose,
969
- title: `\u601D\u8003\u5F3A\u5EA6 \xB7 ${modelId}`,
1121
+ onClose: () => {
1122
+ if (!saving.current) onClose();
1123
+ },
1124
+ title: `\u6A21\u578B\u80FD\u529B \xB7 ${modelId}`,
970
1125
  closeLabel: "\u5173\u95ED",
971
1126
  description: `\u63D0\u4F9B\u65B9 ${provider}`,
972
1127
  footer: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
973
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: onClose, children: "\u5173\u95ED" }),
974
- known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: !writable || busy, onClick: () => {
975
- void clear();
976
- }, children: "\u6E05\u9664\u914D\u7F6E" }),
977
- known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "primary", disabled: !writable || busy, onClick: () => {
978
- void save();
979
- }, children: busy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58" })
1128
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1129
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1130
+ import_dsh_client_ui_primitives5.Button,
1131
+ {
1132
+ variant: "primary",
1133
+ disabled: busy || draft === null || row === void 0 || !snapshot?.writable,
1134
+ onClick: () => {
1135
+ void save();
1136
+ },
1137
+ children: busy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58"
1138
+ }
1139
+ )
980
1140
  ] }),
981
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-effort-dialog-body", children: [
982
- !known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-effort-note", children: "\u8BE5\u6A21\u578B\u5C1A\u672A\u4FDD\u5B58\u5230 settings.yaml\uFF0C\u8BF7\u5148\u5728\u4E0A\u65B9\u4FDD\u5B58\u63D0\u4F9B\u65B9\u914D\u7F6E\u3002" }),
983
- known && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EffortEditorBody, { draft, setDraft, writable, busy }),
984
- !writable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-effort-warn", children: "\u5F53\u524D Settings \u5B58\u50A8\u4E3A\u53EA\u8BFB\uFF0C\u65E0\u6CD5\u4FDD\u5B58\u4FEE\u6539\u3002" }),
985
- error !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "dshmore-effort-error", children: error })
1141
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "dshmore-capabilities-dialog", children: [
1142
+ snapshot === null && error === null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u6B63\u5728\u8BFB\u53D6\u6A21\u578B\u914D\u7F6E\u2026" }),
1143
+ snapshot !== null && row === void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u8BF7\u5148\u4FDD\u5B58\u63D0\u4F9B\u65B9\u914D\u7F6E\uFF0C\u518D\u6253\u5F00\u8BE5\u6A21\u578B\u7684\u80FD\u529B\u8BBE\u7F6E\u3002" }),
1144
+ draft !== null && row !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1145
+ CapabilitiesEditorBody,
1146
+ {
1147
+ draft,
1148
+ setDraft: (update) => {
1149
+ setDraft((current) => current === null ? null : update(current));
1150
+ },
1151
+ disabled: busy || !snapshot?.writable,
1152
+ api: row.api
1153
+ }
1154
+ ),
1155
+ snapshot !== null && !snapshot.writable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "dshmore-capabilities-note", children: "\u5F53\u524D\u914D\u7F6E\u4E3A\u53EA\u8BFB\u3002" }),
1156
+ error !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { role: "alert", className: "dshmore-capabilities-error", children: error }),
1157
+ snapshot === null && error !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_dsh_client_ui_primitives5.Button, { variant: "ghost", onClick: () => {
1158
+ setAttempt((value) => value + 1);
1159
+ }, children: "\u91CD\u8BD5" })
986
1160
  ] })
987
1161
  }
988
1162
  );
989
1163
  }
990
- function ModelsPageEffortPortal(props) {
991
- const settings = (0, import_react5.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot, props.activation.getSnapshot);
992
- const enabled = settings[MODEL_REASONING_EFFORTS_PATCH_ID];
993
- const scopeSnapshot = (0, import_react5.useSyncExternalStore)(props.scope.subscribe, props.scope.getSnapshot, props.scope.getSnapshot);
994
- const [editing, setEditing] = (0, import_react5.useState)(null);
995
- const [data, setData] = (0, import_react5.useState)(null);
996
- const dataRef = (0, import_react5.useRef)(data);
1164
+
1165
+ // src/patches/model-capabilities/client/model-entries.ts
1166
+ function findModelEntries() {
1167
+ const entries = [];
1168
+ const catalogs = document.querySelectorAll('[class*="modelCatalog"]');
1169
+ for (const catalog of catalogs) {
1170
+ for (const entry of catalog.querySelectorAll('[class*="modelEntry"]')) entries.push(entry);
1171
+ }
1172
+ return entries;
1173
+ }
1174
+ function providerRouteOf(entry) {
1175
+ const editor = entry.closest('[class*="editor"]');
1176
+ if (editor === null) return null;
1177
+ const routeSpan = editor.querySelector('[class*="editorRoute"]');
1178
+ const route = routeSpan?.textContent?.trim();
1179
+ if (route !== void 0 && route !== "") return route;
1180
+ const rowCard = editor.closest('[class*="rowCard"]');
1181
+ const name = rowCard?.querySelector('[class*="rowName"]')?.textContent?.trim();
1182
+ return name !== void 0 && name !== "" ? name : null;
1183
+ }
1184
+ function modelIdOf(entry) {
1185
+ const input = entry.querySelector('[class*="modelRow"] input[type="text"]');
1186
+ const id = input?.value.trim();
1187
+ return id !== void 0 && id !== "" ? id : null;
1188
+ }
1189
+
1190
+ // src/patches/model-capabilities/client/styles.ts
1191
+ var capabilitiesStyles = `
1192
+ .dshmore-capabilities-button { box-sizing: border-box; width: 100%; min-height: 30px; color: var(--dsw-alias-label-secondary); font: inherit; cursor: pointer; background: transparent; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 6px; margin-top: 6px; padding: 5px 10px; font-size: 12px; line-height: 18px; text-align: left; overflow-wrap: anywhere; }
1193
+ .dshmore-capabilities-button:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
1194
+ .dshmore-capabilities-dialog, .dshmore-capabilities-fields { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
1195
+ .dshmore-capabilities-dialog { max-height: 65vh; overflow-y: auto; }
1196
+ .dshmore-capabilities-field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--dsw-alias-label-secondary); }
1197
+ .dshmore-capabilities-fields select, .dshmore-capabilities-level input[type="text"] { box-sizing: border-box; min-width: 0; width: 100%; height: 32px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 6px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font: inherit; font-size: 13px; }
1198
+ .dshmore-capabilities-fields :disabled { opacity: .55; cursor: default; }
1199
+ .dshmore-capabilities-fields :focus-visible, .dshmore-capabilities-button:focus-visible { outline: 2px solid var(--dsw-alias-brand-primary); outline-offset: 2px; }
1200
+ .dshmore-capabilities-levels { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 12px; border: 1px solid var(--dsw-alias-border-l3); border-radius: 8px; min-width: 0; }
1201
+ .dshmore-capabilities-levels legend { font-size: 12px; color: var(--dsw-alias-label-secondary); }
1202
+ .dshmore-capabilities-level { display: grid; grid-template-columns: minmax(100px, 1fr) minmax(120px, 1.4fr); gap: 8px; align-items: center; min-height: 32px; }
1203
+ .dshmore-capabilities-level label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--dsw-alias-label-secondary); }
1204
+ .dshmore-capabilities-level input[type="checkbox"] { accent-color: var(--dsw-alias-state-business-primary); }
1205
+ .dshmore-capabilities-level small { color: var(--dsw-alias-label-tertiary); }
1206
+ .dshmore-capabilities-advanced { border-top: 1px solid var(--dsw-alias-border-l3); padding-top: 12px; }
1207
+ .dshmore-capabilities-advanced summary { cursor: pointer; font-size: 13px; color: var(--dsw-alias-label-secondary); }
1208
+ .dshmore-capabilities-advanced[open] summary { margin-bottom: 12px; }
1209
+ .dshmore-capabilities-note { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 18px; }
1210
+ .dshmore-capabilities-error { padding: 8px 10px; border-radius: 8px; background: rgba(208,58,58,.10); color: var(--dsw-alias-state-error-primary, rgb(220,90,90)); font-size: 12px; line-height: 18px; }
1211
+ `;
1212
+
1213
+ // src/patches/model-capabilities/client/index.tsx
1214
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1215
+ var BUTTON_ATTR = "data-dshmore-model-capabilities";
1216
+ function ModelsPageCapabilitiesPortal({ scope, deepseekScope, activation }) {
1217
+ const settings = (0, import_react6.useSyncExternalStore)(activation.subscribe, activation.getSnapshot, activation.getSnapshot);
1218
+ const enabled = settings[MODEL_CAPABILITIES_PATCH_ID];
1219
+ const scopeSnapshot = (0, import_react6.useSyncExternalStore)(scope.subscribe, scope.getSnapshot, scope.getSnapshot);
1220
+ const deepseekSnapshot = (0, import_react6.useSyncExternalStore)(deepseekScope.subscribe, deepseekScope.getSnapshot, deepseekScope.getSnapshot);
1221
+ const [editing, setEditing] = (0, import_react6.useState)(null);
1222
+ const [data, setData] = (0, import_react6.useState)(null);
1223
+ const dataRef = (0, import_react6.useRef)(data);
997
1224
  dataRef.current = data;
998
- const generation = (0, import_react5.useRef)(0);
999
- const fillingRef = (0, import_react5.useRef)(false);
1000
- const reload = (0, import_react5.useCallback)(async () => {
1001
- const current = ++generation.current;
1002
- try {
1003
- const snapshot = await callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "read", {});
1004
- if (generation.current !== current) return;
1005
- setData(snapshot);
1006
- if (enabled && snapshot.writable && snapshot.rows.some((row) => row.reasoningEfforts === null) && !fillingRef.current) {
1007
- fillingRef.current = true;
1008
- void callPatchApi(MODEL_REASONING_EFFORTS_PATCH_ID, "fillDefaults", {}).catch(() => void 0).finally(() => {
1009
- fillingRef.current = false;
1010
- });
1011
- }
1012
- } catch {
1225
+ (0, import_react6.useEffect)(() => {
1226
+ let cancelled = false;
1227
+ if (!enabled) {
1228
+ setEditing(null);
1229
+ setData(null);
1230
+ return;
1013
1231
  }
1014
- }, [enabled]);
1015
- (0, import_react5.useEffect)(() => {
1016
- if (enabled) void reload();
1017
- }, [enabled, reload, scopeSnapshot]);
1018
- const syncButtons = (0, import_react5.useCallback)(() => {
1232
+ void readCapabilities().then((snapshot) => {
1233
+ if (!cancelled) setData(snapshot);
1234
+ }).catch(() => {
1235
+ if (!cancelled) setData(null);
1236
+ });
1237
+ return () => {
1238
+ cancelled = true;
1239
+ };
1240
+ }, [enabled, scopeSnapshot, deepseekSnapshot]);
1241
+ const syncButtons = (0, import_react6.useCallback)(() => {
1019
1242
  if (!enabled) return;
1020
1243
  const active = /* @__PURE__ */ new Set();
1021
1244
  for (const entry of findModelEntries()) {
1022
1245
  const provider = providerRouteOf(entry);
1023
1246
  const modelId = modelIdOf(entry);
1024
- if (provider === null || modelId === null) continue;
1247
+ const modelRow = entry.querySelector('[class*="modelRow"]');
1248
+ if (provider === null || modelId === null || modelRow === null) continue;
1025
1249
  active.add(entry);
1026
- let button = entry.querySelector(`[${EFFORT_BUTTON_ATTR}]`);
1250
+ let button = entry.querySelector(`[${BUTTON_ATTR}]`);
1027
1251
  if (button === null) {
1028
1252
  button = document.createElement("button");
1029
1253
  button.type = "button";
1030
- button.className = "dshmore-effort-row-button";
1031
- button.setAttribute(EFFORT_BUTTON_ATTR, "");
1254
+ button.className = "dshmore-capabilities-button";
1255
+ button.setAttribute(BUTTON_ATTR, "");
1032
1256
  button.addEventListener("click", () => {
1033
1257
  const route = button?.dataset.provider;
1034
1258
  const model = button?.dataset.model;
1035
- if (route !== void 0 && model !== void 0) setEditing({ provider: route, modelId: model });
1259
+ if (route !== void 0 && model !== void 0) setEditing({ namespace: route === DEEPSEEK_PROVIDER ? LLM_DEEPSEEK_SETTINGS_NAMESPACE : LLM_PI_AI_SETTINGS_NAMESPACE, provider: route, modelId: model });
1036
1260
  });
1037
- const row = entry.querySelector('[class*="modelRow"]');
1038
- if (row === null) continue;
1039
- entry.insertBefore(button, row.nextSibling);
1261
+ entry.insertBefore(button, modelRow.nextSibling);
1040
1262
  }
1041
1263
  if (button.dataset.provider !== provider) button.dataset.provider = provider;
1042
1264
  if (button.dataset.model !== modelId) button.dataset.model = modelId;
1043
- const rowData = dataRef.current?.rows.find((row) => row.provider === provider && row.modelId === modelId);
1044
- const text = rowData === void 0 ? "\u601D\u8003\u5F3A\u5EA6" : `\u601D\u8003\u5F3A\u5EA6 \xB7 ${summaryLabel(rowData.reasoningEfforts)}`;
1265
+ const row = dataRef.current?.rows.find((item) => item.provider === provider && item.modelId === modelId);
1266
+ const text = row === void 0 ? "\u6A21\u578B\u80FD\u529B \xB7 \u8BC6\u56FE / \u601D\u8003\u7C7B\u578B" : `\u6A21\u578B\u80FD\u529B \xB7 ${summaryLabel(row)}`;
1045
1267
  if (button.textContent !== text) button.textContent = text;
1046
1268
  }
1047
- document.querySelectorAll(`[${EFFORT_BUTTON_ATTR}]`).forEach((button) => {
1048
- const host = button.parentElement;
1049
- if (host === null || !active.has(host)) button.remove();
1269
+ document.querySelectorAll(`[${BUTTON_ATTR}]`).forEach((button) => {
1270
+ if (button.parentElement === null || !active.has(button.parentElement)) button.remove();
1050
1271
  });
1051
1272
  }, [enabled]);
1052
- (0, import_react5.useEffect)(() => {
1053
- if (!enabled) {
1054
- document.querySelectorAll(`[${EFFORT_BUTTON_ATTR}]`).forEach((element) => element.remove());
1055
- return;
1056
- }
1273
+ (0, import_react6.useEffect)(() => {
1274
+ if (!enabled) return;
1057
1275
  let frame = null;
1058
1276
  const schedule = () => {
1059
1277
  if (frame !== null) return;
@@ -1072,61 +1290,48 @@ function ModelsPageEffortPortal(props) {
1072
1290
  document.removeEventListener("input", schedule);
1073
1291
  document.removeEventListener("change", schedule);
1074
1292
  if (frame !== null) window.cancelAnimationFrame(frame);
1075
- document.querySelectorAll(`[${EFFORT_BUTTON_ATTR}]`).forEach((element) => element.remove());
1293
+ document.querySelectorAll(`[${BUTTON_ATTR}]`).forEach((element) => element.remove());
1076
1294
  };
1077
1295
  }, [enabled, syncButtons]);
1078
- (0, import_react5.useEffect)(() => {
1296
+ (0, import_react6.useEffect)(() => {
1079
1297
  if (enabled) syncButtons();
1080
1298
  }, [enabled, syncButtons, data]);
1081
- const editingRow = editing === null ? void 0 : data?.rows.find((row) => row.provider === editing.provider && row.modelId === editing.modelId);
1082
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1083
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: effortStyles }),
1084
- editing !== null && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1085
- EffortEditorModal,
1299
+ if (!enabled) return null;
1300
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1301
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: capabilitiesStyles }),
1302
+ editing !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1303
+ CapabilitiesEditorModal,
1086
1304
  {
1087
- provider: editing.provider,
1088
- modelId: editing.modelId,
1089
- initial: editingRow === void 0 ? void 0 : editingRow.reasoningEfforts,
1090
- writable: data?.writable ?? true,
1305
+ ...editing,
1091
1306
  onClose: () => {
1092
1307
  setEditing(null);
1093
- }
1094
- }
1308
+ },
1309
+ onSaved: setData
1310
+ },
1311
+ `${editing.provider}/${editing.modelId}`
1095
1312
  )
1096
1313
  ] });
1097
1314
  }
1098
- var effortStyles = `
1099
- .dshmore-effort-row-button { box-sizing: border-box; width: 100%; height: 28px; color: var(--dsw-alias-label-secondary); font: inherit; cursor: pointer; background: transparent; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 6px; margin-top: 6px; padding: 0 10px; font-size: 12px; line-height: 18px; display: inline-flex; align-items: center; justify-content: flex-start; gap: 6px; }
1100
- .dshmore-effort-row-button:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }
1101
- .dshmore-effort-dialog-body { box-sizing: border-box; display: flex; flex-direction: column; gap: 12px; width: 100%; min-width: 0; overflow: hidden; }
1102
- .dshmore-effort-editor { display: flex; flex-direction: column; gap: 12px; }
1103
- .dshmore-effort-switch, .dshmore-effort-level { display: flex; align-items: center; gap: 8px; color: var(--dsw-alias-label-secondary); font-size: 13px; line-height: 20px; cursor: pointer; }
1104
- .dshmore-effort-switch input, .dshmore-effort-level input[type="checkbox"] { accent-color: var(--dsw-alias-state-business-primary); cursor: pointer; }
1105
- .dshmore-effort-levels { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px 12px; }
1106
- .dshmore-effort-level-label { flex: none; }
1107
- .dshmore-effort-wire { box-sizing: border-box; height: 28px; min-width: 0; width: 100%; font: inherit; color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-layer-1); border: 1px solid var(--dsw-alias-border-l2); border-radius: 6px; padding: 0 8px; font-size: 12px; line-height: 18px; }
1108
- .dshmore-effort-wire:focus { border-color: var(--dsw-alias-brand-primary); outline: none; }
1109
- .dshmore-effort-wire::placeholder { color: var(--dsw-alias-label-dimmed); }
1110
- .dshmore-effort-note { color: var(--dsw-alias-label-tertiary); margin: 0; font-size: 12px; line-height: 18px; }
1111
- .dshmore-effort-warn { color: var(--dsw-alias-state-warn-label); margin: 0; font-size: 12px; line-height: 18px; }
1112
- .dshmore-effort-error { padding: 8px 10px; border-radius: 8px; background: rgba(208,58,58,.10); color: var(--dsw-alias-state-error-primary, rgb(220,90,90)); font-size: 12px; line-height: 18px; }
1113
- `;
1114
1315
  var clientPatch3 = {
1115
- id: MODEL_REASONING_EFFORTS_PATCH_ID,
1316
+ id: MODEL_CAPABILITIES_PATCH_ID,
1116
1317
  install: (ctx, activation) => {
1117
- const scope = ctx.settingsScope.bind({ namespace: LLM_PI_AI_SETTINGS_NAMESPACE });
1118
- const boundScope = {
1119
- getSnapshot: scope.getSnapshot.bind(scope),
1120
- subscribe: scope.subscribe.bind(scope),
1121
- set: scope.set.bind(scope),
1122
- unset: scope.unset.bind(scope),
1123
- mutate: scope.mutate.bind(scope)
1318
+ const bindScope = (namespace) => {
1319
+ const scope = ctx.settingsScope.bind({ namespace });
1320
+ return {
1321
+ getSnapshot: scope.getSnapshot.bind(scope),
1322
+ subscribe: scope.subscribe.bind(scope),
1323
+ set: scope.set.bind(scope),
1324
+ unset: scope.unset.bind(scope),
1325
+ mutate: scope.mutate.bind(scope)
1326
+ };
1124
1327
  };
1328
+ const boundScope = bindScope(LLM_PI_AI_SETTINGS_NAMESPACE);
1329
+ const deepseekScope = bindScope(LLM_DEEPSEEK_SETTINGS_NAMESPACE);
1125
1330
  ctx.slots.inject("shell.overlay", () => ctx.slots.register({
1126
1331
  name: "shell.overlay",
1127
- id: `${PLUGIN_NAME}-${MODEL_REASONING_EFFORTS_PATCH_ID}`,
1332
+ id: `${PLUGIN_NAME}-${MODEL_CAPABILITIES_PATCH_ID}`,
1128
1333
  order: 90
1129
- }, (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModelsPageEffortPortal, { ...props, scope: boundScope, activation })));
1334
+ }, () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ModelsPageCapabilitiesPortal, { scope: boundScope, deepseekScope, activation })));
1130
1335
  }
1131
1336
  };
1132
1337
 
@@ -1140,9 +1345,660 @@ var clientPatch4 = {
1140
1345
  }
1141
1346
  };
1142
1347
 
1348
+ // src/patches/projectless-tasks/shared.ts
1349
+ var PROJECTLESS_TASKS_PATCH_ID = "projectless-tasks";
1350
+
1351
+ // src/patches/projectless-tasks/client/adapter.tsx
1352
+ var import_react8 = require("react");
1353
+
1354
+ // src/patches/projectless-tasks/client/create-task.ts
1355
+ function createTaskStarter(sessions) {
1356
+ let pendingId;
1357
+ let flight;
1358
+ let disposed = false;
1359
+ return {
1360
+ start(beforeOpen) {
1361
+ if (disposed) return Promise.reject(new Error("\u72EC\u7ACB\u4EFB\u52A1\u8865\u4E01\u5DF2\u5173\u95ED\u3002"));
1362
+ if (flight !== void 0) return flight;
1363
+ pendingId ??= `task-${crypto.randomUUID()}`;
1364
+ const sessionId = pendingId;
1365
+ flight = (async () => {
1366
+ const location = await callPatchApi(PROJECTLESS_TASKS_PATCH_ID, "prepare", { sessionId });
1367
+ if (location.sessionId !== sessionId || typeof location.cwd !== "string" || location.cwd.length === 0) {
1368
+ throw new Error("\u72EC\u7ACB\u4EFB\u52A1\u754C\u9762\u4E0E\u540E\u53F0\u7248\u672C\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u91CD\u542F DSH\u3002");
1369
+ }
1370
+ if (disposed) return;
1371
+ const id = await sessions.create({ sessionId, cwd: location.cwd });
1372
+ if (id !== sessionId) throw new Error("\u521B\u5EFA\u7ED3\u679C\u4E0E\u72EC\u7ACB\u4EFB\u52A1\u6807\u8BC6\u4E0D\u4E00\u81F4\u3002");
1373
+ if (!disposed && beforeOpen?.(id) !== false) sessions.open(id);
1374
+ pendingId = void 0;
1375
+ })().finally(() => {
1376
+ flight = void 0;
1377
+ });
1378
+ return flight;
1379
+ },
1380
+ dispose() {
1381
+ disposed = true;
1382
+ }
1383
+ };
1384
+ }
1385
+
1386
+ // src/patches/projectless-tasks/client/draft.ts
1387
+ function transferDraft(source, target, rebind) {
1388
+ const from = source.state.getSnapshot();
1389
+ const to = target.state.getSnapshot();
1390
+ if (from.phase !== "plain" || to.phase !== "plain") throw new Error("\u8F93\u5165\u6B63\u5728\u5904\u7406\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u5207\u6362\u4EFB\u52A1\u76EE\u5F55\u3002");
1391
+ if (from.draft !== "" && to.draft !== "" && from.draft !== to.draft) {
1392
+ throw new Error("\u76EE\u6807\u4EFB\u52A1\u5DF2\u6709\u5176\u4ED6\u8349\u7A3F\uFF0C\u672C\u6B21\u5207\u6362\u5DF2\u505C\u6B62\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\u3002");
1393
+ }
1394
+ const ids = from.attachmentIds ?? from.imageIds;
1395
+ const add = from.attachmentIds === void 0 ? target.addImages : target.addAttachments;
1396
+ const remove = from.attachmentIds === void 0 ? source.removeImage : source.removeAttachment;
1397
+ if (!Array.isArray(ids) || typeof add !== "function" || typeof remove !== "function") {
1398
+ throw new Error("\u5F53\u524D DSH \u7248\u672C\u7684\u8349\u7A3F\u63A5\u53E3\u4E0D\u517C\u5BB9\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\u3002");
1399
+ }
1400
+ if (ids.length > 0 && !add.call(target, [...ids])) {
1401
+ throw new Error("\u6682\u65F6\u65E0\u6CD5\u8F6C\u79FB\u56FE\u7247\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
1402
+ }
1403
+ if (ids.length > 0 && from.attachmentIds !== void 0) {
1404
+ if (rebind === void 0) throw new Error("\u65E0\u6CD5\u8F6C\u79FB\u9644\u4EF6\u5F52\u5C5E\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\u3002");
1405
+ rebind(ids);
1406
+ }
1407
+ if (from.draft !== "") target.setDraft(from.draft);
1408
+ if (from.draft !== "") source.setDraft("");
1409
+ ids.forEach((id) => remove.call(source, id));
1410
+ }
1411
+ function transferBeforeOpen(ctx, sourceId, targetId) {
1412
+ const value = ctx.sessions;
1413
+ if (typeof value !== "object" || value === null || !("scope" in value) || typeof value.scope !== "function" || !("list" in value) || typeof value.list !== "object" || value.list === null || !("getSnapshot" in value.list) || typeof value.list.getSnapshot !== "function") {
1414
+ throw new Error("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u4FDD\u7559\u8349\u7A3F\u5207\u6362\uFF0C\u8BF7\u68C0\u67E5\u4F1A\u8BDD\u63A5\u53E3\u3002");
1415
+ }
1416
+ const sessions = value;
1417
+ const list = sessions.list.getSnapshot();
1418
+ if (list.current !== sourceId) return false;
1419
+ if (sourceId === void 0 || sourceId === targetId) return true;
1420
+ if (list.byId[sourceId]?.blank !== true) throw new Error("\u5F53\u524D\u4F1A\u8BDD\u5DF2\u5F00\u59CB\uFF0C\u8BF7\u65B0\u5EFA\u4F1A\u8BDD\u540E\u9009\u62E9\u72EC\u7ACB\u4EFB\u52A1\u3002");
1421
+ const source = sessions.scope(sourceId);
1422
+ const target = sessions.scope(targetId);
1423
+ if (source === void 0 || target === void 0) throw new Error("\u4EFB\u52A1\u5C1A\u672A\u51C6\u5907\u597D\uFF0C\u539F\u8349\u7A3F\u5DF2\u4FDD\u7559\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002");
1424
+ const conversation = ctx.conversation;
1425
+ transferDraft(
1426
+ conversation.input.for(source),
1427
+ conversation.input.for(target),
1428
+ typeof conversation.rebindDraftFiles === "function" ? (ids) => conversation.rebindDraftFiles(targetId, ids) : void 0
1429
+ );
1430
+ return true;
1431
+ }
1432
+
1433
+ // src/patches/projectless-tasks/client/picker.tsx
1434
+ var import_react7 = require("react");
1435
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1436
+ var INDEPENDENT_CHOICE_ID = "::dsh-more-independent-task";
1437
+ var INDEPENDENT_CHOICE = {
1438
+ workspaceId: INDEPENDENT_CHOICE_ID,
1439
+ title: "\u72EC\u7ACB\u4EFB\u52A1",
1440
+ path: "",
1441
+ sessionIds: [],
1442
+ createdAt: "",
1443
+ updatedAt: ""
1444
+ };
1445
+ var ChoiceContext = (0, import_react7.createContext)(void 0);
1446
+ function withIndependentChoice(snapshot) {
1447
+ return { ...snapshot, items: [INDEPENDENT_CHOICE, ...snapshot.items] };
1448
+ }
1449
+ function labelIndependentChip(anchor) {
1450
+ const label = anchor.querySelector('[class*="_workspaceLabel"]');
1451
+ if (label === null) return () => {
1452
+ };
1453
+ const text = label.textContent;
1454
+ const aria = anchor.getAttribute("aria-label");
1455
+ label.textContent = "\u72EC\u7ACB\u4EFB\u52A1";
1456
+ anchor.setAttribute("aria-label", "\u5DE5\u4F5C\u76EE\u5F55\uFF1A\u72EC\u7ACB\u4EFB\u52A1");
1457
+ return () => {
1458
+ if (label.textContent === "\u72EC\u7ACB\u4EFB\u52A1") label.textContent = text;
1459
+ if (anchor.getAttribute("aria-label") === "\u5DE5\u4F5C\u76EE\u5F55\uFF1A\u72EC\u7ACB\u4EFB\u52A1") {
1460
+ if (aria === null) anchor.removeAttribute("aria-label");
1461
+ else anchor.setAttribute("aria-label", aria);
1462
+ }
1463
+ };
1464
+ }
1465
+ function WorkspaceChoice({ owner, state, error, children }) {
1466
+ (0, import_react7.useLayoutEffect)(() => {
1467
+ const anchor = owner.anchorRef?.current;
1468
+ if (!state.independent || owner.selectedId !== void 0 || anchor === void 0 || anchor === null) return;
1469
+ return labelIndependentChip(anchor);
1470
+ });
1471
+ const clear = () => {
1472
+ owner.onClose();
1473
+ state.chooseIndependent();
1474
+ };
1475
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(ChoiceContext.Provider, { value: state, children: [
1476
+ children,
1477
+ owner.selectedId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1478
+ "button",
1479
+ {
1480
+ type: "button",
1481
+ className: "dshmore-workspace-clear",
1482
+ "aria-label": "\u6E05\u9664\u76EE\u5F55\uFF0C\u5207\u6362\u4E3A\u72EC\u7ACB\u4EFB\u52A1",
1483
+ title: "\u6E05\u9664\u76EE\u5F55\uFF0C\u5207\u6362\u4E3A\u72EC\u7ACB\u4EFB\u52A1",
1484
+ disabled: state.busy,
1485
+ onClick: clear,
1486
+ children: "\xD7"
1487
+ }
1488
+ ),
1489
+ state.busy && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dshmore-workspace-status", role: "status", children: "\u5207\u6362\u4E2D\u2026" }),
1490
+ error !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dshmore-workspace-error", role: "alert", children: error }),
1491
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: `
1492
+ .dshmore-workspace-clear { display:inline-flex; align-items:center; justify-content:center; flex:none; width:22px; height:22px; margin:0 4px 0 -2px; padding:0; border:0; border-radius:50%; color:var(--dsw-alias-label-secondary); background:transparent; font:18px/1 sans-serif; cursor:pointer; }
1493
+ .dshmore-workspace-clear:hover { color:var(--dsw-alias-label-primary); background:var(--dsw-alias-interactive-bg-hover); }
1494
+ .dshmore-workspace-clear:disabled { opacity:.45; cursor:wait; }
1495
+ .dshmore-workspace-status,.dshmore-workspace-error { font-size:12px; color:var(--dsw-alias-label-secondary); }
1496
+ .dshmore-workspace-error { max-width:300px; overflow-wrap:anywhere; color:var(--dsw-alias-state-error-primary); }
1497
+ ` })
1498
+ ] });
1499
+ }
1500
+ function extendWorkspacePicker(original) {
1501
+ return function ProjectlessPicker(props) {
1502
+ const choice = (0, import_react7.useContext)(ChoiceContext);
1503
+ const snapshot = props.useWorkspaces((value) => value);
1504
+ const display = (0, import_react7.useMemo)(() => choice === void 0 ? snapshot : withIndependentChoice(snapshot), [snapshot, choice === void 0]);
1505
+ const useWorkspaces = (select) => select(display);
1506
+ return (0, import_react7.createElement)(original, {
1507
+ ...props,
1508
+ useWorkspaces,
1509
+ open: props.open && !choice?.busy,
1510
+ selectedId: props.selectedId ?? (choice?.independent ? INDEPENDENT_CHOICE_ID : void 0),
1511
+ onPick: (id) => {
1512
+ if (choice?.busy) return;
1513
+ if (id === INDEPENDENT_CHOICE_ID) {
1514
+ props.onClose();
1515
+ choice?.chooseIndependent();
1516
+ } else props.onPick(id);
1517
+ }
1518
+ });
1519
+ };
1520
+ }
1521
+ function installPickerAdapter(ctx) {
1522
+ const wrapped = /* @__PURE__ */ new Map();
1523
+ const sync = () => {
1524
+ for (const entry of ctx.slots.entries("conversation.hero.workspace")) {
1525
+ if (wrapped.has(entry) || entry.children?.["conversation.hero.workspace.directoryFlow"] === void 0 || typeof entry.component !== "function") continue;
1526
+ const original = entry.component;
1527
+ const component = extendWorkspacePicker(original);
1528
+ wrapped.set(entry, { original, component });
1529
+ entry.component = component;
1530
+ }
1531
+ };
1532
+ const unsubscribe = ctx.slots.subscribe("conversation.hero.workspace", sync);
1533
+ sync();
1534
+ const priorities = ctx.slots.entries("conversation.hero.workspace").map((entry) => entry.options.priority ?? 0);
1535
+ const fallback = ctx.slots.register({ name: "conversation.hero.workspace", priority: Math.max(0, ...priorities) + 1 }, () => null);
1536
+ return () => {
1537
+ unsubscribe();
1538
+ for (const [entry, patch] of wrapped) if (entry.component === patch.component) entry.component = patch.original;
1539
+ wrapped.clear();
1540
+ fallback();
1541
+ };
1542
+ }
1543
+
1544
+ // src/patches/projectless-tasks/client/adapter.tsx
1545
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1546
+ function isComposerOwner(owner) {
1547
+ return "variant" in owner && (owner.variant === "hero" || owner.variant === "composer");
1548
+ }
1549
+ function isWorkspaceOwner(owner) {
1550
+ return "open" in owner && typeof owner.open === "boolean" && "onPick" in owner && typeof owner.onPick === "function" && "onClose" in owner && typeof owner.onClose === "function";
1551
+ }
1552
+ function clientSessionActions(ctx) {
1553
+ const sessions = ctx.sessions;
1554
+ if (typeof sessions !== "object" || sessions === null || !("create" in sessions) || !("open" in sessions) || typeof sessions.create !== "function" || typeof sessions.open !== "function") {
1555
+ throw new Error("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u72EC\u7ACB\u4EFB\u52A1\uFF0C\u8BF7\u68C0\u67E5\u4F1A\u8BDD\u63A5\u53E3\u3002");
1556
+ }
1557
+ return sessions;
1558
+ }
1559
+ function unlockComposer(owner, independent, block) {
1560
+ if (!independent || owner.disabled !== true || owner.onRequestWorkspace === void 0) return owner;
1561
+ const { disabled: _disabled, onRequestWorkspace: _request, workspacePickerOpen: _picker, placeholder: _placeholder, ...rest } = owner;
1562
+ return { ...rest, ...block === void 0 ? {} : { blocked: block, placeholder: block.reason } };
1563
+ }
1564
+ var CONVERSATION_SLOTS = ["conversation", "main.conversation"];
1565
+ function conversationSlot(name) {
1566
+ return name;
1567
+ }
1568
+ function installConversationAdapter(ctx, activation, name = "conversation") {
1569
+ const slot = conversationSlot(name);
1570
+ const wrapped = /* @__PURE__ */ new Map();
1571
+ let live = true;
1572
+ const listeners = /* @__PURE__ */ new Set();
1573
+ const subscribeLifetime = (listener) => {
1574
+ listeners.add(listener);
1575
+ return () => {
1576
+ listeners.delete(listener);
1577
+ };
1578
+ };
1579
+ const sync = () => {
1580
+ for (const entry of ctx.slots.entries(slot)) {
1581
+ let ProjectlessConversation2 = function(props) {
1582
+ const active = (0, import_react8.useSyncExternalStore)(subscribeLifetime, () => live);
1583
+ const settings = (0, import_react8.useSyncExternalStore)(activation.subscribe, activation.getSnapshot);
1584
+ const workspace = props.useWorkspaces((snapshot) => snapshot);
1585
+ const cwd = props.useSessions((snapshot) => props.sessionId === void 0 ? void 0 : snapshot.byId[props.sessionId]?.cwd);
1586
+ const session = props.useSession((snapshot) => snapshot);
1587
+ const block = props.useComposerBlock((value) => value);
1588
+ const enabled = active && settings[PROJECTLESS_TASKS_PATCH_ID];
1589
+ const starter = (0, import_react8.useRef)();
1590
+ const [busy, setBusy] = (0, import_react8.useState)(false);
1591
+ const [error, setError] = (0, import_react8.useState)();
1592
+ (0, import_react8.useEffect)(() => {
1593
+ if (!enabled) return;
1594
+ setBusy(false);
1595
+ setError(void 0);
1596
+ return () => {
1597
+ starter.current?.dispose();
1598
+ starter.current = void 0;
1599
+ };
1600
+ }, [enabled]);
1601
+ const independent = enabled && props.sessionId !== void 0 && session?.openState === "open" && typeof cwd === "string" && cwd.length > 0 && workspace.phase === "ready" && !workspace.items.some((item) => item.sessionIds.includes(props.sessionId));
1602
+ const chooseIndependent = () => {
1603
+ if (!enabled || busy || independent) return;
1604
+ const operation = starter.current ??= createTaskStarter(clientSessionActions(ctx));
1605
+ setBusy(true);
1606
+ setError(void 0);
1607
+ void operation.start((id) => transferBeforeOpen(ctx, props.sessionId, id)).catch((reason) => {
1608
+ if (starter.current === operation) setError(apiErrorText(reason));
1609
+ }).finally(() => {
1610
+ if (starter.current === operation) setBusy(false);
1611
+ });
1612
+ };
1613
+ const renderSlot = (name2, owner, options) => {
1614
+ if (name2 === "conversation.composer.bar" && isComposerOwner(owner)) {
1615
+ return props.renderSlot("conversation.composer.bar", unlockComposer(owner, independent, block), options);
1616
+ }
1617
+ if (enabled && name2 === "conversation.hero.workspace" && isWorkspaceOwner(owner)) {
1618
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(WorkspaceChoice, { owner, state: { independent, busy, chooseIndependent }, error, children: props.renderSlot("conversation.hero.workspace", owner, options) });
1619
+ }
1620
+ return props.renderSlot(name2, owner, options);
1621
+ };
1622
+ return (0, import_react8.createElement)(original, { ...props, renderSlot });
1623
+ };
1624
+ var ProjectlessConversation = ProjectlessConversation2;
1625
+ if (wrapped.has(entry) || entry.children?.["conversation.composer.bar"] === void 0 || typeof entry.component !== "function") continue;
1626
+ const original = entry.component;
1627
+ wrapped.set(entry, { original, component: ProjectlessConversation2 });
1628
+ entry.component = ProjectlessConversation2;
1629
+ }
1630
+ };
1631
+ const unsubscribe = ctx.slots.subscribe(slot, sync);
1632
+ sync();
1633
+ const priorities = ctx.slots.entries(slot).map((entry) => entry.options.priority ?? 0);
1634
+ const fallback = ctx.slots.register({ name: slot, priority: Math.max(0, ...priorities) + 1 }, () => null);
1635
+ return () => {
1636
+ live = false;
1637
+ listeners.forEach((listener) => listener());
1638
+ unsubscribe();
1639
+ for (const [entry, patch] of wrapped) {
1640
+ if (entry.component === patch.component) entry.component = patch.original;
1641
+ }
1642
+ wrapped.clear();
1643
+ fallback();
1644
+ };
1645
+ }
1646
+
1647
+ // src/patches/projectless-tasks/client/new-session.ts
1648
+ function newSessionTarget(list, workspaces, explicit) {
1649
+ if (explicit !== void 0) return { kind: "workspace", workspaceId: explicit };
1650
+ if (list.current === void 0) return { kind: "native" };
1651
+ if (list.phase !== "ready" || workspaces.phase !== "ready") return { kind: "pending" };
1652
+ const visited = /* @__PURE__ */ new Set();
1653
+ let id = list.current;
1654
+ while (id !== void 0 && !visited.has(id)) {
1655
+ visited.add(id);
1656
+ const workspace = workspaces.items.find((item) => item.sessionIds.includes(id));
1657
+ if (workspace !== void 0) return { kind: "workspace", workspaceId: workspace.workspaceId };
1658
+ const summary = list.byId[id];
1659
+ if (summary === void 0) return { kind: "pending" };
1660
+ if (summary.origin === "subagent") {
1661
+ id = summary.parentId;
1662
+ continue;
1663
+ }
1664
+ return typeof summary.cwd === "string" && summary.cwd.length > 0 ? { kind: "independent", sourceId: list.current } : { kind: "pending" };
1665
+ }
1666
+ return { kind: "pending" };
1667
+ }
1668
+ function bindNewSessionNavigation({ navigation, sessions, workspaces, activation, reportError }) {
1669
+ let disposed = false;
1670
+ let uninstall;
1671
+ const sync = () => {
1672
+ const enabled = !disposed && activation.getSnapshot()[PROJECTLESS_TASKS_PATCH_ID];
1673
+ if (!enabled) {
1674
+ uninstall?.();
1675
+ uninstall = void 0;
1676
+ return;
1677
+ }
1678
+ if (uninstall !== void 0) return;
1679
+ const descriptor = Object.getOwnPropertyDescriptor(navigation, "startSession");
1680
+ const original = navigation.startSession;
1681
+ let active = true;
1682
+ let attempt;
1683
+ const cancel = () => {
1684
+ attempt?.starter.dispose();
1685
+ attempt = void 0;
1686
+ };
1687
+ const start = (workspaceId) => {
1688
+ if (!active) return original.call(navigation, workspaceId);
1689
+ const list = sessions.list.getSnapshot();
1690
+ const target = newSessionTarget(list, workspaces.list.getSnapshot(), workspaceId);
1691
+ if (target.kind === "workspace" || target.kind === "native") {
1692
+ cancel();
1693
+ return original.call(navigation, target.kind === "workspace" ? target.workspaceId : workspaceId);
1694
+ }
1695
+ if (target.kind === "pending") {
1696
+ cancel();
1697
+ if (list.current !== void 0) reportError(list.current, new Error("\u4F1A\u8BDD\u6765\u6E90\u4ECD\u5728\u52A0\u8F7D\uFF0C\u8BF7\u7A0D\u540E\u518D\u65B0\u5EFA\u4F1A\u8BDD\u3002"));
1698
+ return;
1699
+ }
1700
+ if (attempt?.sourceId !== target.sourceId) {
1701
+ cancel();
1702
+ attempt = { sourceId: target.sourceId, starter: createTaskStarter(sessions) };
1703
+ }
1704
+ const current = attempt;
1705
+ if (current === void 0 || current.flight !== void 0) return;
1706
+ current.flight = current.starter.start(() => {
1707
+ if (!active || attempt !== current) return false;
1708
+ const destination = newSessionTarget(sessions.list.getSnapshot(), workspaces.list.getSnapshot());
1709
+ return destination.kind === "independent" && destination.sourceId === current.sourceId;
1710
+ }).catch((error) => {
1711
+ if (active && attempt === current && sessions.list.getSnapshot().current === current.sourceId) {
1712
+ reportError(current.sourceId, error);
1713
+ }
1714
+ }).finally(() => {
1715
+ delete current.flight;
1716
+ });
1717
+ };
1718
+ navigation.startSession = start;
1719
+ uninstall = () => {
1720
+ active = false;
1721
+ cancel();
1722
+ if (Object.getOwnPropertyDescriptor(navigation, "startSession")?.value !== start) return;
1723
+ if (descriptor === void 0) Reflect.deleteProperty(navigation, "startSession");
1724
+ else Object.defineProperty(navigation, "startSession", descriptor);
1725
+ };
1726
+ };
1727
+ const unsubscribe = activation.subscribe(sync);
1728
+ try {
1729
+ sync();
1730
+ } catch (error) {
1731
+ unsubscribe();
1732
+ throw error;
1733
+ }
1734
+ return () => {
1735
+ disposed = true;
1736
+ unsubscribe();
1737
+ sync();
1738
+ };
1739
+ }
1740
+ function installNewSessionNavigation(ctx, activation) {
1741
+ const navigation = ctx.get("uiWorkspace");
1742
+ const sessions = ctx.sessions;
1743
+ if (typeof navigation !== "object" || navigation === null || !("startSession" in navigation) || typeof navigation.startSession !== "function" || typeof sessions !== "object" || sessions === null || !("create" in sessions) || typeof sessions.create !== "function" || !("open" in sessions) || typeof sessions.open !== "function" || !("scope" in sessions) || typeof sessions.scope !== "function" || !("list" in sessions) || typeof sessions.list !== "object" || sessions.list === null || !("getSnapshot" in sessions.list) || typeof sessions.list.getSnapshot !== "function") {
1744
+ throw new Error("\u5F53\u524D DSH \u7248\u672C\u4E0D\u652F\u6301\u8DDF\u968F\u4F1A\u8BDD\u6765\u6E90\u65B0\u5EFA\u4EFB\u52A1\u3002");
1745
+ }
1746
+ const clientSessions = sessions;
1747
+ return bindNewSessionNavigation({
1748
+ navigation,
1749
+ sessions: clientSessions,
1750
+ workspaces: ctx.workspaces,
1751
+ activation,
1752
+ reportError: (sourceId, error) => {
1753
+ const scope = clientSessions.scope(sourceId);
1754
+ const message = `\u65B0\u5EFA\u4F1A\u8BDD\u5931\u8D25\uFF1A${apiErrorText(error)}`;
1755
+ if (scope !== void 0) ctx.conversation.input.for(scope).notify("error", message);
1756
+ else ctx.logger.warn(message);
1757
+ }
1758
+ });
1759
+ }
1760
+
1761
+ // src/patches/projectless-tasks/client/groups.tsx
1762
+ var import_react9 = require("react");
1763
+ var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
1764
+
1765
+ // src/patches/projectless-tasks/groups.ts
1766
+ var SESSION_GROUPS_NAMESPACE = "dsh-more-session-groups";
1767
+ var EMPTY_GROUPS = { assignments: {} };
1768
+ function decodeSessionGroups(value) {
1769
+ if (typeof value !== "object" || value === null || !("assignments" in value)) return void 0;
1770
+ const assignments = value.assignments;
1771
+ if (typeof assignments !== "object" || assignments === null || Array.isArray(assignments) || !Object.values(assignments).every((id) => typeof id === "string")) return void 0;
1772
+ return { assignments };
1773
+ }
1774
+
1775
+ // src/patches/projectless-tasks/client/group-menu.ts
1776
+ var ATTRIBUTE = "data-dshmore-session-move";
1777
+ function installMoveMenu(onMove) {
1778
+ const items = /* @__PURE__ */ new Map();
1779
+ let frame;
1780
+ const sync = () => {
1781
+ frame = void 0;
1782
+ for (const [source, item] of items) {
1783
+ if (!source.isConnected || !item.isConnected) {
1784
+ item.remove();
1785
+ items.delete(source);
1786
+ }
1787
+ }
1788
+ for (const source of document.querySelectorAll('button[role="menuitem"]')) {
1789
+ const text = source.textContent?.trim();
1790
+ if (text !== "\u5F52\u6863\u4F1A\u8BDD" && text !== "Archive session" || items.has(source)) continue;
1791
+ if (document.querySelector('[class*="_sessionRow"][class*="_menuOpen"]') === null) continue;
1792
+ const wrapper = source.parentElement;
1793
+ if (wrapper === null) continue;
1794
+ const item = wrapper.cloneNode(true);
1795
+ const button = item.querySelector('button[role="menuitem"]');
1796
+ if (button === null) continue;
1797
+ const label = text === "\u5F52\u6863\u4F1A\u8BDD" ? "\u79FB\u52A8\u5230\u5DE5\u4F5C\u533A\u2026" : "Move to workspace\u2026";
1798
+ const walker = document.createTreeWalker(button, NodeFilter.SHOW_TEXT);
1799
+ for (let node = walker.nextNode(); node !== null; node = walker.nextNode()) {
1800
+ if (node.nodeValue?.trim() === text) node.nodeValue = node.nodeValue.replace(text, label);
1801
+ }
1802
+ item.setAttribute(ATTRIBUTE, "");
1803
+ button.setAttribute("aria-label", label);
1804
+ button.addEventListener("click", (event) => {
1805
+ event.preventDefault();
1806
+ event.stopImmediatePropagation();
1807
+ onMove(source);
1808
+ });
1809
+ items.set(source, item);
1810
+ wrapper.before(item);
1811
+ }
1812
+ };
1813
+ const observer = new MutationObserver(() => {
1814
+ frame ??= requestAnimationFrame(sync);
1815
+ });
1816
+ sync();
1817
+ observer.observe(document.body, { childList: true, subtree: true });
1818
+ return () => {
1819
+ observer.disconnect();
1820
+ if (frame !== void 0) cancelAnimationFrame(frame);
1821
+ items.forEach((item) => item.remove());
1822
+ items.clear();
1823
+ };
1824
+ }
1825
+
1826
+ // src/patches/projectless-tasks/client/groups.tsx
1827
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1828
+ function projectSessionGroups(workspaces, sessions, groups) {
1829
+ const owned = new Set(workspaces.items.flatMap((item) => item.sessionIds));
1830
+ const items = workspaces.items.map((workspace) => {
1831
+ const added = Object.entries(groups.assignments).flatMap(([id, target]) => target === workspace.workspaceId && !owned.has(id) && sessions.byId[id]?.origin !== "subagent" && sessions.byId[id] !== void 0 ? [id] : []);
1832
+ return added.length === 0 ? workspace : { ...workspace, sessionIds: [...added, ...workspace.sessionIds] };
1833
+ });
1834
+ return items.every((item, index) => item === workspaces.items[index]) ? workspaces : { ...workspaces, items };
1835
+ }
1836
+ var SIDEBAR_SLOT = "sidebar.workspaces";
1837
+ var ALWAYS_LIVE = { subscribe: () => () => {
1838
+ }, getSnapshot: () => true };
1839
+ function extendGroupedSidebar(original, activation, source, lifetime = ALWAYS_LIVE) {
1840
+ return function GroupedSidebar(props) {
1841
+ const settings = (0, import_react9.useSyncExternalStore)(activation.subscribe, activation.getSnapshot);
1842
+ const binding = (0, import_react9.useMemo)(() => ({ subscribe: (listener) => source.subscribe(listener), getSnapshot: () => source.getSnapshot() }), []);
1843
+ const saved = (0, import_react9.useSyncExternalStore)(binding.subscribe, binding.getSnapshot);
1844
+ const native = props.useWorkspaces((value) => value);
1845
+ const sessions = props.useSessions((value) => value);
1846
+ const active = (0, import_react9.useSyncExternalStore)(lifetime.subscribe, lifetime.getSnapshot);
1847
+ const enabled = active && settings[PROJECTLESS_TASKS_PATCH_ID];
1848
+ const groups = saved.value ?? EMPTY_GROUPS;
1849
+ const display = (0, import_react9.useMemo)(() => enabled ? projectSessionGroups(native, sessions, groups) : native, [enabled, native, sessions, groups]);
1850
+ const [pending, setPending] = (0, import_react9.useState)();
1851
+ const [destination, setDestination] = (0, import_react9.useState)("");
1852
+ const [busy, setBusy] = (0, import_react9.useState)(false);
1853
+ const [error, setError] = (0, import_react9.useState)();
1854
+ const intent = (0, import_react9.useRef)(false);
1855
+ const inFlight = (0, import_react9.useRef)(false);
1856
+ const live = (0, import_react9.useRef)(true);
1857
+ (0, import_react9.useEffect)(() => {
1858
+ live.current = true;
1859
+ return () => {
1860
+ live.current = false;
1861
+ };
1862
+ }, []);
1863
+ (0, import_react9.useEffect)(() => {
1864
+ if (!enabled) {
1865
+ setPending(void 0);
1866
+ return;
1867
+ }
1868
+ return installMoveMenu((archive) => {
1869
+ intent.current = true;
1870
+ try {
1871
+ archive.click();
1872
+ } finally {
1873
+ intent.current = false;
1874
+ }
1875
+ });
1876
+ }, [enabled]);
1877
+ const archiveSession = (id) => {
1878
+ if (!intent.current) return props.archiveSession(id);
1879
+ intent.current = false;
1880
+ setPending(id);
1881
+ setDestination(groups.assignments[id] ?? "");
1882
+ setError(void 0);
1883
+ return Promise.resolve();
1884
+ };
1885
+ const useWorkspaces = (select) => select(display);
1886
+ const close = () => {
1887
+ if (!inFlight.current) setPending(void 0);
1888
+ };
1889
+ const move = async () => {
1890
+ if (pending === void 0 || inFlight.current) return;
1891
+ inFlight.current = true;
1892
+ setBusy(true);
1893
+ setError(void 0);
1894
+ try {
1895
+ await callPatchApi(PROJECTLESS_TASKS_PATCH_ID, "move", { sessionId: pending, workspaceId: destination || null });
1896
+ if (live.current) setPending(void 0);
1897
+ } catch (reason) {
1898
+ if (live.current) setError(apiErrorText(reason));
1899
+ } finally {
1900
+ inFlight.current = false;
1901
+ if (live.current) setBusy(false);
1902
+ }
1903
+ };
1904
+ const groupedNatively = pending !== void 0 && native.items.some((item) => item.sessionIds.includes(pending));
1905
+ const subagent = pending !== void 0 && sessions.byId[pending]?.origin === "subagent";
1906
+ const selectedMissing = destination !== "" && !native.items.some((item) => item.workspaceId === destination);
1907
+ const unavailable = groupedNatively ? "\u8FD9\u6761\u4F1A\u8BDD\u5DF2\u6709\u539F\u751F\u5DE5\u4F5C\u533A\uFF0C\u53EA\u652F\u6301\u79FB\u52A8\u672A\u5206\u7EC4\u6216\u624B\u52A8\u5F52\u7EC4\u7684\u4F1A\u8BDD\u3002" : subagent ? "\u5B50\u4F1A\u8BDD\u8DDF\u968F\u4E3B\u4F1A\u8BDD\u5F52\u7EC4\uFF0C\u8BF7\u79FB\u52A8\u4E3B\u4F1A\u8BDD\u3002" : saved.status !== "ready" ? "\u5F52\u7EC4\u8BBE\u7F6E\u5C1A\u672A\u5C31\u7EEA\uFF0C\u8BF7\u786E\u8BA4\u5DF2\u91CD\u542F DSH \u540E\u53F0\u5E76\u5237\u65B0\u9875\u9762\u3002" : !saved.writable ? "\u5F53\u524D\u914D\u7F6E\u4E3A\u53EA\u8BFB\uFF0C\u65E0\u6CD5\u79FB\u52A8\u4F1A\u8BDD\u3002" : selectedMissing ? "\u76EE\u6807\u5DE5\u4F5C\u533A\u5DF2\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002" : void 0;
1908
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1909
+ (0, import_react9.createElement)(original, { ...props, useWorkspaces, archiveSession }),
1910
+ enabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1911
+ import_dsh_client_ui_primitives6.Modal,
1912
+ {
1913
+ open: pending !== void 0,
1914
+ onClose: close,
1915
+ title: "\u79FB\u52A8\u5230\u5DE5\u4F5C\u533A",
1916
+ closeLabel: "\u5173\u95ED",
1917
+ description: "\u4FDD\u7559\u4F1A\u8BDD\u5386\u53F2\u548C\u539F\u5DE5\u4F5C\u76EE\u5F55\uFF0C\u4EC5\u8C03\u6574\u5217\u8868\u5F52\u5C5E\u3002",
1918
+ footer: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1919
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_dsh_client_ui_primitives6.Button, { variant: "ghost", disabled: busy, onClick: close, children: "\u53D6\u6D88" }),
1920
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_dsh_client_ui_primitives6.Button, { variant: "primary", disabled: busy || unavailable !== void 0 || pending === void 0 || (groups.assignments[pending] ?? "") === destination, onClick: () => void move(), children: busy ? "\u6B63\u5728\u79FB\u52A8\u2026" : "\u79FB\u52A8" })
1921
+ ] }),
1922
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "grid", gap: 12 }, children: [
1923
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { children: pending === void 0 ? "" : sessions.byId[pending]?.displayTitle ?? pending }),
1924
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { style: { display: "grid", gap: 8 }, children: [
1925
+ "\u76EE\u6807\u5DE5\u4F5C\u533A",
1926
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1927
+ "select",
1928
+ {
1929
+ "aria-label": "\u76EE\u6807\u5DE5\u4F5C\u533A",
1930
+ value: destination,
1931
+ disabled: busy || unavailable !== void 0 && !selectedMissing,
1932
+ onChange: (event) => setDestination(event.target.value),
1933
+ style: { width: "100%", minHeight: 40, borderRadius: 10, padding: "8px 12px", color: "var(--dsw-alias-label-primary)", background: "var(--dsw-alias-button-elevated-fill)", border: "1px solid var(--dsw-alias-border-l4)" },
1934
+ children: [
1935
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: "", children: "\u672A\u5206\u7EC4" }),
1936
+ native.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("option", { value: item.workspaceId, children: item.title || item.path }, item.workspaceId))
1937
+ ]
1938
+ }
1939
+ )
1940
+ ] }),
1941
+ (error ?? unavailable) !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { role: "alert", style: { color: "var(--dsw-alias-state-error-primary)" }, children: error ?? unavailable })
1942
+ ] })
1943
+ }
1944
+ )
1945
+ ] });
1946
+ };
1947
+ }
1948
+ function installSessionGrouping(ctx, activation) {
1949
+ const source = ctx.settingsScope.bind({ namespace: SESSION_GROUPS_NAMESPACE, decode: decodeSessionGroups });
1950
+ ctx.slots.inject(SIDEBAR_SLOT, () => {
1951
+ let live = true;
1952
+ const listeners = /* @__PURE__ */ new Set();
1953
+ const lifetime = { getSnapshot: () => live, subscribe: (fn) => {
1954
+ listeners.add(fn);
1955
+ return () => {
1956
+ listeners.delete(fn);
1957
+ };
1958
+ } };
1959
+ const wrapped = /* @__PURE__ */ new Map();
1960
+ const sync = () => {
1961
+ for (const entry of ctx.slots.entries(SIDEBAR_SLOT)) {
1962
+ if (wrapped.has(entry) || entry.children?.["sidebar.workspaces.directoryFlow"] === void 0 || typeof entry.component !== "function") continue;
1963
+ const original = entry.component;
1964
+ const component = extendGroupedSidebar(original, activation, source, lifetime);
1965
+ wrapped.set(entry, { original, component });
1966
+ entry.component = component;
1967
+ }
1968
+ };
1969
+ const unsubscribe = ctx.slots.subscribe(SIDEBAR_SLOT, sync);
1970
+ sync();
1971
+ const priorities = ctx.slots.entries(SIDEBAR_SLOT).map((entry) => entry.options.priority ?? 0);
1972
+ const fallback = ctx.slots.register({ name: SIDEBAR_SLOT, priority: Math.max(0, ...priorities) + 1 }, () => null);
1973
+ return () => {
1974
+ live = false;
1975
+ listeners.forEach((listener) => listener());
1976
+ unsubscribe();
1977
+ for (const [entry, patch] of wrapped) if (entry.component === patch.component) entry.component = patch.original;
1978
+ wrapped.clear();
1979
+ fallback();
1980
+ };
1981
+ });
1982
+ }
1983
+
1984
+ // src/patches/projectless-tasks/client/index.tsx
1985
+ var clientPatch5 = {
1986
+ id: PROJECTLESS_TASKS_PATCH_ID,
1987
+ install: (ctx, activation) => {
1988
+ installSessionGrouping(ctx, activation);
1989
+ ctx.inject(["conversation", "uiWorkspace"], (scope) => {
1990
+ scope.effect(() => installNewSessionNavigation(scope, activation));
1991
+ for (const name of CONVERSATION_SLOTS) {
1992
+ scope.slots.inject(conversationSlot(name), () => installConversationAdapter(scope, activation, name));
1993
+ }
1994
+ scope.slots.inject("conversation.hero.workspace", () => installPickerAdapter(scope));
1995
+ });
1996
+ }
1997
+ };
1998
+
1143
1999
  // src/generated/client-registry.ts
1144
2000
  var MESSAGE_ACTION_PATCHES = [{ id: "message-edit", order: 100, useActions: useMessageActions }, { id: "message-delete", order: 200, useActions: useMessageActions2 }];
1145
- var CLIENT_PATCHES = [clientPatch, clientPatch2, clientPatch3, clientPatch4];
2001
+ var CLIENT_PATCHES = [clientPatch, clientPatch2, clientPatch3, clientPatch4, clientPatch5];
1146
2002
 
1147
2003
  // src/kernel/client/activation.ts
1148
2004
  var ClientPatchActivation = class {
@@ -1165,19 +2021,19 @@ var ClientPatchActivation = class {
1165
2021
  };
1166
2022
 
1167
2023
  // src/kernel/client/config-card.tsx
1168
- var import_react6 = require("react");
1169
- var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
1170
- var import_jsx_runtime6 = require("react/jsx-runtime");
2024
+ var import_react10 = require("react");
2025
+ var import_dsh_client_ui_primitives7 = require("@deepseek-ai/dsh-client-ui-primitives");
2026
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1171
2027
  function PatchConfigCard({ activation, initiallyOpen = false }) {
1172
- const scope = (0, import_react6.useSyncExternalStore)(
2028
+ const scope = (0, import_react10.useSyncExternalStore)(
1173
2029
  activation.subscribe,
1174
2030
  activation.getSettingsSnapshot,
1175
2031
  activation.getSettingsSnapshot
1176
2032
  );
1177
2033
  const settings = activation.getSnapshot();
1178
- const [open, setOpen] = (0, import_react6.useState)(initiallyOpen);
1179
- const [busy, setBusy] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
1180
- const [error, setError] = (0, import_react6.useState)(null);
2034
+ const [open, setOpen] = (0, import_react10.useState)(initiallyOpen);
2035
+ const [busy, setBusy] = (0, import_react10.useState)(/* @__PURE__ */ new Set());
2036
+ const [error, setError] = (0, import_react10.useState)(null);
1181
2037
  if (scope.status === "unavailable") return null;
1182
2038
  const update = async (id, enabled) => {
1183
2039
  setBusy((current) => /* @__PURE__ */ new Set([...current, id]));
@@ -1194,9 +2050,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
1194
2050
  });
1195
2051
  }
1196
2052
  };
1197
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { className: `dshmore-config-card${open ? " dshmore-config-card-open" : ""}`, children: [
1198
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: styles }),
1199
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
2053
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { className: `dshmore-config-card${open ? " dshmore-config-card-open" : ""}`, children: [
2054
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: styles }),
2055
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1200
2056
  "button",
1201
2057
  {
1202
2058
  type: "button",
@@ -1207,23 +2063,23 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
1207
2063
  setOpen((current) => !current);
1208
2064
  },
1209
2065
  children: [
1210
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dshmore-config-heading-copy", children: [
1211
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "DSH More" }),
1212
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u52A8\u6001\u5F00\u542F\u6216\u5173\u95ED\u72EC\u7ACB\u8865\u4E01\uFF0C\u9ED8\u8BA4\u5168\u90E8\u5F00\u542F\u3002" })
2066
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "dshmore-config-heading-copy", children: [
2067
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: "DSH More" }),
2068
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "\u52A8\u6001\u5F00\u542F\u6216\u5173\u95ED\u72EC\u7ACB\u8865\u4E01\uFF0C\u9ED8\u8BA4\u5168\u90E8\u5F00\u542F\u3002" })
1213
2069
  ] }),
1214
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives6.IconChevronDownOutline14, { className: `dshmore-config-chevron${open ? " dshmore-config-chevron-open" : ""}` })
2070
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives7.IconChevronDownOutline14, { className: `dshmore-config-chevron${open ? " dshmore-config-chevron-open" : ""}` })
1215
2071
  ]
1216
2072
  }
1217
2073
  ),
1218
- open && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dshmore-config-body", children: [
1219
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dshmore-config-list", children: PATCH_CATALOG.map((patch) => {
2074
+ open && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "dshmore-config-body", children: [
2075
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "dshmore-config-list", children: PATCH_CATALOG.map((patch) => {
1220
2076
  const waiting = busy.has(patch.id);
1221
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "dshmore-config-row", children: [
1222
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "dshmore-config-copy", children: [
1223
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: patch.name }),
1224
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: patch.description })
2077
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "dshmore-config-row", children: [
2078
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "dshmore-config-copy", children: [
2079
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: patch.name }),
2080
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: patch.description })
1225
2081
  ] }),
1226
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
2082
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1227
2083
  "input",
1228
2084
  {
1229
2085
  type: "checkbox",
@@ -1238,9 +2094,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
1238
2094
  )
1239
2095
  ] }, patch.id);
1240
2096
  }) }),
1241
- scope.status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dshmore-config-note", children: "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u914D\u7F6E\u2026" }),
1242
- scope.status === "ready" && !scope.writable && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dshmore-config-note", children: "\u5F53\u524D Settings \u5B58\u50A8\u4E3A\u53EA\u8BFB\u3002" }),
1243
- error !== null && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "dshmore-config-error", children: error })
2097
+ scope.status === "loading" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "dshmore-config-note", children: "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u914D\u7F6E\u2026" }),
2098
+ scope.status === "ready" && !scope.writable && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "dshmore-config-note", children: "\u5F53\u524D Settings \u5B58\u50A8\u4E3A\u53EA\u8BFB\u3002" }),
2099
+ error !== null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "dshmore-config-error", children: error })
1244
2100
  ] })
1245
2101
  ] });
1246
2102
  }
@@ -1249,14 +2105,14 @@ function installPatchConfigCard(ctx, activation) {
1249
2105
  name: "settings.plugin.item",
1250
2106
  key: PATCH_SETTINGS_NAMESPACE,
1251
2107
  priority: 90
1252
- }, (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PatchConfigCard, { ...props, activation })));
2108
+ }, (props) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PatchConfigCard, { ...props, activation })));
1253
2109
  }
1254
2110
 
1255
2111
  // src/kernel/message-visibility.ts
1256
2112
  var MESSAGE_VISIBILITY_PROJECTION_KEY = "dshMoreMessageDelete";
1257
2113
 
1258
2114
  // src/platform/dsh/client/message-targets.tsx
1259
- var import_react7 = require("react");
2115
+ var import_react11 = require("react");
1260
2116
 
1261
2117
  // src/platform/dsh/client/message-content.ts
1262
2118
  function contentText(content) {
@@ -1394,17 +2250,17 @@ function trajectorySourceSeq(row) {
1394
2250
  return Number.isSafeInteger(seq) && seq >= 0 ? seq : void 0;
1395
2251
  }
1396
2252
  function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = true) {
1397
- const selector = (0, import_react7.useMemo)(() => createMessageSurfaceSelector(active), [active, props.sessionId]);
2253
+ const selector = (0, import_react11.useMemo)(() => createMessageSurfaceSelector(active), [active, props.sessionId]);
1398
2254
  const surface = props.useChat(selector);
1399
- const surfaceRef = (0, import_react7.useRef)(surface);
1400
- const hiddenSeqsRef = (0, import_react7.useRef)(hiddenSeqs);
1401
- const hiddenTrajectoryKeysRef = (0, import_react7.useRef)(hiddenTrajectoryKeys);
2255
+ const surfaceRef = (0, import_react11.useRef)(surface);
2256
+ const hiddenSeqsRef = (0, import_react11.useRef)(hiddenSeqs);
2257
+ const hiddenTrajectoryKeysRef = (0, import_react11.useRef)(hiddenTrajectoryKeys);
1402
2258
  surfaceRef.current = surface;
1403
2259
  hiddenSeqsRef.current = hiddenSeqs;
1404
2260
  hiddenTrajectoryKeysRef.current = hiddenTrajectoryKeys;
1405
- const [targets, setTargets] = (0, import_react7.useState)([]);
1406
- const requestFullScanRef = (0, import_react7.useRef)(null);
1407
- (0, import_react7.useLayoutEffect)(() => {
2261
+ const [targets, setTargets] = (0, import_react11.useState)([]);
2262
+ const requestFullScanRef = (0, import_react11.useRef)(null);
2263
+ (0, import_react11.useLayoutEffect)(() => {
1408
2264
  if (!active) {
1409
2265
  setTargets((current) => current.length === 0 ? current : []);
1410
2266
  return;
@@ -1528,21 +2384,21 @@ function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = tru
1528
2384
  for (const host of document.querySelectorAll("[data-dshmore-message-actions]")) host.remove();
1529
2385
  };
1530
2386
  }, [active, props.sessionId]);
1531
- (0, import_react7.useLayoutEffect)(() => {
2387
+ (0, import_react11.useLayoutEffect)(() => {
1532
2388
  requestFullScanRef.current?.();
1533
2389
  }, [surface, hiddenSeqs, hiddenTrajectoryKeys]);
1534
2390
  return targets;
1535
2391
  }
1536
2392
 
1537
2393
  // src/client/index.tsx
1538
- var import_jsx_runtime7 = require("react/jsx-runtime");
2394
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1539
2395
  var inject = ["slots", "sessions", "workspaces", "settingsScope"];
1540
2396
  function MessageActionPatchController({ patch, props, targets, enabled }) {
1541
2397
  const actions = patch.useActions(props, enabled);
1542
2398
  const style = { "--dshmore-action-order": patch.order };
1543
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2399
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1544
2400
  enabled && targets.map((target) => (0, import_react_dom.createPortal)(
1545
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "dshmore-action-contribution", style, children: actions.renderAction(target) }),
2401
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dshmore-action-contribution", style, children: actions.renderAction(target) }),
1546
2402
  target.host,
1547
2403
  `${patch.id}:${target.key}`
1548
2404
  )),
@@ -1550,15 +2406,15 @@ function MessageActionPatchController({ patch, props, targets, enabled }) {
1550
2406
  ] });
1551
2407
  }
1552
2408
  function MessageActionsController(props) {
1553
- const settings = (0, import_react8.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot);
2409
+ const settings = (0, import_react12.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot);
1554
2410
  const projected = props.useProjection(MESSAGE_VISIBILITY_PROJECTION_KEY);
1555
- const hiddenSeqs = (0, import_react8.useMemo)(() => new Set(projected?.deletedSeqs ?? []), [projected]);
1556
- const hiddenTrajectoryKeys = (0, import_react8.useMemo)(() => new Set(projected?.hiddenTrajectoryKeys ?? []), [projected]);
2411
+ const hiddenSeqs = (0, import_react12.useMemo)(() => new Set(projected?.deletedSeqs ?? []), [projected]);
2412
+ const hiddenTrajectoryKeys = (0, import_react12.useMemo)(() => new Set(projected?.hiddenTrajectoryKeys ?? []), [projected]);
1557
2413
  const messageActionsEnabled = MESSAGE_ACTION_PATCHES.some((patch) => settings[patch.id]);
1558
2414
  const targets = useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, messageActionsEnabled);
1559
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1560
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: styles }),
1561
- MESSAGE_ACTION_PATCHES.map((patch) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2415
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2416
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: styles }),
2417
+ MESSAGE_ACTION_PATCHES.map((patch) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1562
2418
  MessageActionPatchController,
1563
2419
  {
1564
2420
  patch,
@@ -1581,7 +2437,7 @@ function apply(ctx) {
1581
2437
  name: "conversation.session.header.utilities",
1582
2438
  id: `${PLUGIN_NAME}-message-actions`,
1583
2439
  order: 90
1584
- }, (props) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageActionsController, { ...props, ctx, activation })));
2440
+ }, (props) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MessageActionsController, { ...props, ctx, activation })));
1585
2441
  for (const patch of CLIENT_PATCHES) patch.install(ctx, activation);
1586
2442
  }
1587
2443
  return module.exports; } });