ms-vite-plugin 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp/tools.js +41 -37
- package/dist/project.d.ts +4 -2
- package/dist/project.js +27 -13
- package/package.json +1 -1
package/dist/mcp/tools.js
CHANGED
|
@@ -303,22 +303,29 @@ function registerRuntimeTools(server) {
|
|
|
303
303
|
return workspace;
|
|
304
304
|
}
|
|
305
305
|
/**
|
|
306
|
-
*
|
|
307
|
-
* @param
|
|
308
|
-
* @
|
|
306
|
+
* 在后台启动一次日志监听,不阻塞 run/run_ui 调用返回
|
|
307
|
+
* @param ip 设备 IP
|
|
308
|
+
* @param port 设备端口
|
|
309
|
+
* @param durationSeconds 监听秒数
|
|
310
|
+
* @param maxLogs 最大日志条数
|
|
311
|
+
* @returns 返回监听目标说明文本
|
|
309
312
|
* @example
|
|
310
|
-
* const
|
|
313
|
+
* const tip = startBackgroundLogWatch("192.168.1.10", 9800, 20, 300)
|
|
311
314
|
*/
|
|
312
|
-
function
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
.
|
|
316
|
-
.
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
315
|
+
function startBackgroundLogWatch(ip, port, durationSeconds, maxLogs) {
|
|
316
|
+
const durationMs = durationSeconds > 0 ? durationSeconds * 1000 : 0;
|
|
317
|
+
void (0, project_1.watchDeviceLogsBySse)(ip, port, durationMs, maxLogs)
|
|
318
|
+
.then((result) => {
|
|
319
|
+
console.log(`[mcp] background logs ${ip}:${port} done, reason=${result.stopReason}, logs=${result.logs.length}, runtime_status=${result.runtimeStatus.length}`);
|
|
320
|
+
})
|
|
321
|
+
.catch((error) => {
|
|
322
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
323
|
+
console.warn(`[mcp] background logs ${ip}:${port} failed: ${message}`);
|
|
324
|
+
});
|
|
325
|
+
if (durationSeconds === 0) {
|
|
326
|
+
return `已在后台启动持续日志监听: ${ip}:${port}(直到连接断开,max ${maxLogs})`;
|
|
327
|
+
}
|
|
328
|
+
return `已在后台启动日志监听: ${ip}:${port}(${durationSeconds}s,max ${maxLogs})`;
|
|
322
329
|
}
|
|
323
330
|
/**
|
|
324
331
|
* 解析运行目标:
|
|
@@ -631,11 +638,11 @@ function registerRuntimeTools(server) {
|
|
|
631
638
|
durationSeconds: z
|
|
632
639
|
.number()
|
|
633
640
|
.int()
|
|
634
|
-
.min(
|
|
641
|
+
.min(0)
|
|
635
642
|
.max(300)
|
|
636
643
|
.optional()
|
|
637
644
|
.default(15)
|
|
638
|
-
.describe("监听时长(秒),默认 15
|
|
645
|
+
.describe("监听时长(秒),默认 15 秒;传 0 表示持续监听直到连接断开"),
|
|
639
646
|
maxLogs: z
|
|
640
647
|
.number()
|
|
641
648
|
.int()
|
|
@@ -659,7 +666,8 @@ function registerRuntimeTools(server) {
|
|
|
659
666
|
type: "text",
|
|
660
667
|
text: [
|
|
661
668
|
`监听目标: ${device.ip}:${device.port}`,
|
|
662
|
-
|
|
669
|
+
`监听模式: ${durationSeconds === 0 ? "持续直到连接断开" : `${durationSeconds}s`}`,
|
|
670
|
+
`结束原因: ${result.stopReason},收集日志: ${result.logs.length} 条,runtime_status: ${result.runtimeStatus.length} 条`,
|
|
663
671
|
"",
|
|
664
672
|
"最新日志(最多展示最后20条):",
|
|
665
673
|
logsPreview || "无日志",
|
|
@@ -755,11 +763,11 @@ function registerRuntimeTools(server) {
|
|
|
755
763
|
logDurationSeconds: z
|
|
756
764
|
.number()
|
|
757
765
|
.int()
|
|
758
|
-
.min(
|
|
766
|
+
.min(0)
|
|
759
767
|
.max(300)
|
|
760
768
|
.optional()
|
|
761
|
-
.default(
|
|
762
|
-
.describe("日志监听时长(秒),默认
|
|
769
|
+
.default(0)
|
|
770
|
+
.describe("日志监听时长(秒),默认 0;0 表示持续监听直到 runtime_status 失败或连接断开"),
|
|
763
771
|
logMaxLogs: z
|
|
764
772
|
.number()
|
|
765
773
|
.int()
|
|
@@ -771,15 +779,13 @@ function registerRuntimeTools(server) {
|
|
|
771
779
|
},
|
|
772
780
|
}, async ({ transport, ip, port, wsPort, wsWaitMs, workspacePath, watchLogs, logDurationSeconds, logMaxLogs, }) => {
|
|
773
781
|
const workspace = await ensureWorkspacePath(workspacePath);
|
|
774
|
-
let
|
|
775
|
-
let logTargetText = "";
|
|
782
|
+
let logNotice = "";
|
|
776
783
|
let logSetupWarning = "";
|
|
777
784
|
if (watchLogs) {
|
|
778
785
|
try {
|
|
779
786
|
const logDevice = await (0, device_config_1.resolveDeviceConfig)(ip, port);
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
logTask = (0, project_1.watchDeviceLogsBySse)(logDevice.ip, logDevice.port, logDurationSeconds * 1000, logMaxLogs);
|
|
787
|
+
// 先启动日志监听,再执行 run,且不等待日志结束,避免 run 被阻塞
|
|
788
|
+
logNotice = startBackgroundLogWatch(logDevice.ip, logDevice.port, logDurationSeconds, logMaxLogs);
|
|
783
789
|
}
|
|
784
790
|
catch (error) {
|
|
785
791
|
logSetupWarning = `日志监听未启动: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -805,8 +811,8 @@ function registerRuntimeTools(server) {
|
|
|
805
811
|
transport: "http",
|
|
806
812
|
workspacePath: workspace,
|
|
807
813
|
});
|
|
808
|
-
const logSection =
|
|
809
|
-
? `\n\n
|
|
814
|
+
const logSection = logNotice
|
|
815
|
+
? `\n\n${logNotice}`
|
|
810
816
|
: logSetupWarning
|
|
811
817
|
? `\n\n${logSetupWarning}`
|
|
812
818
|
: "";
|
|
@@ -866,11 +872,11 @@ function registerRuntimeTools(server) {
|
|
|
866
872
|
logDurationSeconds: z
|
|
867
873
|
.number()
|
|
868
874
|
.int()
|
|
869
|
-
.min(
|
|
875
|
+
.min(0)
|
|
870
876
|
.max(300)
|
|
871
877
|
.optional()
|
|
872
|
-
.default(
|
|
873
|
-
.describe("日志监听时长(秒),默认
|
|
878
|
+
.default(0)
|
|
879
|
+
.describe("日志监听时长(秒),默认 0;0 表示持续监听直到 runtime_status 失败或连接断开"),
|
|
874
880
|
logMaxLogs: z
|
|
875
881
|
.number()
|
|
876
882
|
.int()
|
|
@@ -882,15 +888,13 @@ function registerRuntimeTools(server) {
|
|
|
882
888
|
},
|
|
883
889
|
}, async ({ transport, ip, port, wsPort, wsWaitMs, workspacePath, watchLogs, logDurationSeconds, logMaxLogs, }) => {
|
|
884
890
|
const workspace = await ensureWorkspacePath(workspacePath);
|
|
885
|
-
let
|
|
886
|
-
let logTargetText = "";
|
|
891
|
+
let logNotice = "";
|
|
887
892
|
let logSetupWarning = "";
|
|
888
893
|
if (watchLogs) {
|
|
889
894
|
try {
|
|
890
895
|
const logDevice = await (0, device_config_1.resolveDeviceConfig)(ip, port);
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
logTask = (0, project_1.watchDeviceLogsBySse)(logDevice.ip, logDevice.port, logDurationSeconds * 1000, logMaxLogs);
|
|
896
|
+
// 先启动日志监听,再执行 run-ui,且不等待日志结束,避免 run-ui 被阻塞
|
|
897
|
+
logNotice = startBackgroundLogWatch(logDevice.ip, logDevice.port, logDurationSeconds, logMaxLogs);
|
|
894
898
|
}
|
|
895
899
|
catch (error) {
|
|
896
900
|
logSetupWarning = `日志监听未启动: ${error instanceof Error ? error.message : String(error)}`;
|
|
@@ -916,8 +920,8 @@ function registerRuntimeTools(server) {
|
|
|
916
920
|
transport: "http",
|
|
917
921
|
workspacePath: workspace,
|
|
918
922
|
});
|
|
919
|
-
const logSection =
|
|
920
|
-
? `\n\n
|
|
923
|
+
const logSection = logNotice
|
|
924
|
+
? `\n\n${logNotice}`
|
|
921
925
|
: logSetupWarning
|
|
922
926
|
? `\n\n${logSetupWarning}`
|
|
923
927
|
: "";
|
package/dist/project.d.ts
CHANGED
|
@@ -37,6 +37,8 @@ export interface DeviceLogWatchResult {
|
|
|
37
37
|
logs: DeviceLogEntry[];
|
|
38
38
|
/** 收集到的 runtime_status 条目 */
|
|
39
39
|
runtimeStatus: DeviceRuntimeStatusEntry[];
|
|
40
|
+
/** 监听结束原因 */
|
|
41
|
+
stopReason: "timeout" | "stream_closed" | "manual_abort" | "unknown";
|
|
40
42
|
}
|
|
41
43
|
/**
|
|
42
44
|
* 在设备上获取截图 JPG 二进制数据(HTTP)
|
|
@@ -68,11 +70,11 @@ export declare function getSourceOnDevice(options: DeviceCliOptions, maxDepth?:
|
|
|
68
70
|
* 监听设备 SSE 日志并返回原始结果
|
|
69
71
|
* @param ip 设备 IP 地址
|
|
70
72
|
* @param port 设备端口
|
|
71
|
-
* @param durationMs 监听时长(毫秒),默认 15000
|
|
73
|
+
* @param durationMs 监听时长(毫秒),默认 15000;传 0 表示不设超时,持续监听
|
|
72
74
|
* @param maxLogs 最多收集日志条数,默认 200
|
|
73
75
|
* @returns 返回日志与运行状态
|
|
74
76
|
* @example
|
|
75
|
-
* const result = await watchDeviceLogsBySse("192.168.1.10", 9800,
|
|
77
|
+
* const result = await watchDeviceLogsBySse("192.168.1.10", 9800, 0, 300)
|
|
76
78
|
*/
|
|
77
79
|
export declare function watchDeviceLogsBySse(ip: string, port: number, durationMs?: number, maxLogs?: number): Promise<DeviceLogWatchResult>;
|
|
78
80
|
/**
|
package/dist/project.js
CHANGED
|
@@ -513,11 +513,11 @@ function normalizeLogEntry(payload) {
|
|
|
513
513
|
* 监听设备 SSE 日志并返回原始结果
|
|
514
514
|
* @param ip 设备 IP 地址
|
|
515
515
|
* @param port 设备端口
|
|
516
|
-
* @param durationMs 监听时长(毫秒),默认 15000
|
|
516
|
+
* @param durationMs 监听时长(毫秒),默认 15000;传 0 表示不设超时,持续监听
|
|
517
517
|
* @param maxLogs 最多收集日志条数,默认 200
|
|
518
518
|
* @returns 返回日志与运行状态
|
|
519
519
|
* @example
|
|
520
|
-
* const result = await watchDeviceLogsBySse("192.168.1.10", 9800,
|
|
520
|
+
* const result = await watchDeviceLogsBySse("192.168.1.10", 9800, 0, 300)
|
|
521
521
|
*/
|
|
522
522
|
async function watchDeviceLogsBySse(ip, port, durationMs = 15000, maxLogs = 200) {
|
|
523
523
|
if (!ip.trim()) {
|
|
@@ -526,7 +526,7 @@ async function watchDeviceLogsBySse(ip, port, durationMs = 15000, maxLogs = 200)
|
|
|
526
526
|
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
527
527
|
throw new Error(`监听日志失败: 无效端口 ${port}`);
|
|
528
528
|
}
|
|
529
|
-
if (!Number.isInteger(durationMs) || durationMs <
|
|
529
|
+
if (!Number.isInteger(durationMs) || durationMs < 0) {
|
|
530
530
|
throw new Error(`监听日志失败: 无效 durationMs ${durationMs}`);
|
|
531
531
|
}
|
|
532
532
|
if (!Number.isInteger(maxLogs) || maxLogs < 1) {
|
|
@@ -536,9 +536,13 @@ async function watchDeviceLogsBySse(ip, port, durationMs = 15000, maxLogs = 200)
|
|
|
536
536
|
const logs = [];
|
|
537
537
|
const runtimeStatus = [];
|
|
538
538
|
const controller = new AbortController();
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
539
|
+
let stopReason = "unknown";
|
|
540
|
+
const timeoutHandle = durationMs > 0
|
|
541
|
+
? setTimeout(() => {
|
|
542
|
+
stopReason = "timeout";
|
|
543
|
+
controller.abort();
|
|
544
|
+
}, durationMs)
|
|
545
|
+
: undefined;
|
|
542
546
|
try {
|
|
543
547
|
const response = await fetch(url, {
|
|
544
548
|
method: "GET",
|
|
@@ -556,6 +560,9 @@ async function watchDeviceLogsBySse(ip, port, durationMs = 15000, maxLogs = 200)
|
|
|
556
560
|
while (true) {
|
|
557
561
|
const { value, done } = await reader.read();
|
|
558
562
|
if (done) {
|
|
563
|
+
if (stopReason === "unknown") {
|
|
564
|
+
stopReason = "stream_closed";
|
|
565
|
+
}
|
|
559
566
|
break;
|
|
560
567
|
}
|
|
561
568
|
buffer += decoder.decode(value, { stream: true });
|
|
@@ -569,11 +576,16 @@ async function watchDeviceLogsBySse(ip, port, durationMs = 15000, maxLogs = 200)
|
|
|
569
576
|
try {
|
|
570
577
|
const parsed = JSON.parse(event.data);
|
|
571
578
|
if (event.event === "log") {
|
|
572
|
-
|
|
573
|
-
|
|
579
|
+
// 日志缓冲使用环形窗口,持续监听时不会无限增长
|
|
580
|
+
if (logs.length >= maxLogs) {
|
|
581
|
+
logs.shift();
|
|
574
582
|
}
|
|
583
|
+
logs.push(normalizeLogEntry(parsed));
|
|
575
584
|
}
|
|
576
585
|
else if (event.event === "runtime_status") {
|
|
586
|
+
if (runtimeStatus.length >= maxLogs) {
|
|
587
|
+
runtimeStatus.shift();
|
|
588
|
+
}
|
|
577
589
|
runtimeStatus.push({
|
|
578
590
|
raw: parsed,
|
|
579
591
|
timestamp: new Date().toISOString(),
|
|
@@ -584,10 +596,6 @@ async function watchDeviceLogsBySse(ip, port, durationMs = 15000, maxLogs = 200)
|
|
|
584
596
|
// 兼容非 JSON 数据:不抛错,继续监听后续事件
|
|
585
597
|
}
|
|
586
598
|
}
|
|
587
|
-
if (logs.length >= maxLogs) {
|
|
588
|
-
controller.abort();
|
|
589
|
-
break;
|
|
590
|
-
}
|
|
591
599
|
splitIndex = buffer.search(/\r?\n\r?\n/);
|
|
592
600
|
}
|
|
593
601
|
}
|
|
@@ -599,13 +607,19 @@ async function watchDeviceLogsBySse(ip, port, durationMs = 15000, maxLogs = 200)
|
|
|
599
607
|
error.message === "The operation was aborted."))) {
|
|
600
608
|
throw error;
|
|
601
609
|
}
|
|
610
|
+
if (stopReason === "unknown") {
|
|
611
|
+
stopReason = "manual_abort";
|
|
612
|
+
}
|
|
602
613
|
}
|
|
603
614
|
finally {
|
|
604
|
-
|
|
615
|
+
if (timeoutHandle) {
|
|
616
|
+
clearTimeout(timeoutHandle);
|
|
617
|
+
}
|
|
605
618
|
}
|
|
606
619
|
return {
|
|
607
620
|
logs,
|
|
608
621
|
runtimeStatus,
|
|
622
|
+
stopReason,
|
|
609
623
|
};
|
|
610
624
|
}
|
|
611
625
|
/**
|