@aipanel/dsh-client 1.2.9 → 1.2.11
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 +76 -17
- package/package.json +2 -2
package/lib/client.js
CHANGED
|
@@ -67,6 +67,20 @@ var WIDGET_MSG = {
|
|
|
67
67
|
SESSION_READY: "AIPANEL_SESSION_READY"
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
+
// ../../core/es/common/utils.mjs
|
|
71
|
+
function ensureNodeId(element) {
|
|
72
|
+
if (element.id) return element.id;
|
|
73
|
+
const random = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID().replace(/-/g, "").slice(0, 8) : Math.random().toString(36).slice(2, 10);
|
|
74
|
+
element.id = `n${random}`;
|
|
75
|
+
return element.id;
|
|
76
|
+
}
|
|
77
|
+
function toNodeMention(id) {
|
|
78
|
+
return `@\u8282\u70B9[${id}]`;
|
|
79
|
+
}
|
|
80
|
+
function widgetEnvelope(type, data) {
|
|
81
|
+
return { type, ...data };
|
|
82
|
+
}
|
|
83
|
+
|
|
70
84
|
// dsh-client/src/client/diagnostics-view.tsx
|
|
71
85
|
var import_react = require("react");
|
|
72
86
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
@@ -74,12 +88,39 @@ var import_jsx_runtime = require("react/jsx-runtime");
|
|
|
74
88
|
function isSettledToolResult(block) {
|
|
75
89
|
return typeof block === "object" && block !== null && "kind" in block && block.kind === "tool-result";
|
|
76
90
|
}
|
|
91
|
+
var TEXT_ESLINT_RE = /^[ \t]*(ERROR|WARN) \[([^\]\r\n]+?):(\d+):(\d+)\] (.*)$/gm;
|
|
92
|
+
var TEXT_TSC_RE = /^[ \t]*([^():\r\n]+)\((\d+),(\d+)\):\s*(error|warning)\s+(.*)$/gm;
|
|
93
|
+
function parseTextDiagnostics(text) {
|
|
94
|
+
const out = [];
|
|
95
|
+
if (!text) return out;
|
|
96
|
+
for (const m of text.matchAll(TEXT_ESLINT_RE)) {
|
|
97
|
+
out.push({
|
|
98
|
+
file: m[2],
|
|
99
|
+
line: Number(m[3]),
|
|
100
|
+
column: Number(m[4]),
|
|
101
|
+
severity: m[1].toLowerCase(),
|
|
102
|
+
message: m[5].trim()
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
for (const m of text.matchAll(TEXT_TSC_RE)) {
|
|
106
|
+
out.push({
|
|
107
|
+
file: m[1].trim(),
|
|
108
|
+
line: Number(m[2]),
|
|
109
|
+
column: Number(m[3]),
|
|
110
|
+
severity: m[4],
|
|
111
|
+
message: m[5].trim()
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
77
116
|
function readDiagnostics(block) {
|
|
78
117
|
if (!isSettledToolResult(block)) return void 0;
|
|
79
118
|
const meta = block.meta;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
119
|
+
if (Array.isArray(meta?.diagnostics) && meta.diagnostics.every(isEntry)) {
|
|
120
|
+
return meta.diagnostics;
|
|
121
|
+
}
|
|
122
|
+
const parsed = parseTextDiagnostics(extractBlockText(block));
|
|
123
|
+
return parsed.length > 0 ? parsed : void 0;
|
|
83
124
|
}
|
|
84
125
|
function extractBlockText(block) {
|
|
85
126
|
if (!isSettledToolResult(block)) return "";
|
|
@@ -214,6 +255,7 @@ function DiagnosticsRow({ block, cwd, toolName, openFile }) {
|
|
|
214
255
|
const errors = (diagnostics ?? []).filter((d) => d.severity === "error");
|
|
215
256
|
const warnings = (diagnostics ?? []).filter((d) => d.severity === "warning");
|
|
216
257
|
const contentText = extractBlockText(block);
|
|
258
|
+
const textHasIssues = /^[ \t]*(?:ERROR|WARN)\s+\[/m.test(contentText);
|
|
217
259
|
const firstLine = (contentText.split("\n")[0] || "").trim();
|
|
218
260
|
const isFullProject = /^全量诊断结果/.test(firstLine);
|
|
219
261
|
const scope = isFullProject ? "project" : "file";
|
|
@@ -250,7 +292,7 @@ function DiagnosticsRow({ block, cwd, toolName, openFile }) {
|
|
|
250
292
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sep, "aria-hidden": true }),
|
|
251
293
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.summary, children: "\u8BCA\u65AD\u8FD0\u884C\u4E2D\u2026" })
|
|
252
294
|
] });
|
|
253
|
-
} else if (diagnostics && diagnostics.length === 0) {
|
|
295
|
+
} else if (diagnostics && diagnostics.length === 0 && !textHasIssues) {
|
|
254
296
|
collapsed = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
255
297
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.sep, "aria-hidden": true }),
|
|
256
298
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.summary, children: [
|
|
@@ -322,12 +364,7 @@ var MSG = WIDGET_MSG;
|
|
|
322
364
|
var inject = ["slots", "sessions", "inputTriggers", "conversation"];
|
|
323
365
|
var SESSION_SETTLE_MS = 400;
|
|
324
366
|
var FOCUS_OPEN_MAX_ATTEMPTS = 3;
|
|
325
|
-
|
|
326
|
-
if (e.id) return e.id;
|
|
327
|
-
const random = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID().replace(/-/g, "").slice(0, 8) : Math.random().toString(36).slice(2, 10);
|
|
328
|
-
e.id = `n${random}`;
|
|
329
|
-
return e.id;
|
|
330
|
-
}
|
|
367
|
+
var FOCUS_INFLIGHT_TIMEOUT_MS = 1e4;
|
|
331
368
|
function elementContextRef(e) {
|
|
332
369
|
return JSON.stringify(e);
|
|
333
370
|
}
|
|
@@ -335,7 +372,7 @@ function serializeElement(ref) {
|
|
|
335
372
|
try {
|
|
336
373
|
const e = JSON.parse(ref);
|
|
337
374
|
if (!e || typeof e !== "object") throw new Error("not an element payload");
|
|
338
|
-
return
|
|
375
|
+
return toNodeMention(ensureNodeId(e));
|
|
339
376
|
} catch {
|
|
340
377
|
return `@${ref}`;
|
|
341
378
|
}
|
|
@@ -360,7 +397,7 @@ function isEmbedded() {
|
|
|
360
397
|
function postToHost(type, data = {}) {
|
|
361
398
|
if (!isEmbedded()) return;
|
|
362
399
|
try {
|
|
363
|
-
window.parent.postMessage(
|
|
400
|
+
window.parent.postMessage(widgetEnvelope(type, data), "*");
|
|
364
401
|
} catch {
|
|
365
402
|
}
|
|
366
403
|
}
|
|
@@ -376,6 +413,7 @@ function apply(ctx, config = {}) {
|
|
|
376
413
|
let lastCurrent;
|
|
377
414
|
let settleTimer = null;
|
|
378
415
|
let targetSessionId;
|
|
416
|
+
let focusDeadline = 0;
|
|
379
417
|
let pendingFocusId;
|
|
380
418
|
let focusAttempts = 0;
|
|
381
419
|
let refreshing = false;
|
|
@@ -395,6 +433,10 @@ function apply(ctx, config = {}) {
|
|
|
395
433
|
if (!id) return;
|
|
396
434
|
const snap = sessions.list.getSnapshot();
|
|
397
435
|
if (!hasBaseline(snap)) return;
|
|
436
|
+
if (Date.now() >= focusDeadline) {
|
|
437
|
+
clearFocusTarget();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
398
440
|
pendingFocusId = void 0;
|
|
399
441
|
focusAttempts = 0;
|
|
400
442
|
void tryOpenTarget(id);
|
|
@@ -403,7 +445,10 @@ function apply(ctx, config = {}) {
|
|
|
403
445
|
if (focusAttempts >= FOCUS_OPEN_MAX_ATTEMPTS) return;
|
|
404
446
|
focusAttempts += 1;
|
|
405
447
|
const snap = sessions.list.getSnapshot();
|
|
406
|
-
if (snap.current === id)
|
|
448
|
+
if (snap.current === id) {
|
|
449
|
+
clearFocusTarget();
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
407
452
|
if (!listContains(snap, id) && !refreshing) {
|
|
408
453
|
refreshing = true;
|
|
409
454
|
try {
|
|
@@ -423,8 +468,16 @@ function apply(ctx, config = {}) {
|
|
|
423
468
|
} catch {
|
|
424
469
|
}
|
|
425
470
|
};
|
|
426
|
-
const
|
|
471
|
+
const clearFocusTarget = () => {
|
|
472
|
+
targetSessionId = void 0;
|
|
473
|
+
focusDeadline = 0;
|
|
474
|
+
pendingFocusId = void 0;
|
|
475
|
+
};
|
|
476
|
+
const handleFocus = (sessionId, source2 = "host") => {
|
|
427
477
|
targetSessionId = sessionId;
|
|
478
|
+
if (source2 === "host") {
|
|
479
|
+
focusDeadline = Date.now() + FOCUS_INFLIGHT_TIMEOUT_MS;
|
|
480
|
+
}
|
|
428
481
|
const snap = sessions.list.getSnapshot();
|
|
429
482
|
if (!hasBaseline(snap)) {
|
|
430
483
|
pendingFocusId = sessionId;
|
|
@@ -451,8 +504,14 @@ function apply(ctx, config = {}) {
|
|
|
451
504
|
settleTimer = null;
|
|
452
505
|
if (sessions.list?.getSnapshot?.()?.current === current) {
|
|
453
506
|
notifyReady(current);
|
|
454
|
-
if (targetSessionId
|
|
455
|
-
|
|
507
|
+
if (targetSessionId) {
|
|
508
|
+
if (current === targetSessionId) {
|
|
509
|
+
clearFocusTarget();
|
|
510
|
+
} else if (Date.now() < focusDeadline) {
|
|
511
|
+
handleFocus(targetSessionId, "refocus");
|
|
512
|
+
} else {
|
|
513
|
+
clearFocusTarget();
|
|
514
|
+
}
|
|
456
515
|
}
|
|
457
516
|
}
|
|
458
517
|
}, SESSION_SETTLE_MS);
|
|
@@ -568,7 +627,7 @@ function apply(ctx, config = {}) {
|
|
|
568
627
|
if (data.type === MSG.SET_THEME && typeof data.theme === "string") {
|
|
569
628
|
applyThemeFromHost(data.theme);
|
|
570
629
|
} else if (data.type === MSG.FOCUS_SESSION && typeof data.sessionId === "string") {
|
|
571
|
-
handleFocus(data.sessionId);
|
|
630
|
+
handleFocus(data.sessionId, "host");
|
|
572
631
|
} else if (data.type === MSG.INSERT_FILE_PART && data.element) {
|
|
573
632
|
insertElement(data.element);
|
|
574
633
|
} else if (data.type === MSG.SELECT_MODE_CHANGE) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aipanel/dsh-client",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AIPanel 浏览器侧插件(dsh web Web Client):注册 @aipanel 文件引用 source,选中元素以 file chip 高亮插入并可供模型解析。",
|
|
6
6
|
"publishConfig": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@types/react": "^18.3.0",
|
|
23
23
|
"esbuild": "^0.25.0",
|
|
24
24
|
"react": "^18.3.0",
|
|
25
|
-
"@aipanel/core": "1.2.
|
|
25
|
+
"@aipanel/core": "1.2.11"
|
|
26
26
|
},
|
|
27
27
|
"exports": {
|
|
28
28
|
".": "./lib/index.js",
|