dsh-more 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +5 -3
- package/README.md +17 -6
- package/README.zh-CN.md +17 -6
- package/dist/client.js +398 -61
- package/dist/index.js +102 -29
- package/dist/types/generated/patch-catalog.d.ts +1 -1
- package/dist/types/patches/conversation-markdown-export/client/menu.d.ts +5 -0
- package/dist/types/patches/projectless-tasks/client/adapter.d.ts +4 -2
- package/dist/types/patches/projectless-tasks/client/draft.d.ts +17 -3
- package/dist/types/patches/projectless-tasks/client/group-menu.d.ts +2 -0
- package/dist/types/patches/projectless-tasks/client/groups.d.ts +21 -0
- package/dist/types/patches/projectless-tasks/groups.d.ts +6 -0
- package/dist/types/patches/projectless-tasks/host/groups.d.ts +9 -0
- package/dsh.plugin.json +1 -1
- package/package.json +62 -60
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
|
|
28
|
+
var import_react12 = require("react");
|
|
29
29
|
var import_react_dom = require("react-dom");
|
|
30
30
|
|
|
31
31
|
// src/generated/patch-catalog.ts
|
|
@@ -36,7 +36,7 @@ var PATCH_CATALOG = [
|
|
|
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
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
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\
|
|
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" }
|
|
40
40
|
];
|
|
41
41
|
var DEFAULT_PATCH_SETTINGS = {
|
|
42
42
|
"message-edit": true,
|
|
@@ -678,10 +678,83 @@ function markdownFilename(title, sessionId) {
|
|
|
678
678
|
return `${safeStem(title) || fallback}.md`;
|
|
679
679
|
}
|
|
680
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
|
+
|
|
681
753
|
// src/patches/conversation-markdown-export/client/index.tsx
|
|
682
754
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
683
755
|
var exportStyles = `
|
|
684
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; }
|
|
685
758
|
.dshmore-markdown-export-button:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }
|
|
686
759
|
.dshmore-markdown-export-button:disabled { color: var(--dsw-alias-label-dimmed); cursor: wait; }
|
|
687
760
|
.dshmore-markdown-export-button > span, .dshmore-markdown-export-button > svg { flex: none; }
|
|
@@ -705,15 +778,23 @@ function ConversationMarkdownExportButton(props) {
|
|
|
705
778
|
const title = props.useSessions((state) => state.byId[props.sessionId]?.displayTitle ?? String(props.sessionId));
|
|
706
779
|
const [busy, setBusy] = (0, import_react4.useState)(false);
|
|
707
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);
|
|
708
783
|
const generation = (0, import_react4.useRef)(0);
|
|
709
784
|
const activeSession = (0, import_react4.useRef)(null);
|
|
710
785
|
activeSession.current = enabled ? String(props.sessionId) : null;
|
|
711
786
|
(0, import_react4.useEffect)(() => {
|
|
712
787
|
generation.current += 1;
|
|
788
|
+
inFlight.current = false;
|
|
713
789
|
setBusy(false);
|
|
714
790
|
setError(null);
|
|
791
|
+
return () => {
|
|
792
|
+
generation.current += 1;
|
|
793
|
+
};
|
|
715
794
|
}, [enabled, props.sessionId]);
|
|
716
795
|
const download = async () => {
|
|
796
|
+
if (inFlight.current) return;
|
|
797
|
+
inFlight.current = true;
|
|
717
798
|
const requestSessionId = String(props.sessionId);
|
|
718
799
|
const requestGeneration = ++generation.current;
|
|
719
800
|
setBusy(true);
|
|
@@ -729,15 +810,25 @@ function ConversationMarkdownExportButton(props) {
|
|
|
729
810
|
} catch (caught) {
|
|
730
811
|
if (generation.current === requestGeneration && activeSession.current === requestSessionId) setError(apiErrorText(caught));
|
|
731
812
|
} finally {
|
|
732
|
-
if (generation.current === requestGeneration && activeSession.current === requestSessionId)
|
|
813
|
+
if (generation.current === requestGeneration && activeSession.current === requestSessionId) {
|
|
814
|
+
inFlight.current = false;
|
|
815
|
+
setBusy(false);
|
|
816
|
+
}
|
|
733
817
|
}
|
|
734
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]);
|
|
735
825
|
if (!enabled) return null;
|
|
736
826
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
737
827
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: exportStyles }),
|
|
738
828
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
739
829
|
"button",
|
|
740
830
|
{
|
|
831
|
+
ref: button,
|
|
741
832
|
type: "button",
|
|
742
833
|
className: "dshmore-markdown-export-button",
|
|
743
834
|
disabled: busy,
|
|
@@ -1293,19 +1384,29 @@ function createTaskStarter(sessions) {
|
|
|
1293
1384
|
}
|
|
1294
1385
|
|
|
1295
1386
|
// src/patches/projectless-tasks/client/draft.ts
|
|
1296
|
-
function transferDraft(source, target) {
|
|
1387
|
+
function transferDraft(source, target, rebind) {
|
|
1297
1388
|
const from = source.state.getSnapshot();
|
|
1298
1389
|
const to = target.state.getSnapshot();
|
|
1299
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");
|
|
1300
1391
|
if (from.draft !== "" && to.draft !== "" && from.draft !== to.draft) {
|
|
1301
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");
|
|
1302
1393
|
}
|
|
1303
|
-
|
|
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])) {
|
|
1304
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");
|
|
1305
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
|
+
}
|
|
1306
1407
|
if (from.draft !== "") target.setDraft(from.draft);
|
|
1307
1408
|
if (from.draft !== "") source.setDraft("");
|
|
1308
|
-
|
|
1409
|
+
ids.forEach((id) => remove.call(source, id));
|
|
1309
1410
|
}
|
|
1310
1411
|
function transferBeforeOpen(ctx, sourceId, targetId) {
|
|
1311
1412
|
const value = ctx.sessions;
|
|
@@ -1320,7 +1421,12 @@ function transferBeforeOpen(ctx, sourceId, targetId) {
|
|
|
1320
1421
|
const source = sessions.scope(sourceId);
|
|
1321
1422
|
const target = sessions.scope(targetId);
|
|
1322
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");
|
|
1323
|
-
|
|
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
|
+
);
|
|
1324
1430
|
return true;
|
|
1325
1431
|
}
|
|
1326
1432
|
|
|
@@ -1455,7 +1561,12 @@ function unlockComposer(owner, independent, block) {
|
|
|
1455
1561
|
const { disabled: _disabled, onRequestWorkspace: _request, workspacePickerOpen: _picker, placeholder: _placeholder, ...rest } = owner;
|
|
1456
1562
|
return { ...rest, ...block === void 0 ? {} : { blocked: block, placeholder: block.reason } };
|
|
1457
1563
|
}
|
|
1458
|
-
|
|
1564
|
+
var CONVERSATION_SLOTS = ["conversation", "main.conversation"];
|
|
1565
|
+
function conversationSlot(name) {
|
|
1566
|
+
return name;
|
|
1567
|
+
}
|
|
1568
|
+
function installConversationAdapter(ctx, activation, name = "main.conversation") {
|
|
1569
|
+
const slot = conversationSlot(name);
|
|
1459
1570
|
const wrapped = /* @__PURE__ */ new Map();
|
|
1460
1571
|
let live = true;
|
|
1461
1572
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -1466,7 +1577,7 @@ function installConversationAdapter(ctx, activation) {
|
|
|
1466
1577
|
};
|
|
1467
1578
|
};
|
|
1468
1579
|
const sync = () => {
|
|
1469
|
-
for (const entry of ctx.slots.entries(
|
|
1580
|
+
for (const entry of ctx.slots.entries(slot)) {
|
|
1470
1581
|
let ProjectlessConversation2 = function(props) {
|
|
1471
1582
|
const active = (0, import_react8.useSyncExternalStore)(subscribeLifetime, () => live);
|
|
1472
1583
|
const settings = (0, import_react8.useSyncExternalStore)(activation.subscribe, activation.getSnapshot);
|
|
@@ -1499,14 +1610,14 @@ function installConversationAdapter(ctx, activation) {
|
|
|
1499
1610
|
if (starter.current === operation) setBusy(false);
|
|
1500
1611
|
});
|
|
1501
1612
|
};
|
|
1502
|
-
const renderSlot = (
|
|
1503
|
-
if (
|
|
1613
|
+
const renderSlot = (name2, owner, options) => {
|
|
1614
|
+
if (name2 === "conversation.composer.bar" && isComposerOwner(owner)) {
|
|
1504
1615
|
return props.renderSlot("conversation.composer.bar", unlockComposer(owner, independent, block), options);
|
|
1505
1616
|
}
|
|
1506
|
-
if (enabled &&
|
|
1617
|
+
if (enabled && name2 === "conversation.hero.workspace" && isWorkspaceOwner(owner)) {
|
|
1507
1618
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(WorkspaceChoice, { owner, state: { independent, busy, chooseIndependent }, error, children: props.renderSlot("conversation.hero.workspace", owner, options) });
|
|
1508
1619
|
}
|
|
1509
|
-
return props.renderSlot(
|
|
1620
|
+
return props.renderSlot(name2, owner, options);
|
|
1510
1621
|
};
|
|
1511
1622
|
return (0, import_react8.createElement)(original, { ...props, renderSlot });
|
|
1512
1623
|
};
|
|
@@ -1517,10 +1628,10 @@ function installConversationAdapter(ctx, activation) {
|
|
|
1517
1628
|
entry.component = ProjectlessConversation2;
|
|
1518
1629
|
}
|
|
1519
1630
|
};
|
|
1520
|
-
const unsubscribe = ctx.slots.subscribe(
|
|
1631
|
+
const unsubscribe = ctx.slots.subscribe(slot, sync);
|
|
1521
1632
|
sync();
|
|
1522
|
-
const priorities = ctx.slots.entries(
|
|
1523
|
-
const fallback = ctx.slots.register({ name:
|
|
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);
|
|
1524
1635
|
return () => {
|
|
1525
1636
|
live = false;
|
|
1526
1637
|
listeners.forEach((listener) => listener());
|
|
@@ -1647,13 +1758,239 @@ function installNewSessionNavigation(ctx, activation) {
|
|
|
1647
1758
|
});
|
|
1648
1759
|
}
|
|
1649
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
|
+
|
|
1650
1984
|
// src/patches/projectless-tasks/client/index.tsx
|
|
1651
1985
|
var clientPatch5 = {
|
|
1652
1986
|
id: PROJECTLESS_TASKS_PATCH_ID,
|
|
1653
1987
|
install: (ctx, activation) => {
|
|
1988
|
+
installSessionGrouping(ctx, activation);
|
|
1654
1989
|
ctx.inject(["conversation", "uiWorkspace"], (scope) => {
|
|
1655
1990
|
scope.effect(() => installNewSessionNavigation(scope, activation));
|
|
1656
|
-
|
|
1991
|
+
for (const name of CONVERSATION_SLOTS) {
|
|
1992
|
+
scope.slots.inject(conversationSlot(name), () => installConversationAdapter(scope, activation, name));
|
|
1993
|
+
}
|
|
1657
1994
|
scope.slots.inject("conversation.hero.workspace", () => installPickerAdapter(scope));
|
|
1658
1995
|
});
|
|
1659
1996
|
}
|
|
@@ -1684,19 +2021,19 @@ var ClientPatchActivation = class {
|
|
|
1684
2021
|
};
|
|
1685
2022
|
|
|
1686
2023
|
// src/kernel/client/config-card.tsx
|
|
1687
|
-
var
|
|
1688
|
-
var
|
|
1689
|
-
var
|
|
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");
|
|
1690
2027
|
function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
1691
|
-
const scope = (0,
|
|
2028
|
+
const scope = (0, import_react10.useSyncExternalStore)(
|
|
1692
2029
|
activation.subscribe,
|
|
1693
2030
|
activation.getSettingsSnapshot,
|
|
1694
2031
|
activation.getSettingsSnapshot
|
|
1695
2032
|
);
|
|
1696
2033
|
const settings = activation.getSnapshot();
|
|
1697
|
-
const [open, setOpen] = (0,
|
|
1698
|
-
const [busy, setBusy] = (0,
|
|
1699
|
-
const [error, setError] = (0,
|
|
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);
|
|
1700
2037
|
if (scope.status === "unavailable") return null;
|
|
1701
2038
|
const update = async (id, enabled) => {
|
|
1702
2039
|
setBusy((current) => /* @__PURE__ */ new Set([...current, id]));
|
|
@@ -1713,9 +2050,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
|
1713
2050
|
});
|
|
1714
2051
|
}
|
|
1715
2052
|
};
|
|
1716
|
-
return /* @__PURE__ */ (0,
|
|
1717
|
-
/* @__PURE__ */ (0,
|
|
1718
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
1719
2056
|
"button",
|
|
1720
2057
|
{
|
|
1721
2058
|
type: "button",
|
|
@@ -1726,23 +2063,23 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
|
1726
2063
|
setOpen((current) => !current);
|
|
1727
2064
|
},
|
|
1728
2065
|
children: [
|
|
1729
|
-
/* @__PURE__ */ (0,
|
|
1730
|
-
/* @__PURE__ */ (0,
|
|
1731
|
-
/* @__PURE__ */ (0,
|
|
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" })
|
|
1732
2069
|
] }),
|
|
1733
|
-
/* @__PURE__ */ (0,
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_dsh_client_ui_primitives7.IconChevronDownOutline14, { className: `dshmore-config-chevron${open ? " dshmore-config-chevron-open" : ""}` })
|
|
1734
2071
|
]
|
|
1735
2072
|
}
|
|
1736
2073
|
),
|
|
1737
|
-
open && /* @__PURE__ */ (0,
|
|
1738
|
-
/* @__PURE__ */ (0,
|
|
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) => {
|
|
1739
2076
|
const waiting = busy.has(patch.id);
|
|
1740
|
-
return /* @__PURE__ */ (0,
|
|
1741
|
-
/* @__PURE__ */ (0,
|
|
1742
|
-
/* @__PURE__ */ (0,
|
|
1743
|
-
/* @__PURE__ */ (0,
|
|
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 })
|
|
1744
2081
|
] }),
|
|
1745
|
-
/* @__PURE__ */ (0,
|
|
2082
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1746
2083
|
"input",
|
|
1747
2084
|
{
|
|
1748
2085
|
type: "checkbox",
|
|
@@ -1757,9 +2094,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
|
1757
2094
|
)
|
|
1758
2095
|
] }, patch.id);
|
|
1759
2096
|
}) }),
|
|
1760
|
-
scope.status === "loading" && /* @__PURE__ */ (0,
|
|
1761
|
-
scope.status === "ready" && !scope.writable && /* @__PURE__ */ (0,
|
|
1762
|
-
error !== null && /* @__PURE__ */ (0,
|
|
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 })
|
|
1763
2100
|
] })
|
|
1764
2101
|
] });
|
|
1765
2102
|
}
|
|
@@ -1768,14 +2105,14 @@ function installPatchConfigCard(ctx, activation) {
|
|
|
1768
2105
|
name: "settings.plugin.item",
|
|
1769
2106
|
key: PATCH_SETTINGS_NAMESPACE,
|
|
1770
2107
|
priority: 90
|
|
1771
|
-
}, (props) => /* @__PURE__ */ (0,
|
|
2108
|
+
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PatchConfigCard, { ...props, activation })));
|
|
1772
2109
|
}
|
|
1773
2110
|
|
|
1774
2111
|
// src/kernel/message-visibility.ts
|
|
1775
2112
|
var MESSAGE_VISIBILITY_PROJECTION_KEY = "dshMoreMessageDelete";
|
|
1776
2113
|
|
|
1777
2114
|
// src/platform/dsh/client/message-targets.tsx
|
|
1778
|
-
var
|
|
2115
|
+
var import_react11 = require("react");
|
|
1779
2116
|
|
|
1780
2117
|
// src/platform/dsh/client/message-content.ts
|
|
1781
2118
|
function contentText(content) {
|
|
@@ -1913,17 +2250,17 @@ function trajectorySourceSeq(row) {
|
|
|
1913
2250
|
return Number.isSafeInteger(seq) && seq >= 0 ? seq : void 0;
|
|
1914
2251
|
}
|
|
1915
2252
|
function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = true) {
|
|
1916
|
-
const selector = (0,
|
|
2253
|
+
const selector = (0, import_react11.useMemo)(() => createMessageSurfaceSelector(active), [active, props.sessionId]);
|
|
1917
2254
|
const surface = props.useChat(selector);
|
|
1918
|
-
const surfaceRef = (0,
|
|
1919
|
-
const hiddenSeqsRef = (0,
|
|
1920
|
-
const hiddenTrajectoryKeysRef = (0,
|
|
2255
|
+
const surfaceRef = (0, import_react11.useRef)(surface);
|
|
2256
|
+
const hiddenSeqsRef = (0, import_react11.useRef)(hiddenSeqs);
|
|
2257
|
+
const hiddenTrajectoryKeysRef = (0, import_react11.useRef)(hiddenTrajectoryKeys);
|
|
1921
2258
|
surfaceRef.current = surface;
|
|
1922
2259
|
hiddenSeqsRef.current = hiddenSeqs;
|
|
1923
2260
|
hiddenTrajectoryKeysRef.current = hiddenTrajectoryKeys;
|
|
1924
|
-
const [targets, setTargets] = (0,
|
|
1925
|
-
const requestFullScanRef = (0,
|
|
1926
|
-
(0,
|
|
2261
|
+
const [targets, setTargets] = (0, import_react11.useState)([]);
|
|
2262
|
+
const requestFullScanRef = (0, import_react11.useRef)(null);
|
|
2263
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
1927
2264
|
if (!active) {
|
|
1928
2265
|
setTargets((current) => current.length === 0 ? current : []);
|
|
1929
2266
|
return;
|
|
@@ -2047,21 +2384,21 @@ function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = tru
|
|
|
2047
2384
|
for (const host of document.querySelectorAll("[data-dshmore-message-actions]")) host.remove();
|
|
2048
2385
|
};
|
|
2049
2386
|
}, [active, props.sessionId]);
|
|
2050
|
-
(0,
|
|
2387
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
2051
2388
|
requestFullScanRef.current?.();
|
|
2052
2389
|
}, [surface, hiddenSeqs, hiddenTrajectoryKeys]);
|
|
2053
2390
|
return targets;
|
|
2054
2391
|
}
|
|
2055
2392
|
|
|
2056
2393
|
// src/client/index.tsx
|
|
2057
|
-
var
|
|
2394
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2058
2395
|
var inject = ["slots", "sessions", "workspaces", "settingsScope"];
|
|
2059
2396
|
function MessageActionPatchController({ patch, props, targets, enabled }) {
|
|
2060
2397
|
const actions = patch.useActions(props, enabled);
|
|
2061
2398
|
const style = { "--dshmore-action-order": patch.order };
|
|
2062
|
-
return /* @__PURE__ */ (0,
|
|
2399
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2063
2400
|
enabled && targets.map((target) => (0, import_react_dom.createPortal)(
|
|
2064
|
-
/* @__PURE__ */ (0,
|
|
2401
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "dshmore-action-contribution", style, children: actions.renderAction(target) }),
|
|
2065
2402
|
target.host,
|
|
2066
2403
|
`${patch.id}:${target.key}`
|
|
2067
2404
|
)),
|
|
@@ -2069,15 +2406,15 @@ function MessageActionPatchController({ patch, props, targets, enabled }) {
|
|
|
2069
2406
|
] });
|
|
2070
2407
|
}
|
|
2071
2408
|
function MessageActionsController(props) {
|
|
2072
|
-
const settings = (0,
|
|
2409
|
+
const settings = (0, import_react12.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot);
|
|
2073
2410
|
const projected = props.useProjection(MESSAGE_VISIBILITY_PROJECTION_KEY);
|
|
2074
|
-
const hiddenSeqs = (0,
|
|
2075
|
-
const hiddenTrajectoryKeys = (0,
|
|
2411
|
+
const hiddenSeqs = (0, import_react12.useMemo)(() => new Set(projected?.deletedSeqs ?? []), [projected]);
|
|
2412
|
+
const hiddenTrajectoryKeys = (0, import_react12.useMemo)(() => new Set(projected?.hiddenTrajectoryKeys ?? []), [projected]);
|
|
2076
2413
|
const messageActionsEnabled = MESSAGE_ACTION_PATCHES.some((patch) => settings[patch.id]);
|
|
2077
2414
|
const targets = useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, messageActionsEnabled);
|
|
2078
|
-
return /* @__PURE__ */ (0,
|
|
2079
|
-
/* @__PURE__ */ (0,
|
|
2080
|
-
MESSAGE_ACTION_PATCHES.map((patch) => /* @__PURE__ */ (0,
|
|
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)(
|
|
2081
2418
|
MessageActionPatchController,
|
|
2082
2419
|
{
|
|
2083
2420
|
patch,
|
|
@@ -2100,7 +2437,7 @@ function apply(ctx) {
|
|
|
2100
2437
|
name: "conversation.session.header.utilities",
|
|
2101
2438
|
id: `${PLUGIN_NAME}-message-actions`,
|
|
2102
2439
|
order: 90
|
|
2103
|
-
}, (props) => /* @__PURE__ */ (0,
|
|
2440
|
+
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MessageActionsController, { ...props, ctx, activation })));
|
|
2104
2441
|
for (const patch of CLIENT_PATCHES) patch.install(ctx, activation);
|
|
2105
2442
|
}
|
|
2106
2443
|
return module.exports; } });
|