dsh-more 0.0.3 → 0.0.5
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 +1 -1
- package/README.md +5 -3
- package/README.zh-CN.md +5 -3
- package/dist/client.js +88 -513
- package/dist/index.js +154 -58
- package/dist/types/client/index.d.ts +5 -1
- package/dist/types/generated/host-settings-schema.d.ts +2 -2
- package/dist/types/generated/patch-catalog.d.ts +4 -4
- package/dist/types/kernel/client/activation.d.ts +2 -1
- package/dist/types/kernel/client/config-card.d.ts +2 -2
- package/dist/types/kernel/client/message-actions.d.ts +4 -0
- package/dist/types/kernel/client/patch.d.ts +1 -1
- package/dist/types/kernel/host/settings.d.ts +1 -1
- package/dist/types/patches/message-delete/client/index.d.ts +1 -1
- package/dist/types/patches/message-delete/host/message-selection.d.ts +3 -3
- package/dist/types/patches/message-delete/host/projection.d.ts +26 -3
- package/dist/types/patches/message-edit/client/index.d.ts +1 -1
- package/dist/types/patches/message-edit/host/edit-continuation.d.ts +3 -3
- package/dist/types/patches/model-reasoning-efforts/client/index.d.ts +17 -2
- package/dist/types/patches/session-auto-title/client/index.d.ts +2 -0
- package/dist/types/patches/session-auto-title/host/generate.d.ts +6 -0
- package/dist/types/patches/session-auto-title/shared.d.ts +2 -0
- package/dist/types/platform/dsh/client/message-targets.d.ts +3 -2
- package/dist/types/platform/dsh/client/runtime.d.ts +2 -1
- package/dist/types/platform/dsh/client/session-sync.d.ts +4 -2
- package/dist/types/platform/dsh/host/session-history.d.ts +3 -3
- package/dsh.plugin.json +1 -1
- package/package.json +65 -46
- package/dist/types/patches/conversation-quick-navigation/client/index.d.ts +0 -22
- package/dist/types/patches/conversation-quick-navigation/client/navigation.d.ts +0 -26
- package/dist/types/patches/conversation-quick-navigation/shared.d.ts +0 -1
- /package/dist/types/patches/{conversation-quick-navigation → session-auto-title}/host/index.d.ts +0 -0
package/dist/client.js
CHANGED
|
@@ -25,8 +25,8 @@ __export(index_exports, {
|
|
|
25
25
|
inject: () => inject
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(index_exports);
|
|
28
|
-
var
|
|
29
|
-
var
|
|
28
|
+
var import_react8 = require("react");
|
|
29
|
+
var import_react_dom = require("react-dom");
|
|
30
30
|
|
|
31
31
|
// src/generated/patch-catalog.ts
|
|
32
32
|
var PATCH_CATALOG = [
|
|
@@ -35,7 +35,7 @@ var PATCH_CATALOG = [
|
|
|
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
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": "
|
|
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
39
|
];
|
|
40
40
|
var DEFAULT_PATCH_SETTINGS = {
|
|
41
41
|
"message-edit": true,
|
|
@@ -43,7 +43,7 @@ var DEFAULT_PATCH_SETTINGS = {
|
|
|
43
43
|
"session-delete": true,
|
|
44
44
|
"conversation-markdown-export": true,
|
|
45
45
|
"model-reasoning-efforts": true,
|
|
46
|
-
"
|
|
46
|
+
"session-auto-title": true
|
|
47
47
|
};
|
|
48
48
|
function decodePatchSettings(value) {
|
|
49
49
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
@@ -506,6 +506,7 @@ function installSessionDeleteMenuItems(onDelete) {
|
|
|
506
506
|
frame = null;
|
|
507
507
|
for (const [archiveButton, deleteItem] of deleteItems) {
|
|
508
508
|
if (!archiveButton.isConnected) {
|
|
509
|
+
deleteItem.remove();
|
|
509
510
|
deleteItems.delete(archiveButton);
|
|
510
511
|
} else if (!deleteItem.isConnected) {
|
|
511
512
|
archiveButton.removeAttribute(DELETE_SOURCE_ATTRIBUTE);
|
|
@@ -654,8 +655,7 @@ var clientPatch = {
|
|
|
654
655
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
655
656
|
name: "shell.overlay",
|
|
656
657
|
id: `${PLUGIN_NAME}-${SESSION_DELETE_PATCH_ID}`,
|
|
657
|
-
order: 90
|
|
658
|
-
registrant: PLUGIN_NAME
|
|
658
|
+
order: 90
|
|
659
659
|
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SessionDeleteController, { ...props, ctx, activation })));
|
|
660
660
|
}
|
|
661
661
|
};
|
|
@@ -769,8 +769,7 @@ var clientPatch2 = {
|
|
|
769
769
|
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
770
770
|
name: "conversation.session.header.utilities",
|
|
771
771
|
id: `${PLUGIN_NAME}-${CONVERSATION_MARKDOWN_EXPORT_PATCH_ID}`,
|
|
772
|
-
order: 100
|
|
773
|
-
registrant: PLUGIN_NAME
|
|
772
|
+
order: 100
|
|
774
773
|
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ConversationMarkdownExportButton, { ...props, activation })));
|
|
775
774
|
}
|
|
776
775
|
};
|
|
@@ -1066,9 +1065,14 @@ function ModelsPageEffortPortal(props) {
|
|
|
1066
1065
|
syncButtons();
|
|
1067
1066
|
const observer = new MutationObserver(schedule);
|
|
1068
1067
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
1068
|
+
document.addEventListener("input", schedule);
|
|
1069
|
+
document.addEventListener("change", schedule);
|
|
1069
1070
|
return () => {
|
|
1070
1071
|
observer.disconnect();
|
|
1072
|
+
document.removeEventListener("input", schedule);
|
|
1073
|
+
document.removeEventListener("change", schedule);
|
|
1071
1074
|
if (frame !== null) window.cancelAnimationFrame(frame);
|
|
1075
|
+
document.querySelectorAll(`[${EFFORT_BUTTON_ATTR}]`).forEach((element) => element.remove());
|
|
1072
1076
|
};
|
|
1073
1077
|
}, [enabled, syncButtons]);
|
|
1074
1078
|
(0, import_react5.useEffect)(() => {
|
|
@@ -1115,461 +1119,24 @@ var clientPatch3 = {
|
|
|
1115
1119
|
getSnapshot: scope.getSnapshot.bind(scope),
|
|
1116
1120
|
subscribe: scope.subscribe.bind(scope),
|
|
1117
1121
|
set: scope.set.bind(scope),
|
|
1118
|
-
unset: scope.unset.bind(scope)
|
|
1122
|
+
unset: scope.unset.bind(scope),
|
|
1123
|
+
mutate: scope.mutate.bind(scope)
|
|
1119
1124
|
};
|
|
1120
1125
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
1121
1126
|
name: "shell.overlay",
|
|
1122
1127
|
id: `${PLUGIN_NAME}-${MODEL_REASONING_EFFORTS_PATCH_ID}`,
|
|
1123
|
-
order: 90
|
|
1124
|
-
registrant: PLUGIN_NAME
|
|
1128
|
+
order: 90
|
|
1125
1129
|
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ModelsPageEffortPortal, { ...props, scope: boundScope, activation })));
|
|
1126
1130
|
}
|
|
1127
1131
|
};
|
|
1128
1132
|
|
|
1129
|
-
// src/patches/
|
|
1130
|
-
var
|
|
1131
|
-
var import_react_dom = require("react-dom");
|
|
1132
|
-
var import_dsh_client_ui_primitives6 = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
1133
|
-
|
|
1134
|
-
// src/kernel/message-visibility.ts
|
|
1135
|
-
var MESSAGE_VISIBILITY_PROJECTION_KEY = "dshMoreMessageDelete";
|
|
1136
|
-
|
|
1137
|
-
// src/patches/conversation-quick-navigation/shared.ts
|
|
1138
|
-
var CONVERSATION_QUICK_NAVIGATION_PATCH_ID = "conversation-quick-navigation";
|
|
1139
|
-
|
|
1140
|
-
// src/platform/dsh/client/message-content.ts
|
|
1141
|
-
function contentText(content) {
|
|
1142
|
-
return content.filter((block) => block.type === "text").map((block) => block.text).join(" ").replace(/\s+/g, " ").trim();
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
// src/patches/conversation-quick-navigation/client/navigation.ts
|
|
1146
|
-
var MAX_LABEL_CODE_POINTS = 72;
|
|
1147
|
-
function conciseLabel(content, fallbackIndex) {
|
|
1148
|
-
const text = contentText(content);
|
|
1149
|
-
if (text === "") return `\u7B2C ${String(fallbackIndex)} \u8F6E \xB7 \u975E\u6587\u672C\u6D88\u606F`;
|
|
1150
|
-
const codePoints = [...text];
|
|
1151
|
-
if (codePoints.length <= MAX_LABEL_CODE_POINTS) return text;
|
|
1152
|
-
return `${codePoints.slice(0, MAX_LABEL_CODE_POINTS - 1).join("")}\u2026`;
|
|
1153
|
-
}
|
|
1154
|
-
function turnSummary(node, key, index) {
|
|
1155
|
-
const candidate = node;
|
|
1156
|
-
if (candidate?.kind !== "user" && candidate?.kind !== "steering") return null;
|
|
1157
|
-
if (!Number.isSafeInteger(candidate.data?.seq) || !Array.isArray(candidate.data?.content)) return null;
|
|
1158
|
-
return {
|
|
1159
|
-
key,
|
|
1160
|
-
seq: candidate.data.seq,
|
|
1161
|
-
label: conciseLabel(candidate.data.content, index)
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
function sameTurns(left, right) {
|
|
1165
|
-
return left.length === right.length && left.every((turn, index) => {
|
|
1166
|
-
const other = right[index];
|
|
1167
|
-
return other !== void 0 && turn.key === other.key && turn.seq === other.seq && turn.label === other.label;
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1170
|
-
function createConversationTurnSelector() {
|
|
1171
|
-
let previousOrder;
|
|
1172
|
-
let previous = [];
|
|
1173
|
-
return (snapshot) => {
|
|
1174
|
-
if (snapshot.chat.order === previousOrder) return previous;
|
|
1175
|
-
previousOrder = snapshot.chat.order;
|
|
1176
|
-
const next = [];
|
|
1177
|
-
for (const key of snapshot.chat.order) {
|
|
1178
|
-
const summary = turnSummary(snapshot.chat.nodes.get(key), key, next.length + 1);
|
|
1179
|
-
if (summary !== null) next.push(summary);
|
|
1180
|
-
}
|
|
1181
|
-
if (!sameTurns(previous, next)) previous = next;
|
|
1182
|
-
return previous;
|
|
1183
|
-
};
|
|
1184
|
-
}
|
|
1185
|
-
function historyWindowSignature(snapshot) {
|
|
1186
|
-
const first = snapshot.chat.order[0] ?? "";
|
|
1187
|
-
const last = snapshot.chat.order.at(-1) ?? "";
|
|
1188
|
-
return `${first}\0${last}\0${String(snapshot.chat.order.length)}`;
|
|
1189
|
-
}
|
|
1190
|
-
function shouldAutoLoadOlder(state) {
|
|
1191
|
-
return state.enabled && state.surfaceAvailable && state.hasMore && !state.loadingOlder && !state.paused;
|
|
1192
|
-
}
|
|
1193
|
-
function activeTurnAt(positions, readingLine) {
|
|
1194
|
-
let active = positions[0]?.key ?? null;
|
|
1195
|
-
for (const position of positions) {
|
|
1196
|
-
if (position.top > readingLine) break;
|
|
1197
|
-
active = position.key;
|
|
1198
|
-
}
|
|
1199
|
-
return active;
|
|
1200
|
-
}
|
|
1201
|
-
function scrollOffsetForRow(currentScrollTop, scrollportTop, rowTop, topInset = 20) {
|
|
1202
|
-
return Math.max(0, currentScrollTop + rowTop - scrollportTop - topInset);
|
|
1203
|
-
}
|
|
1133
|
+
// src/patches/session-auto-title/shared.ts
|
|
1134
|
+
var SESSION_AUTO_TITLE_PATCH_ID = "session-auto-title";
|
|
1204
1135
|
|
|
1205
|
-
// src/patches/
|
|
1206
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1207
|
-
var MAX_NO_PROGRESS_ATTEMPTS = 3;
|
|
1208
|
-
var MENU_LIST_ID = "dshmore-conversation-nav-list";
|
|
1209
|
-
var navigationCollapsedPreference = false;
|
|
1210
|
-
function conversationRow(root, key) {
|
|
1211
|
-
for (const row of root.querySelectorAll("[data-chat-flow-key]")) {
|
|
1212
|
-
if (row.dataset.chatFlowKey === key) return row;
|
|
1213
|
-
}
|
|
1214
|
-
return null;
|
|
1215
|
-
}
|
|
1216
|
-
function sessionRoot(marker) {
|
|
1217
|
-
return marker?.closest("[data-phase]") ?? null;
|
|
1218
|
-
}
|
|
1219
|
-
function conversationScrollport(marker) {
|
|
1220
|
-
return sessionRoot(marker)?.querySelector("[data-conversation-scroll]") ?? null;
|
|
1221
|
-
}
|
|
1222
|
-
function nativeLoadOlderButton(scrollport) {
|
|
1223
|
-
const flow = scrollport.querySelector("[data-chat-flow]");
|
|
1224
|
-
if (flow === null) return null;
|
|
1225
|
-
for (const child of flow.children) {
|
|
1226
|
-
if (child instanceof HTMLElement && child.dataset.chatFlowKey !== void 0) break;
|
|
1227
|
-
const button = child.querySelector("button");
|
|
1228
|
-
if (button !== null) return button;
|
|
1229
|
-
}
|
|
1230
|
-
return null;
|
|
1231
|
-
}
|
|
1232
|
-
function ConversationNavigationMenu({
|
|
1233
|
-
turns,
|
|
1234
|
-
activeKey,
|
|
1235
|
-
hasMore,
|
|
1236
|
-
loadingOlder,
|
|
1237
|
-
autoLoadPaused,
|
|
1238
|
-
collapsed,
|
|
1239
|
-
onRetry,
|
|
1240
|
-
onToggleCollapsed,
|
|
1241
|
-
onJump,
|
|
1242
|
-
listRef
|
|
1243
|
-
}) {
|
|
1244
|
-
const loading = hasMore && !autoLoadPaused;
|
|
1245
|
-
const compactStatus = autoLoadPaused ? `${String(turns.length)} \u8F6E \xB7 \u5DF2\u6682\u505C` : loading ? `${String(turns.length)} \u8F6E \xB7 \u52A0\u8F7D\u4E2D` : `${String(turns.length)} \u8F6E`;
|
|
1246
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1247
|
-
"nav",
|
|
1248
|
-
{
|
|
1249
|
-
className: "dshmore-conversation-nav-menu",
|
|
1250
|
-
"data-collapsed": collapsed ? "true" : "false",
|
|
1251
|
-
"aria-label": "\u5F53\u524D\u4F1A\u8BDD\u7684\u5BF9\u8BDD\u76EE\u5F55",
|
|
1252
|
-
children: [
|
|
1253
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("header", { className: "dshmore-conversation-nav-header", children: [
|
|
1254
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dshmore-conversation-nav-heading", children: [
|
|
1255
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dshmore-conversation-nav-title-row", children: [
|
|
1256
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dshmore-conversation-nav-title", children: "\u5BF9\u8BDD\u76EE\u5F55" }),
|
|
1257
|
-
collapsed && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dshmore-conversation-nav-compact-status", role: "status", "aria-live": "polite", children: [
|
|
1258
|
-
loading && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dshmore-conversation-nav-loading-dot", "aria-hidden": "true" }),
|
|
1259
|
-
compactStatus
|
|
1260
|
-
] })
|
|
1261
|
-
] }),
|
|
1262
|
-
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dshmore-conversation-nav-count", role: "status", "aria-live": "polite", children: [
|
|
1263
|
-
loading && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dshmore-conversation-nav-loading-dot", "aria-hidden": "true" }),
|
|
1264
|
-
autoLoadPaused ? `\u5DF2\u8F7D\u5165 ${String(turns.length)} \u8F6E\uFF0C\u81EA\u52A8\u52A0\u8F7D\u5DF2\u6682\u505C` : loading ? `\u6B63\u5728\u52A0\u8F7D\u5168\u90E8\u8BB0\u5F55 \xB7 \u5DF2\u8F7D\u5165 ${String(turns.length)} \u8F6E` : `\u5171 ${String(turns.length)} \u8F6E`
|
|
1265
|
-
] })
|
|
1266
|
-
] }),
|
|
1267
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "dshmore-conversation-nav-actions", children: [
|
|
1268
|
-
!collapsed && autoLoadPaused && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "dshmore-conversation-nav-retry", onClick: onRetry, children: "\u7EE7\u7EED\u52A0\u8F7D" }),
|
|
1269
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1270
|
-
"button",
|
|
1271
|
-
{
|
|
1272
|
-
type: "button",
|
|
1273
|
-
className: "dshmore-conversation-nav-toggle",
|
|
1274
|
-
"aria-label": collapsed ? "\u5C55\u5F00\u5BF9\u8BDD\u76EE\u5F55" : "\u6298\u53E0\u5BF9\u8BDD\u76EE\u5F55",
|
|
1275
|
-
"aria-controls": MENU_LIST_ID,
|
|
1276
|
-
"aria-expanded": !collapsed,
|
|
1277
|
-
onClick: onToggleCollapsed,
|
|
1278
|
-
children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives6.IconChevronDownOutline14, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives6.IconChevronUpOutline14, { size: 14 })
|
|
1279
|
-
}
|
|
1280
|
-
)
|
|
1281
|
-
] })
|
|
1282
|
-
] }),
|
|
1283
|
-
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { id: MENU_LIST_ID, ref: listRef, className: "dshmore-conversation-nav-list", children: [
|
|
1284
|
-
turns.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "dshmore-conversation-nav-empty", children: loadingOlder || hasMore ? "\u6B63\u5728\u8BFB\u53D6\u5386\u53F2\u8BB0\u5F55\u2026" : "\u5F53\u524D\u6CA1\u6709\u53EF\u5B9A\u4F4D\u7684\u5BF9\u8BDD" }),
|
|
1285
|
-
turns.map((turn, index) => {
|
|
1286
|
-
const active = turn.key === activeKey;
|
|
1287
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1288
|
-
"button",
|
|
1289
|
-
{
|
|
1290
|
-
type: "button",
|
|
1291
|
-
className: "dshmore-conversation-nav-item",
|
|
1292
|
-
"aria-current": active ? "location" : void 0,
|
|
1293
|
-
onClick: () => {
|
|
1294
|
-
onJump(turn.key);
|
|
1295
|
-
},
|
|
1296
|
-
children: [
|
|
1297
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dshmore-conversation-nav-index", children: String(index + 1).padStart(2, "0") }),
|
|
1298
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "dshmore-conversation-nav-label", children: turn.label })
|
|
1299
|
-
]
|
|
1300
|
-
},
|
|
1301
|
-
turn.key
|
|
1302
|
-
);
|
|
1303
|
-
})
|
|
1304
|
-
] })
|
|
1305
|
-
]
|
|
1306
|
-
}
|
|
1307
|
-
);
|
|
1308
|
-
}
|
|
1309
|
-
function ConversationQuickNavigation(props) {
|
|
1310
|
-
const settings = (0, import_react6.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot, props.activation.getSnapshot);
|
|
1311
|
-
const enabled = settings[CONVERSATION_QUICK_NAVIGATION_PATCH_ID];
|
|
1312
|
-
const selector = (0, import_react6.useMemo)(createConversationTurnSelector, [props.sessionId]);
|
|
1313
|
-
const allTurns = props.useSession(selector);
|
|
1314
|
-
const hasMore = props.useSession((snapshot) => snapshot.hasMore);
|
|
1315
|
-
const loadingOlder = props.useSession((snapshot) => snapshot.loadingOlder);
|
|
1316
|
-
const windowSignature = props.useSession(historyWindowSignature);
|
|
1317
|
-
const projected = props.useProjection(MESSAGE_VISIBILITY_PROJECTION_KEY);
|
|
1318
|
-
const hiddenSeqs = (0, import_react6.useMemo)(() => new Set(projected?.deletedSeqs ?? []), [projected]);
|
|
1319
|
-
const turns = (0, import_react6.useMemo)(
|
|
1320
|
-
() => allTurns.filter((turn) => !hiddenSeqs.has(turn.seq)),
|
|
1321
|
-
[allTurns, hiddenSeqs]
|
|
1322
|
-
);
|
|
1323
|
-
const markerRef = (0, import_react6.useRef)(null);
|
|
1324
|
-
const listRef = (0, import_react6.useRef)(null);
|
|
1325
|
-
const pendingLoadSignatureRef = (0, import_react6.useRef)(null);
|
|
1326
|
-
const noProgressAttemptsRef = (0, import_react6.useRef)(0);
|
|
1327
|
-
const [portalTarget, setPortalTarget] = (0, import_react6.useState)(null);
|
|
1328
|
-
const [activeKey, setActiveKey] = (0, import_react6.useState)(null);
|
|
1329
|
-
const [surfaceAvailable, setSurfaceAvailable] = (0, import_react6.useState)(false);
|
|
1330
|
-
const [composerInset, setComposerInset] = (0, import_react6.useState)(176);
|
|
1331
|
-
const [autoLoadPaused, setAutoLoadPaused] = (0, import_react6.useState)(false);
|
|
1332
|
-
const [loadTick, setLoadTick] = (0, import_react6.useState)(0);
|
|
1333
|
-
const [collapsed, setCollapsed] = (0, import_react6.useState)(() => navigationCollapsedPreference);
|
|
1334
|
-
(0, import_react6.useLayoutEffect)(() => {
|
|
1335
|
-
const root = sessionRoot(markerRef.current);
|
|
1336
|
-
setPortalTarget(root);
|
|
1337
|
-
if (root === null) return;
|
|
1338
|
-
const composer = root.querySelector("[data-composer-seat]");
|
|
1339
|
-
const updateInset = () => {
|
|
1340
|
-
setComposerInset(Math.max(96, (composer?.offsetHeight ?? 152) + 20));
|
|
1341
|
-
};
|
|
1342
|
-
updateInset();
|
|
1343
|
-
if (composer === null || typeof ResizeObserver === "undefined") return;
|
|
1344
|
-
const observer = new ResizeObserver(updateInset);
|
|
1345
|
-
observer.observe(composer);
|
|
1346
|
-
return () => {
|
|
1347
|
-
observer.disconnect();
|
|
1348
|
-
};
|
|
1349
|
-
}, [props.sessionId]);
|
|
1350
|
-
(0, import_react6.useEffect)(() => {
|
|
1351
|
-
pendingLoadSignatureRef.current = null;
|
|
1352
|
-
noProgressAttemptsRef.current = 0;
|
|
1353
|
-
setAutoLoadPaused(false);
|
|
1354
|
-
}, [enabled, props.sessionId]);
|
|
1355
|
-
(0, import_react6.useEffect)(() => {
|
|
1356
|
-
if (hasMore) return;
|
|
1357
|
-
pendingLoadSignatureRef.current = null;
|
|
1358
|
-
noProgressAttemptsRef.current = 0;
|
|
1359
|
-
setAutoLoadPaused(false);
|
|
1360
|
-
}, [hasMore]);
|
|
1361
|
-
(0, import_react6.useEffect)(() => {
|
|
1362
|
-
if (!enabled) {
|
|
1363
|
-
setActiveKey(null);
|
|
1364
|
-
setSurfaceAvailable(false);
|
|
1365
|
-
return;
|
|
1366
|
-
}
|
|
1367
|
-
let frame = null;
|
|
1368
|
-
let scrollport = null;
|
|
1369
|
-
const schedule = () => {
|
|
1370
|
-
if (frame !== null) return;
|
|
1371
|
-
frame = window.requestAnimationFrame(recompute);
|
|
1372
|
-
};
|
|
1373
|
-
const bindScrollport = (next) => {
|
|
1374
|
-
if (next === scrollport) return;
|
|
1375
|
-
scrollport?.removeEventListener("scroll", schedule);
|
|
1376
|
-
scrollport = next;
|
|
1377
|
-
scrollport?.addEventListener("scroll", schedule, { passive: true });
|
|
1378
|
-
};
|
|
1379
|
-
const recompute = () => {
|
|
1380
|
-
frame = null;
|
|
1381
|
-
const nextScrollport = conversationScrollport(markerRef.current);
|
|
1382
|
-
bindScrollport(nextScrollport);
|
|
1383
|
-
const flowAvailable = nextScrollport !== null && nextScrollport.querySelector("[data-chat-flow]") !== null;
|
|
1384
|
-
setSurfaceAvailable(flowAvailable);
|
|
1385
|
-
if (nextScrollport === null || !flowAvailable) {
|
|
1386
|
-
setActiveKey(null);
|
|
1387
|
-
return;
|
|
1388
|
-
}
|
|
1389
|
-
const viewport = nextScrollport.getBoundingClientRect();
|
|
1390
|
-
const readingLine = viewport.top + Math.min(120, nextScrollport.clientHeight * 0.24);
|
|
1391
|
-
const positions = [];
|
|
1392
|
-
for (const turn of turns) {
|
|
1393
|
-
const row = conversationRow(nextScrollport, turn.key);
|
|
1394
|
-
if (row !== null) positions.push({ key: turn.key, top: row.getBoundingClientRect().top });
|
|
1395
|
-
}
|
|
1396
|
-
setActiveKey(activeTurnAt(positions, readingLine));
|
|
1397
|
-
};
|
|
1398
|
-
const observer = new MutationObserver(schedule);
|
|
1399
|
-
const root = sessionRoot(markerRef.current);
|
|
1400
|
-
if (root !== null) observer.observe(root, { childList: true, subtree: true });
|
|
1401
|
-
window.addEventListener("resize", schedule);
|
|
1402
|
-
recompute();
|
|
1403
|
-
return () => {
|
|
1404
|
-
observer.disconnect();
|
|
1405
|
-
window.removeEventListener("resize", schedule);
|
|
1406
|
-
scrollport?.removeEventListener("scroll", schedule);
|
|
1407
|
-
if (frame !== null) window.cancelAnimationFrame(frame);
|
|
1408
|
-
};
|
|
1409
|
-
}, [enabled, turns]);
|
|
1410
|
-
(0, import_react6.useEffect)(() => {
|
|
1411
|
-
if (!shouldAutoLoadOlder({ enabled, surfaceAvailable, hasMore, loadingOlder, paused: autoLoadPaused })) return;
|
|
1412
|
-
const pendingSignature = pendingLoadSignatureRef.current;
|
|
1413
|
-
let delay2 = 0;
|
|
1414
|
-
if (pendingSignature !== null) {
|
|
1415
|
-
if (pendingSignature === windowSignature) {
|
|
1416
|
-
noProgressAttemptsRef.current += 1;
|
|
1417
|
-
if (noProgressAttemptsRef.current >= MAX_NO_PROGRESS_ATTEMPTS) {
|
|
1418
|
-
pendingLoadSignatureRef.current = null;
|
|
1419
|
-
setAutoLoadPaused(true);
|
|
1420
|
-
return;
|
|
1421
|
-
}
|
|
1422
|
-
delay2 = noProgressAttemptsRef.current * 350;
|
|
1423
|
-
} else {
|
|
1424
|
-
noProgressAttemptsRef.current = 0;
|
|
1425
|
-
}
|
|
1426
|
-
pendingLoadSignatureRef.current = null;
|
|
1427
|
-
}
|
|
1428
|
-
let frame = null;
|
|
1429
|
-
let retryTimer = null;
|
|
1430
|
-
let requestTimer = null;
|
|
1431
|
-
const request = () => {
|
|
1432
|
-
frame = window.requestAnimationFrame(() => {
|
|
1433
|
-
frame = null;
|
|
1434
|
-
const scrollport = conversationScrollport(markerRef.current);
|
|
1435
|
-
const button = scrollport === null ? null : nativeLoadOlderButton(scrollport);
|
|
1436
|
-
if (button === null || button.disabled) {
|
|
1437
|
-
retryTimer = window.setTimeout(() => {
|
|
1438
|
-
setLoadTick((current) => current + 1);
|
|
1439
|
-
}, 180);
|
|
1440
|
-
return;
|
|
1441
|
-
}
|
|
1442
|
-
pendingLoadSignatureRef.current = windowSignature;
|
|
1443
|
-
button.click();
|
|
1444
|
-
retryTimer = window.setTimeout(() => {
|
|
1445
|
-
setLoadTick((current) => current + 1);
|
|
1446
|
-
}, 1600);
|
|
1447
|
-
});
|
|
1448
|
-
};
|
|
1449
|
-
if (delay2 > 0) requestTimer = window.setTimeout(request, delay2);
|
|
1450
|
-
else request();
|
|
1451
|
-
return () => {
|
|
1452
|
-
if (frame !== null) window.cancelAnimationFrame(frame);
|
|
1453
|
-
if (retryTimer !== null) window.clearTimeout(retryTimer);
|
|
1454
|
-
if (requestTimer !== null) window.clearTimeout(requestTimer);
|
|
1455
|
-
};
|
|
1456
|
-
}, [autoLoadPaused, enabled, hasMore, loadTick, loadingOlder, surfaceAvailable, windowSignature]);
|
|
1457
|
-
(0, import_react6.useLayoutEffect)(() => {
|
|
1458
|
-
if (collapsed || activeKey === null) return;
|
|
1459
|
-
const list = listRef.current;
|
|
1460
|
-
const active = list?.querySelector('[aria-current="location"]');
|
|
1461
|
-
if (list === null || active === null || active === void 0) return;
|
|
1462
|
-
const top = active.offsetTop;
|
|
1463
|
-
const bottom = top + active.offsetHeight;
|
|
1464
|
-
if (top < list.scrollTop) list.scrollTop = top;
|
|
1465
|
-
else if (bottom > list.scrollTop + list.clientHeight) list.scrollTop = bottom - list.clientHeight;
|
|
1466
|
-
}, [activeKey, collapsed]);
|
|
1467
|
-
const retryAutoLoad = () => {
|
|
1468
|
-
pendingLoadSignatureRef.current = null;
|
|
1469
|
-
noProgressAttemptsRef.current = 0;
|
|
1470
|
-
setAutoLoadPaused(false);
|
|
1471
|
-
setLoadTick((current) => current + 1);
|
|
1472
|
-
};
|
|
1473
|
-
const toggleCollapsed = () => {
|
|
1474
|
-
setCollapsed((current) => {
|
|
1475
|
-
navigationCollapsedPreference = !current;
|
|
1476
|
-
return navigationCollapsedPreference;
|
|
1477
|
-
});
|
|
1478
|
-
};
|
|
1479
|
-
const jump = (key) => {
|
|
1480
|
-
const scrollport = conversationScrollport(markerRef.current);
|
|
1481
|
-
if (scrollport === null) return;
|
|
1482
|
-
const row = conversationRow(scrollport, key);
|
|
1483
|
-
if (row === null) return;
|
|
1484
|
-
const viewport = scrollport.getBoundingClientRect();
|
|
1485
|
-
const rowRect = row.getBoundingClientRect();
|
|
1486
|
-
const top = scrollOffsetForRow(scrollport.scrollTop, viewport.top, rowRect.top);
|
|
1487
|
-
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1488
|
-
scrollport.scrollTo({ top, behavior: reducedMotion ? "auto" : "smooth" });
|
|
1489
|
-
setActiveKey(key);
|
|
1490
|
-
};
|
|
1491
|
-
const rootStyle = { "--dshmore-conversation-nav-bottom": `${String(composerInset)}px` };
|
|
1492
|
-
const surface = enabled && surfaceAvailable && portalTarget !== null ? (0, import_react_dom.createPortal)(
|
|
1493
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1494
|
-
"div",
|
|
1495
|
-
{
|
|
1496
|
-
className: "dshmore-conversation-nav-root",
|
|
1497
|
-
"data-collapsed": collapsed ? "true" : "false",
|
|
1498
|
-
style: rootStyle,
|
|
1499
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1500
|
-
ConversationNavigationMenu,
|
|
1501
|
-
{
|
|
1502
|
-
turns,
|
|
1503
|
-
activeKey,
|
|
1504
|
-
hasMore,
|
|
1505
|
-
loadingOlder,
|
|
1506
|
-
autoLoadPaused,
|
|
1507
|
-
collapsed,
|
|
1508
|
-
onRetry: retryAutoLoad,
|
|
1509
|
-
onToggleCollapsed: toggleCollapsed,
|
|
1510
|
-
onJump: jump,
|
|
1511
|
-
listRef
|
|
1512
|
-
}
|
|
1513
|
-
)
|
|
1514
|
-
}
|
|
1515
|
-
),
|
|
1516
|
-
portalTarget
|
|
1517
|
-
) : null;
|
|
1518
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1519
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { ref: markerRef, className: "dshmore-conversation-nav-marker", "aria-hidden": "true" }),
|
|
1520
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: navigationStyles }),
|
|
1521
|
-
surface
|
|
1522
|
-
] });
|
|
1523
|
-
}
|
|
1524
|
-
var navigationStyles = `
|
|
1525
|
-
.dshmore-conversation-nav-marker { display: none; }
|
|
1526
|
-
.dshmore-conversation-nav-root { position: absolute; z-index: 20; right: 14px; top: 78px; bottom: var(--dshmore-conversation-nav-bottom, 176px); width: min(286px, calc(100% - 40px)); pointer-events: none; display: flex; align-items: flex-start; font-family: var(--dsw-font-family); }
|
|
1527
|
-
.dshmore-conversation-nav-root[data-collapsed="true"] { bottom: auto; height: 58px; }
|
|
1528
|
-
.dshmore-conversation-nav-menu { box-sizing: border-box; width: 100%; max-height: min(620px, 100%); min-height: 0; overflow: hidden; pointer-events: auto; display: flex; flex-direction: column; border: 1px solid var(--dsw-alias-border-l2); border-radius: 12px; color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-base); box-shadow: var(--dsw-shadow-lv1, var(--dsw-shadow-lv2)); animation: dshmore-conversation-nav-enter 150ms ease-out; }
|
|
1529
|
-
.dshmore-conversation-nav-menu[data-collapsed="true"] { height: 58px; max-height: 58px; }
|
|
1530
|
-
.dshmore-conversation-nav-header { box-sizing: border-box; flex: none; min-height: 58px; padding: 12px 12px 10px 14px; display: flex; align-items: center; justify-content: space-between; gap: 10px; border-bottom: 1px solid var(--dsw-alias-border-l3); }
|
|
1531
|
-
.dshmore-conversation-nav-menu[data-collapsed="true"] .dshmore-conversation-nav-header { height: 58px; min-height: 58px; padding: 0 12px 0 14px; border-bottom: 0; }
|
|
1532
|
-
.dshmore-conversation-nav-heading { min-width: 0; }
|
|
1533
|
-
.dshmore-conversation-nav-title-row { min-width: 0; display: flex; align-items: baseline; gap: 6px; }
|
|
1534
|
-
.dshmore-conversation-nav-title { font: var(--dsw-font-s-strong-14); }
|
|
1535
|
-
.dshmore-conversation-nav-compact-status { min-width: 0; overflow: hidden; color: var(--dsw-alias-label-caption); text-overflow: ellipsis; white-space: nowrap; font-size: 11px; line-height: 16px; }
|
|
1536
|
-
.dshmore-conversation-nav-count { margin-top: 2px; color: var(--dsw-alias-label-caption); font-size: 11px; line-height: 16px; text-wrap: pretty; }
|
|
1537
|
-
.dshmore-conversation-nav-loading-dot { width: 6px; height: 6px; margin-right: 6px; display: inline-block; border-radius: 999px; background: var(--dsw-alias-state-business-primary); vertical-align: 1px; animation: dshmore-conversation-nav-pulse 1.1s ease-in-out infinite; }
|
|
1538
|
-
.dshmore-conversation-nav-retry { flex: none; min-height: 28px; padding: 4px 9px; border: 1px solid var(--dsw-alias-border-l2); border-radius: 8px; color: var(--dsw-alias-label-secondary); background: transparent; cursor: pointer; font: inherit; font-size: 11px; }
|
|
1539
|
-
.dshmore-conversation-nav-retry:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
|
|
1540
|
-
.dshmore-conversation-nav-actions { flex: none; display: flex; align-items: center; gap: 6px; }
|
|
1541
|
-
.dshmore-conversation-nav-toggle { box-sizing: border-box; width: 28px; height: 28px; flex: none; padding: 0; display: grid; place-items: center; border: 0; border-radius: 999px; color: var(--dsw-alias-label-secondary); background: transparent; cursor: pointer; }
|
|
1542
|
-
.dshmore-conversation-nav-toggle:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
|
|
1543
|
-
.dshmore-conversation-nav-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 6px; scrollbar-width: thin; }
|
|
1544
|
-
.dshmore-conversation-nav-empty { padding: 18px 12px; color: var(--dsw-alias-label-caption); text-align: center; font-size: 12px; line-height: 18px; text-wrap: pretty; }
|
|
1545
|
-
.dshmore-conversation-nav-item { box-sizing: border-box; width: 100%; min-height: 46px; padding: 7px 9px; display: grid; grid-template-columns: 28px minmax(0, 1fr); align-items: start; gap: 2px; border: 0; border-radius: 9px; color: var(--dsw-alias-label-secondary); background: transparent; cursor: pointer; text-align: left; font-family: inherit; transition: background-color 120ms ease, color 120ms ease; }
|
|
1546
|
-
.dshmore-conversation-nav-item:hover { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover); }
|
|
1547
|
-
.dshmore-conversation-nav-item:focus-visible, .dshmore-conversation-nav-retry:focus-visible, .dshmore-conversation-nav-toggle:focus-visible { outline: 2px solid var(--dsw-alias-state-business-primary); outline-offset: -2px; }
|
|
1548
|
-
.dshmore-conversation-nav-item[aria-current="location"] { color: var(--dsw-alias-label-primary); background: var(--dsw-alias-interactive-bg-hover-solid); }
|
|
1549
|
-
.dshmore-conversation-nav-index { color: var(--dsw-alias-label-caption); font-size: 11px; line-height: 20px; font-variant-numeric: tabular-nums; }
|
|
1550
|
-
.dshmore-conversation-nav-item[aria-current="location"] .dshmore-conversation-nav-index { color: var(--dsw-alias-state-business-primary); font-weight: 600; }
|
|
1551
|
-
.dshmore-conversation-nav-label { min-width: 0; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; font-size: 13px; line-height: 20px; overflow-wrap: anywhere; text-wrap: pretty; }
|
|
1552
|
-
@keyframes dshmore-conversation-nav-enter { from { opacity: 0; transform: translateX(6px); } to { opacity: 1; transform: translateX(0); } }
|
|
1553
|
-
@keyframes dshmore-conversation-nav-pulse { 50% { opacity: .35; transform: scale(.82); } }
|
|
1554
|
-
@media (max-width: 720px) {
|
|
1555
|
-
.dshmore-conversation-nav-root { right: 8px; top: 74px; bottom: auto; width: calc(100% - 16px); height: min(220px, 32dvh); align-items: stretch; }
|
|
1556
|
-
.dshmore-conversation-nav-root[data-collapsed="true"] { height: 58px; }
|
|
1557
|
-
.dshmore-conversation-nav-menu { max-height: 100%; }
|
|
1558
|
-
}
|
|
1559
|
-
@media (prefers-reduced-motion: reduce) {
|
|
1560
|
-
.dshmore-conversation-nav-menu, .dshmore-conversation-nav-loading-dot { animation: none; }
|
|
1561
|
-
.dshmore-conversation-nav-item { transition: none; }
|
|
1562
|
-
}
|
|
1563
|
-
`;
|
|
1136
|
+
// src/patches/session-auto-title/client/index.ts
|
|
1564
1137
|
var clientPatch4 = {
|
|
1565
|
-
id:
|
|
1566
|
-
install: (
|
|
1567
|
-
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
1568
|
-
name: "conversation.session.header.utilities",
|
|
1569
|
-
id: `${PLUGIN_NAME}-${CONVERSATION_QUICK_NAVIGATION_PATCH_ID}`,
|
|
1570
|
-
order: 120,
|
|
1571
|
-
registrant: PLUGIN_NAME
|
|
1572
|
-
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ConversationQuickNavigation, { ...props, activation })));
|
|
1138
|
+
id: SESSION_AUTO_TITLE_PATCH_ID,
|
|
1139
|
+
install: () => {
|
|
1573
1140
|
}
|
|
1574
1141
|
};
|
|
1575
1142
|
|
|
@@ -1598,19 +1165,19 @@ var ClientPatchActivation = class {
|
|
|
1598
1165
|
};
|
|
1599
1166
|
|
|
1600
1167
|
// src/kernel/client/config-card.tsx
|
|
1601
|
-
var
|
|
1602
|
-
var
|
|
1603
|
-
var
|
|
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");
|
|
1604
1171
|
function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
1605
|
-
const scope = (0,
|
|
1172
|
+
const scope = (0, import_react6.useSyncExternalStore)(
|
|
1606
1173
|
activation.subscribe,
|
|
1607
1174
|
activation.getSettingsSnapshot,
|
|
1608
1175
|
activation.getSettingsSnapshot
|
|
1609
1176
|
);
|
|
1610
1177
|
const settings = activation.getSnapshot();
|
|
1611
|
-
const [open, setOpen] = (0,
|
|
1612
|
-
const [busy, setBusy] = (0,
|
|
1613
|
-
const [error, setError] = (0,
|
|
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);
|
|
1614
1181
|
if (scope.status === "unavailable") return null;
|
|
1615
1182
|
const update = async (id, enabled) => {
|
|
1616
1183
|
setBusy((current) => /* @__PURE__ */ new Set([...current, id]));
|
|
@@ -1627,9 +1194,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
|
1627
1194
|
});
|
|
1628
1195
|
}
|
|
1629
1196
|
};
|
|
1630
|
-
return /* @__PURE__ */ (0,
|
|
1631
|
-
/* @__PURE__ */ (0,
|
|
1632
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
1633
1200
|
"button",
|
|
1634
1201
|
{
|
|
1635
1202
|
type: "button",
|
|
@@ -1640,23 +1207,23 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
|
1640
1207
|
setOpen((current) => !current);
|
|
1641
1208
|
},
|
|
1642
1209
|
children: [
|
|
1643
|
-
/* @__PURE__ */ (0,
|
|
1644
|
-
/* @__PURE__ */ (0,
|
|
1645
|
-
/* @__PURE__ */ (0,
|
|
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" })
|
|
1646
1213
|
] }),
|
|
1647
|
-
/* @__PURE__ */ (0,
|
|
1214
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dsh_client_ui_primitives6.IconChevronDownOutline14, { className: `dshmore-config-chevron${open ? " dshmore-config-chevron-open" : ""}` })
|
|
1648
1215
|
]
|
|
1649
1216
|
}
|
|
1650
1217
|
),
|
|
1651
|
-
open && /* @__PURE__ */ (0,
|
|
1652
|
-
/* @__PURE__ */ (0,
|
|
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) => {
|
|
1653
1220
|
const waiting = busy.has(patch.id);
|
|
1654
|
-
return /* @__PURE__ */ (0,
|
|
1655
|
-
/* @__PURE__ */ (0,
|
|
1656
|
-
/* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
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 })
|
|
1658
1225
|
] }),
|
|
1659
|
-
/* @__PURE__ */ (0,
|
|
1226
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1660
1227
|
"input",
|
|
1661
1228
|
{
|
|
1662
1229
|
type: "checkbox",
|
|
@@ -1671,9 +1238,9 @@ function PatchConfigCard({ activation, initiallyOpen = false }) {
|
|
|
1671
1238
|
)
|
|
1672
1239
|
] }, patch.id);
|
|
1673
1240
|
}) }),
|
|
1674
|
-
scope.status === "loading" && /* @__PURE__ */ (0,
|
|
1675
|
-
scope.status === "ready" && !scope.writable && /* @__PURE__ */ (0,
|
|
1676
|
-
error !== null && /* @__PURE__ */ (0,
|
|
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 })
|
|
1677
1244
|
] })
|
|
1678
1245
|
] });
|
|
1679
1246
|
}
|
|
@@ -1681,13 +1248,22 @@ function installPatchConfigCard(ctx, activation) {
|
|
|
1681
1248
|
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
|
1682
1249
|
name: "settings.plugin.item",
|
|
1683
1250
|
key: PATCH_SETTINGS_NAMESPACE,
|
|
1684
|
-
priority: 90
|
|
1685
|
-
|
|
1686
|
-
|
|
1251
|
+
priority: 90
|
|
1252
|
+
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PatchConfigCard, { ...props, activation })));
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// src/kernel/message-visibility.ts
|
|
1256
|
+
var MESSAGE_VISIBILITY_PROJECTION_KEY = "dshMoreMessageDelete";
|
|
1257
|
+
|
|
1258
|
+
// src/platform/dsh/client/message-targets.tsx
|
|
1259
|
+
var import_react7 = require("react");
|
|
1260
|
+
|
|
1261
|
+
// src/platform/dsh/client/message-content.ts
|
|
1262
|
+
function contentText(content) {
|
|
1263
|
+
return content.filter((block) => block.type === "text").map((block) => block.text).join(" ").replace(/\s+/g, " ").trim();
|
|
1687
1264
|
}
|
|
1688
1265
|
|
|
1689
1266
|
// src/platform/dsh/client/message-targets.tsx
|
|
1690
|
-
var import_react8 = require("react");
|
|
1691
1267
|
var EMPTY_MESSAGE_SURFACE = {
|
|
1692
1268
|
rows: [],
|
|
1693
1269
|
byKey: /* @__PURE__ */ new Map()
|
|
@@ -1727,13 +1303,10 @@ function createMessageSurfaceSelector(active = true) {
|
|
|
1727
1303
|
if (!active) return () => EMPTY_MESSAGE_SURFACE;
|
|
1728
1304
|
const nodeCache = /* @__PURE__ */ new WeakMap();
|
|
1729
1305
|
let previous = EMPTY_MESSAGE_SURFACE;
|
|
1730
|
-
let previousOrder;
|
|
1731
1306
|
return (snapshot) => {
|
|
1732
|
-
if (snapshot.chat.order === previousOrder) return previous;
|
|
1733
|
-
previousOrder = snapshot.chat.order;
|
|
1734
1307
|
const rows = [];
|
|
1735
|
-
for (const key of snapshot.
|
|
1736
|
-
const node = snapshot.
|
|
1308
|
+
for (const key of snapshot.order) {
|
|
1309
|
+
const node = snapshot.nodes.get(key);
|
|
1737
1310
|
if (node === void 0) continue;
|
|
1738
1311
|
let row = nodeCache.get(node);
|
|
1739
1312
|
if (row === void 0) {
|
|
@@ -1755,8 +1328,8 @@ function createMessageSurfaceSelector(active = true) {
|
|
|
1755
1328
|
function hostForRow(row, kind) {
|
|
1756
1329
|
const existing = row.querySelector(":scope [data-dshmore-message-actions]");
|
|
1757
1330
|
if (kind === "assistant") {
|
|
1758
|
-
const turnRoot = row.querySelector("[data-turn-tail][data-
|
|
1759
|
-
const copyButton2 = turnRoot?.querySelector('button[aria-label="\u590D\u5236"], button[aria-label="Copy"]');
|
|
1331
|
+
const turnRoot = row.querySelector("[data-turn-tail][data-actions-reveal]");
|
|
1332
|
+
const copyButton2 = turnRoot?.querySelector('button[aria-label="\u590D\u5236"], button[aria-label="Copy"], button[aria-label="\u5DF2\u590D\u5236"], button[aria-label="Copied"]');
|
|
1760
1333
|
const builtInActions2 = copyButton2?.parentElement;
|
|
1761
1334
|
const placeBeforeClock = (host3) => {
|
|
1762
1335
|
if (builtInActions2 === void 0 || builtInActions2 === null) return;
|
|
@@ -1780,7 +1353,7 @@ function hostForRow(row, kind) {
|
|
|
1780
1353
|
else row.appendChild(host2);
|
|
1781
1354
|
return host2;
|
|
1782
1355
|
}
|
|
1783
|
-
const copyButton = row.querySelector('button[aria-label="\u590D\u5236"], button[aria-label="Copy"]');
|
|
1356
|
+
const copyButton = row.querySelector('button[aria-label="\u590D\u5236"], button[aria-label="Copy"], button[aria-label="\u5DF2\u590D\u5236"], button[aria-label="Copied"]');
|
|
1784
1357
|
const builtInActions = copyButton?.parentElement;
|
|
1785
1358
|
if (existing !== null) {
|
|
1786
1359
|
if (builtInActions !== void 0 && builtInActions !== null && (existing.parentElement !== builtInActions || existing.nextElementSibling !== copyButton)) {
|
|
@@ -1821,17 +1394,17 @@ function trajectorySourceSeq(row) {
|
|
|
1821
1394
|
return Number.isSafeInteger(seq) && seq >= 0 ? seq : void 0;
|
|
1822
1395
|
}
|
|
1823
1396
|
function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = true) {
|
|
1824
|
-
const selector = (0,
|
|
1825
|
-
const surface = props.
|
|
1826
|
-
const surfaceRef = (0,
|
|
1827
|
-
const hiddenSeqsRef = (0,
|
|
1828
|
-
const hiddenTrajectoryKeysRef = (0,
|
|
1397
|
+
const selector = (0, import_react7.useMemo)(() => createMessageSurfaceSelector(active), [active, props.sessionId]);
|
|
1398
|
+
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);
|
|
1829
1402
|
surfaceRef.current = surface;
|
|
1830
1403
|
hiddenSeqsRef.current = hiddenSeqs;
|
|
1831
1404
|
hiddenTrajectoryKeysRef.current = hiddenTrajectoryKeys;
|
|
1832
|
-
const [targets, setTargets] = (0,
|
|
1833
|
-
const requestFullScanRef = (0,
|
|
1834
|
-
(0,
|
|
1405
|
+
const [targets, setTargets] = (0, import_react7.useState)([]);
|
|
1406
|
+
const requestFullScanRef = (0, import_react7.useRef)(null);
|
|
1407
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
1835
1408
|
if (!active) {
|
|
1836
1409
|
setTargets((current) => current.length === 0 ? current : []);
|
|
1837
1410
|
return;
|
|
@@ -1935,7 +1508,10 @@ function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = tru
|
|
|
1935
1508
|
requestFullScanRef.current = requestFullScan;
|
|
1936
1509
|
const observer = new MutationObserver((records) => {
|
|
1937
1510
|
for (const record of records) {
|
|
1938
|
-
if (record.removedNodes.length > 0)
|
|
1511
|
+
if (record.removedNodes.length > 0) {
|
|
1512
|
+
pruneDisconnected = true;
|
|
1513
|
+
collectRows(record.target);
|
|
1514
|
+
}
|
|
1939
1515
|
record.addedNodes.forEach(collectRows);
|
|
1940
1516
|
}
|
|
1941
1517
|
if (pendingChatRows.size > 0 || pendingTrajectoryRows.size > 0 || pruneDisconnected) schedule();
|
|
@@ -1951,22 +1527,22 @@ function useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, active = tru
|
|
|
1951
1527
|
}
|
|
1952
1528
|
for (const host of document.querySelectorAll("[data-dshmore-message-actions]")) host.remove();
|
|
1953
1529
|
};
|
|
1954
|
-
}, [active]);
|
|
1955
|
-
(0,
|
|
1530
|
+
}, [active, props.sessionId]);
|
|
1531
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
1956
1532
|
requestFullScanRef.current?.();
|
|
1957
1533
|
}, [surface, hiddenSeqs, hiddenTrajectoryKeys]);
|
|
1958
1534
|
return targets;
|
|
1959
1535
|
}
|
|
1960
1536
|
|
|
1961
1537
|
// src/client/index.tsx
|
|
1962
|
-
var
|
|
1538
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1963
1539
|
var inject = ["slots", "sessions", "workspaces", "settingsScope"];
|
|
1964
1540
|
function MessageActionPatchController({ patch, props, targets, enabled }) {
|
|
1965
1541
|
const actions = patch.useActions(props, enabled);
|
|
1966
1542
|
const style = { "--dshmore-action-order": patch.order };
|
|
1967
|
-
return /* @__PURE__ */ (0,
|
|
1968
|
-
enabled && targets.map((target) => (0,
|
|
1969
|
-
/* @__PURE__ */ (0,
|
|
1543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1544
|
+
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) }),
|
|
1970
1546
|
target.host,
|
|
1971
1547
|
`${patch.id}:${target.key}`
|
|
1972
1548
|
)),
|
|
@@ -1974,15 +1550,15 @@ function MessageActionPatchController({ patch, props, targets, enabled }) {
|
|
|
1974
1550
|
] });
|
|
1975
1551
|
}
|
|
1976
1552
|
function MessageActionsController(props) {
|
|
1977
|
-
const settings = (0,
|
|
1553
|
+
const settings = (0, import_react8.useSyncExternalStore)(props.activation.subscribe, props.activation.getSnapshot);
|
|
1978
1554
|
const projected = props.useProjection(MESSAGE_VISIBILITY_PROJECTION_KEY);
|
|
1979
|
-
const hiddenSeqs = (0,
|
|
1980
|
-
const hiddenTrajectoryKeys = (0,
|
|
1555
|
+
const hiddenSeqs = (0, import_react8.useMemo)(() => new Set(projected?.deletedSeqs ?? []), [projected]);
|
|
1556
|
+
const hiddenTrajectoryKeys = (0, import_react8.useMemo)(() => new Set(projected?.hiddenTrajectoryKeys ?? []), [projected]);
|
|
1981
1557
|
const messageActionsEnabled = MESSAGE_ACTION_PATCHES.some((patch) => settings[patch.id]);
|
|
1982
1558
|
const targets = useMessageTargets(props, hiddenSeqs, hiddenTrajectoryKeys, messageActionsEnabled);
|
|
1983
|
-
return /* @__PURE__ */ (0,
|
|
1984
|
-
/* @__PURE__ */ (0,
|
|
1985
|
-
MESSAGE_ACTION_PATCHES.map((patch) => /* @__PURE__ */ (0,
|
|
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)(
|
|
1986
1562
|
MessageActionPatchController,
|
|
1987
1563
|
{
|
|
1988
1564
|
patch,
|
|
@@ -2004,9 +1580,8 @@ function apply(ctx) {
|
|
|
2004
1580
|
ctx.slots.inject("conversation.session.header.utilities", () => ctx.slots.register({
|
|
2005
1581
|
name: "conversation.session.header.utilities",
|
|
2006
1582
|
id: `${PLUGIN_NAME}-message-actions`,
|
|
2007
|
-
order: 90
|
|
2008
|
-
|
|
2009
|
-
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MessageActionsController, { ...props, ctx, activation })));
|
|
1583
|
+
order: 90
|
|
1584
|
+
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MessageActionsController, { ...props, ctx, activation })));
|
|
2010
1585
|
for (const patch of CLIENT_PATCHES) patch.install(ctx, activation);
|
|
2011
1586
|
}
|
|
2012
1587
|
return module.exports; } });
|