@aipanel/dsh-client 1.2.4 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +340 -25
- package/package.json +8 -4
package/lib/client.js
CHANGED
|
@@ -26,13 +26,275 @@ var index_exports = {};
|
|
|
26
26
|
__export(index_exports, {
|
|
27
27
|
INSERT_ELEMENT_EVENT: () => INSERT_ELEMENT_EVENT,
|
|
28
28
|
SESSION_READY_EVENT: () => SESSION_READY_EVENT,
|
|
29
|
-
apply: () => apply
|
|
29
|
+
apply: () => apply,
|
|
30
|
+
inject: () => inject
|
|
30
31
|
});
|
|
31
32
|
module.exports = __toCommonJS(index_exports);
|
|
33
|
+
|
|
34
|
+
// dsh-client/src/client/diagnostics-view.tsx
|
|
35
|
+
var import_react = require("react");
|
|
36
|
+
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
37
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
38
|
+
var DIAGNOSTICS_STORAGE_KEY = "dsh.bridge.diagnostics.enabled";
|
|
39
|
+
function readDiagnostics(block) {
|
|
40
|
+
if (typeof block !== "object" || block === null) return void 0;
|
|
41
|
+
const settled = block;
|
|
42
|
+
if (settled.kind !== "tool-result") return void 0;
|
|
43
|
+
const meta = settled.meta;
|
|
44
|
+
const diagnostics = meta?.diagnostics;
|
|
45
|
+
if (!Array.isArray(diagnostics)) return void 0;
|
|
46
|
+
return diagnostics.every(isEntry) ? diagnostics : void 0;
|
|
47
|
+
}
|
|
48
|
+
function extractBlockText(block) {
|
|
49
|
+
if (typeof block !== "object" || block === null) return "";
|
|
50
|
+
const settled = block;
|
|
51
|
+
if (!Array.isArray(settled.content)) return "";
|
|
52
|
+
return (settled.content ?? []).filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("\n");
|
|
53
|
+
}
|
|
54
|
+
function isEntry(d) {
|
|
55
|
+
const e = d;
|
|
56
|
+
return !!e && typeof e.file === "string" && typeof e.line === "number" && typeof e.column === "number" && (e.severity === "error" || e.severity === "warning") && typeof e.message === "string";
|
|
57
|
+
}
|
|
58
|
+
function relativize(path, cwd) {
|
|
59
|
+
if (!cwd) return path;
|
|
60
|
+
const root = cwd.replace(/[/\\]+$/, "");
|
|
61
|
+
if (path.startsWith(`${root}/`) || path.startsWith(`${root}\\`)) {
|
|
62
|
+
return path.slice(root.length + 1);
|
|
63
|
+
}
|
|
64
|
+
return path;
|
|
65
|
+
}
|
|
66
|
+
var styles = {
|
|
67
|
+
sep: {
|
|
68
|
+
background: "var(--dsw-alias-label-caption)",
|
|
69
|
+
borderRadius: 1,
|
|
70
|
+
flex: "none",
|
|
71
|
+
width: 2,
|
|
72
|
+
height: 2,
|
|
73
|
+
margin: "0 8px"
|
|
74
|
+
},
|
|
75
|
+
summary: {
|
|
76
|
+
textOverflow: "ellipsis",
|
|
77
|
+
whiteSpace: "nowrap",
|
|
78
|
+
minWidth: 0,
|
|
79
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
80
|
+
flex: "auto",
|
|
81
|
+
fontSize: 12,
|
|
82
|
+
lineHeight: 24,
|
|
83
|
+
overflow: "hidden"
|
|
84
|
+
},
|
|
85
|
+
diagnostic: {
|
|
86
|
+
display: "flex",
|
|
87
|
+
alignItems: "flex-start",
|
|
88
|
+
gap: 8,
|
|
89
|
+
padding: "5px 0 5px 4px"
|
|
90
|
+
},
|
|
91
|
+
card: {
|
|
92
|
+
display: "flex",
|
|
93
|
+
flexDirection: "column",
|
|
94
|
+
gap: 2,
|
|
95
|
+
margin: "4px 0 4px 4px",
|
|
96
|
+
padding: "8px 12px",
|
|
97
|
+
borderRadius: 12,
|
|
98
|
+
background: "var(--dsw-alias-markdown-code-block)"
|
|
99
|
+
},
|
|
100
|
+
cardHead: {
|
|
101
|
+
display: "flex",
|
|
102
|
+
alignItems: "center",
|
|
103
|
+
justifyContent: "space-between",
|
|
104
|
+
gap: 8,
|
|
105
|
+
paddingBottom: 6,
|
|
106
|
+
marginBottom: 4,
|
|
107
|
+
borderBottom: "1px solid var(--dsw-alias-border-l1)"
|
|
108
|
+
},
|
|
109
|
+
cardTitle: {
|
|
110
|
+
color: "var(--dsw-alias-label-primary)",
|
|
111
|
+
fontWeight: 600,
|
|
112
|
+
fontSize: 12,
|
|
113
|
+
lineHeight: 1.4
|
|
114
|
+
},
|
|
115
|
+
scopeBadge: {
|
|
116
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
117
|
+
fontSize: 11,
|
|
118
|
+
lineHeight: 1,
|
|
119
|
+
padding: "3px 8px",
|
|
120
|
+
borderRadius: 999,
|
|
121
|
+
border: "1px solid var(--dsw-alias-border-l2)"
|
|
122
|
+
},
|
|
123
|
+
target: {
|
|
124
|
+
display: "block",
|
|
125
|
+
width: "100%",
|
|
126
|
+
textAlign: "left",
|
|
127
|
+
border: "none",
|
|
128
|
+
background: "none",
|
|
129
|
+
padding: "0 0 4px 0",
|
|
130
|
+
margin: "0 0 4px 0",
|
|
131
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
132
|
+
fontSize: 12,
|
|
133
|
+
fontFamily: "var(--ds-font-family-code, ui-monospace, SFMono-Regular, Menlo, monospace)",
|
|
134
|
+
cursor: "pointer",
|
|
135
|
+
textDecoration: "underline"
|
|
136
|
+
},
|
|
137
|
+
targetText: {
|
|
138
|
+
display: "block",
|
|
139
|
+
padding: "0 0 4px 0",
|
|
140
|
+
margin: "0 0 4px 0",
|
|
141
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
142
|
+
fontSize: 12,
|
|
143
|
+
fontFamily: "var(--ds-font-family-code, ui-monospace, SFMono-Regular, Menlo, monospace)"
|
|
144
|
+
},
|
|
145
|
+
marker: { flex: "0 0 auto", width: 14, textAlign: "center", fontSize: 12, lineHeight: 1.6 },
|
|
146
|
+
diagBody: {
|
|
147
|
+
flex: 1,
|
|
148
|
+
minWidth: 0,
|
|
149
|
+
display: "flex",
|
|
150
|
+
flexDirection: "column",
|
|
151
|
+
gap: 3
|
|
152
|
+
},
|
|
153
|
+
loc: {
|
|
154
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
155
|
+
fontSize: 12,
|
|
156
|
+
lineHeight: 1.4
|
|
157
|
+
},
|
|
158
|
+
msg: {
|
|
159
|
+
color: "var(--dsw-alias-label-primary)",
|
|
160
|
+
fontSize: 12,
|
|
161
|
+
lineHeight: 1.6,
|
|
162
|
+
whiteSpace: "pre-wrap",
|
|
163
|
+
wordBreak: "break-word"
|
|
164
|
+
},
|
|
165
|
+
successMsg: {
|
|
166
|
+
color: "var(--dsw-alias-state-success-primary)",
|
|
167
|
+
fontSize: 12,
|
|
168
|
+
lineHeight: 1.6
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
function DiagnosticsRow({ block, cwd, toolName, openFile }) {
|
|
172
|
+
const diagnostics = readDiagnostics(block);
|
|
173
|
+
const [expanded, setExpanded] = (0, import_react.useState)(false);
|
|
174
|
+
const isSettled = block?.kind === "tool-result";
|
|
175
|
+
const hasDiagnostics = typeof diagnostics !== "undefined" && diagnostics.length > 0;
|
|
176
|
+
const errors = (diagnostics ?? []).filter((d) => d.severity === "error");
|
|
177
|
+
const warnings = (diagnostics ?? []).filter((d) => d.severity === "warning");
|
|
178
|
+
const contentText = extractBlockText(block);
|
|
179
|
+
const firstLine = (contentText.split("\n")[0] || "").trim();
|
|
180
|
+
const isFullProject = /^全量诊断结果/.test(firstLine);
|
|
181
|
+
const scope = isFullProject ? "project" : "file";
|
|
182
|
+
const scopeLabel = isFullProject ? "\u5168\u91CF" : "\u5355\u6587\u4EF6";
|
|
183
|
+
const cardTitle = "\u8BCA\u65AD\u7ED3\u679C";
|
|
184
|
+
const titleFileMatch = /^诊断结果:\s*(.+)$/.exec(firstLine);
|
|
185
|
+
const targetFile = scope === "file" && diagnostics && diagnostics.length > 0 ? diagnostics[0].file : null;
|
|
186
|
+
const targetDisplay = scope === "file" ? targetFile ? relativize(targetFile, cwd) : titleFileMatch ? titleFileMatch[1].trim() : null : null;
|
|
187
|
+
const errColor = "var(--dsw-alias-state-error-primary)";
|
|
188
|
+
const warnColor = "var(--dsw-alias-state-warn-primary)";
|
|
189
|
+
const state = !isSettled ? "ongoing" : errors.length > 0 ? "error" : warnings.length > 0 ? "warning" : "done";
|
|
190
|
+
const expandable = isSettled;
|
|
191
|
+
let collapsed;
|
|
192
|
+
if (hasDiagnostics) {
|
|
193
|
+
collapsed = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
194
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sep, "aria-hidden": true }),
|
|
195
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.summary, children: [
|
|
196
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--dsw-alias-label-tertiary)" }, children: scopeLabel }),
|
|
197
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, children: " \xB7 " }),
|
|
198
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { color: errColor }, children: [
|
|
199
|
+
errors.length,
|
|
200
|
+
" \u9519\u8BEF"
|
|
201
|
+
] }),
|
|
202
|
+
" \xB7",
|
|
203
|
+
" ",
|
|
204
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: { color: warnColor }, children: [
|
|
205
|
+
warnings.length,
|
|
206
|
+
" \u8B66\u544A"
|
|
207
|
+
] })
|
|
208
|
+
] })
|
|
209
|
+
] });
|
|
210
|
+
} else if (!isSettled) {
|
|
211
|
+
collapsed = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
212
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sep, "aria-hidden": true }),
|
|
213
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.summary, children: "\u8BCA\u65AD\u8FD0\u884C\u4E2D\u2026" })
|
|
214
|
+
] });
|
|
215
|
+
} else if (diagnostics && diagnostics.length === 0) {
|
|
216
|
+
collapsed = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
217
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sep, "aria-hidden": true }),
|
|
218
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.summary, children: [
|
|
219
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--dsw-alias-label-tertiary)" }, children: scopeLabel }),
|
|
220
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": true, children: " \xB7 " }),
|
|
221
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "var(--dsw-alias-state-success-primary)" }, children: "\u672A\u53D1\u73B0\u95EE\u9898" })
|
|
222
|
+
] })
|
|
223
|
+
] });
|
|
224
|
+
} else {
|
|
225
|
+
collapsed = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
226
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sep, "aria-hidden": true }),
|
|
227
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.summary, children: extractBlockText(block) || "\u65E0\u8F93\u51FA" })
|
|
228
|
+
] });
|
|
229
|
+
}
|
|
230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
231
|
+
import_dsh_client_ui_primitives.DisclosureRow,
|
|
232
|
+
{
|
|
233
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.StateDot, { state }),
|
|
234
|
+
title: toolName,
|
|
235
|
+
open: expanded,
|
|
236
|
+
expandable,
|
|
237
|
+
expandOnRowClick: expandable,
|
|
238
|
+
keepContentWhenOpen: true,
|
|
239
|
+
onToggle: () => setExpanded((v) => !v),
|
|
240
|
+
collapsedContent: collapsed,
|
|
241
|
+
children: expandable && expanded ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.card, children: [
|
|
242
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.cardHead, children: [
|
|
243
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.cardTitle, children: cardTitle }),
|
|
244
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.scopeBadge, children: scopeLabel })
|
|
245
|
+
] }),
|
|
246
|
+
scope === "file" && targetDisplay ? targetFile && typeof openFile === "function" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", style: styles.target, onClick: () => openFile(targetFile), children: targetDisplay }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.targetText, children: targetDisplay }) : null,
|
|
247
|
+
hasDiagnostics ? diagnostics.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.diagnostic, children: [
|
|
248
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
249
|
+
"span",
|
|
250
|
+
{
|
|
251
|
+
style: {
|
|
252
|
+
...styles.marker,
|
|
253
|
+
color: d.severity === "error" ? errColor : warnColor
|
|
254
|
+
},
|
|
255
|
+
children: d.severity === "error" ? "\u2716" : "\u26A0"
|
|
256
|
+
}
|
|
257
|
+
),
|
|
258
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.diagBody, children: [
|
|
259
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.loc, children: [
|
|
260
|
+
relativize(d.file, cwd),
|
|
261
|
+
":",
|
|
262
|
+
d.line,
|
|
263
|
+
":",
|
|
264
|
+
d.column
|
|
265
|
+
] }),
|
|
266
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.msg, children: d.message })
|
|
267
|
+
] })
|
|
268
|
+
] }, i)) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.successMsg, children: "\u672A\u53D1\u73B0\u95EE\u9898" })
|
|
269
|
+
] }) : null
|
|
270
|
+
}
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
function registerDiagnosticsView(ctx) {
|
|
274
|
+
try {
|
|
275
|
+
if (localStorage.getItem(DIAGNOSTICS_STORAGE_KEY) !== "1") return;
|
|
276
|
+
} catch {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const slots = ctx.slots;
|
|
280
|
+
if (!slots) return;
|
|
281
|
+
slots.inject("tool.call.toolview", function* () {
|
|
282
|
+
yield slots.register({ name: "tool.call.toolview", key: "run_diagnostics" }, DiagnosticsRow);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// dsh-client/src/client/index.ts
|
|
32
287
|
var SELECTION_STORAGE_KEY = "dsh.bridge.selection";
|
|
288
|
+
var inject = ["slots"];
|
|
33
289
|
var SESSION_READY_EVENT = "aipanel:session-ready";
|
|
34
290
|
var INSERT_ELEMENT_EVENT = "aipanel:insert-element";
|
|
35
291
|
var SESSION_SETTLE_MS = 400;
|
|
292
|
+
function ensureNodeId(e) {
|
|
293
|
+
if (e.id) return e.id;
|
|
294
|
+
const random = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID().replace(/-/g, "").slice(0, 8) : Math.random().toString(36).slice(2, 10);
|
|
295
|
+
e.id = `n${random}`;
|
|
296
|
+
return e.id;
|
|
297
|
+
}
|
|
36
298
|
function elementLabel(e) {
|
|
37
299
|
if (e.description) return e.description;
|
|
38
300
|
const text = e.innerText?.trim();
|
|
@@ -46,24 +308,19 @@ function serializeElement(ref) {
|
|
|
46
308
|
try {
|
|
47
309
|
const e = JSON.parse(ref);
|
|
48
310
|
if (!e || typeof e !== "object") throw new Error("not an element payload");
|
|
49
|
-
|
|
50
|
-
const selector = safe(e.description || "element");
|
|
51
|
-
const text = e.innerText?.trim();
|
|
52
|
-
const textPreview = text ? text.length > 5 ? text.slice(0, 5) + "..." : text : "";
|
|
53
|
-
const body = `\u9009\u4E2D\u5143\u7D20:${selector}${textPreview ? `(${safe(textPreview)})` : ""}`;
|
|
54
|
-
return `@"${body}"`;
|
|
311
|
+
return `@\u8282\u70B9[${ensureNodeId(e)}]`;
|
|
55
312
|
} catch {
|
|
56
313
|
return `@${ref}`;
|
|
57
314
|
}
|
|
58
315
|
}
|
|
59
316
|
function toReference(e) {
|
|
60
|
-
const
|
|
317
|
+
const mark = `\u8282\u70B9[${ensureNodeId(e)}]`;
|
|
61
318
|
return {
|
|
62
319
|
source: "aipanel",
|
|
63
320
|
ref: elementContextRef(e),
|
|
64
|
-
label,
|
|
321
|
+
label: mark,
|
|
65
322
|
appearance: "file",
|
|
66
|
-
clipboardText:
|
|
323
|
+
clipboardText: `@${mark}`
|
|
67
324
|
};
|
|
68
325
|
}
|
|
69
326
|
function toCandidate(e) {
|
|
@@ -85,6 +342,7 @@ function readSelectionCandidates() {
|
|
|
85
342
|
}
|
|
86
343
|
}
|
|
87
344
|
function apply(ctx) {
|
|
345
|
+
registerDiagnosticsView(ctx);
|
|
88
346
|
const inputTriggers = ctx.get("inputTriggers");
|
|
89
347
|
if (!inputTriggers) return;
|
|
90
348
|
const source = {
|
|
@@ -101,16 +359,35 @@ function apply(ctx) {
|
|
|
101
359
|
(c) => c.name.toLowerCase().includes(query) || (c.description ?? "").toLowerCase().includes(query)
|
|
102
360
|
);
|
|
103
361
|
},
|
|
104
|
-
// 选定 → 铸造 file 引用:ref/label 分离(label 短,ref
|
|
105
|
-
onPick: (pick) =>
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
362
|
+
// 选定 → 铸造 file 引用:ref/label 分离(label 短,ref 携带完整元素 + 节点 id)
|
|
363
|
+
onPick: (pick) => {
|
|
364
|
+
try {
|
|
365
|
+
const parsed = JSON.parse(pick.candidate.value ?? "null");
|
|
366
|
+
if (parsed) {
|
|
367
|
+
ensureNodeId(parsed);
|
|
368
|
+
return {
|
|
369
|
+
insert: {
|
|
370
|
+
source: "aipanel",
|
|
371
|
+
ref: JSON.stringify(parsed),
|
|
372
|
+
label: pick.candidate.name,
|
|
373
|
+
appearance: "file",
|
|
374
|
+
// clipboardText 以 @ 开头(dsh backdrop 取首字符作 chip 触发 glyph)
|
|
375
|
+
clipboardText: `@${pick.candidate.name}`
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
} catch {
|
|
112
380
|
}
|
|
113
|
-
|
|
381
|
+
return {
|
|
382
|
+
insert: {
|
|
383
|
+
source: "aipanel",
|
|
384
|
+
ref: pick.candidate.value ?? pick.candidate.name,
|
|
385
|
+
label: pick.candidate.name,
|
|
386
|
+
appearance: "file",
|
|
387
|
+
clipboardText: `@${pick.candidate.name}`
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
},
|
|
114
391
|
// 模型投影
|
|
115
392
|
codec: {
|
|
116
393
|
clipboardText: (ref) => ref,
|
|
@@ -161,16 +438,54 @@ function apply(ctx) {
|
|
|
161
438
|
const current = sessions?.list?.getSnapshot()?.current;
|
|
162
439
|
if (!current) return;
|
|
163
440
|
try {
|
|
164
|
-
const actx = sessions
|
|
441
|
+
const actx = sessions?.scope?.(current);
|
|
442
|
+
if (!actx) return;
|
|
165
443
|
const input = conversation?.input?.for?.(actx);
|
|
166
444
|
if (!input || typeof input.insertReference !== "function") return;
|
|
167
445
|
const snapshot = input.state?.getSnapshot?.();
|
|
168
446
|
if (!snapshot) return;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
447
|
+
let start = snapshot.draft.length;
|
|
448
|
+
let end = snapshot.draft.length;
|
|
449
|
+
try {
|
|
450
|
+
const el = document.querySelector("textarea[data-phase]");
|
|
451
|
+
if (el && el.value === snapshot.draft) {
|
|
452
|
+
const s = el.selectionStart ?? 0;
|
|
453
|
+
const e = el.selectionEnd ?? s;
|
|
454
|
+
start = Math.min(s, snapshot.draft.length);
|
|
455
|
+
end = Math.min(e, snapshot.draft.length);
|
|
456
|
+
}
|
|
457
|
+
} catch {
|
|
458
|
+
}
|
|
459
|
+
const reference = toReference(element);
|
|
460
|
+
const gap = snapshot.draft.slice(end)[0] === " " ? 0 : 1;
|
|
461
|
+
const insertedLen = reference.clipboardText.length + gap;
|
|
462
|
+
let leadingSpace = 0;
|
|
463
|
+
let rev = snapshot.draftRev;
|
|
464
|
+
const insertable = input;
|
|
465
|
+
if (start > 0 && !/\s/.test(snapshot.draft[start - 1])) {
|
|
466
|
+
try {
|
|
467
|
+
if (insertable.insertText?.(" ", { start, end, draftRev: rev })) {
|
|
468
|
+
const next = input.state?.getSnapshot?.();
|
|
469
|
+
if (next) {
|
|
470
|
+
leadingSpace = 1;
|
|
471
|
+
start += 1;
|
|
472
|
+
end += 1;
|
|
473
|
+
rev = next.draftRev;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
} catch {
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
input.insertReference(reference, { start, end, draftRev: rev });
|
|
480
|
+
requestAnimationFrame(() => {
|
|
481
|
+
try {
|
|
482
|
+
const el = document.querySelector("textarea[data-phase]");
|
|
483
|
+
if (!el) return;
|
|
484
|
+
const caret = Math.min(start + insertedLen + leadingSpace, el.value.length);
|
|
485
|
+
el.focus();
|
|
486
|
+
el.setSelectionRange(caret, caret);
|
|
487
|
+
} catch {
|
|
488
|
+
}
|
|
174
489
|
});
|
|
175
490
|
} catch {
|
|
176
491
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aipanel/dsh-client",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AIPanel 浏览器侧插件(dsh web Web Client):注册 @aipanel 文件引用 source,选中元素以 file chip 高亮插入并可供模型解析。",
|
|
6
6
|
"publishConfig": {
|
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"lib"
|
|
12
12
|
],
|
|
13
|
-
"dependencies": {},
|
|
14
13
|
"devDependencies": {
|
|
15
14
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
16
15
|
"@deepseek-ai/dsh-client-ui-input-trigger": "^0.1.1-rc.2",
|
|
17
|
-
"
|
|
16
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.0.1-rc.1",
|
|
17
|
+
"@types/react": "^18.3.0",
|
|
18
|
+
"esbuild": "^0.25.0",
|
|
19
|
+
"react": "^18.3.0"
|
|
18
20
|
},
|
|
19
21
|
"exports": {
|
|
20
22
|
".": "./lib/index.js",
|
|
@@ -24,7 +26,9 @@
|
|
|
24
26
|
"dsh": {
|
|
25
27
|
"client": {
|
|
26
28
|
"platform": "web",
|
|
27
|
-
"inject": [
|
|
29
|
+
"inject": [
|
|
30
|
+
"slots"
|
|
31
|
+
]
|
|
28
32
|
}
|
|
29
33
|
},
|
|
30
34
|
"scripts": {
|