@lujoai/lujo-mcp 0.7.5 → 0.7.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/bin/cli.js +50 -3
- package/browser-sdk/ai-debug.js +17 -1
- package/package.json +4 -4
package/bin/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// lujo-mcp-server launcher — locates the platform-specific binary in the companion
|
|
3
|
-
// lujo-mcp-<platform>-<arch> package and
|
|
3
|
+
// lujo-mcp-<platform>-<arch> package and starts the local unified server.
|
|
4
4
|
//
|
|
5
5
|
// Mirrors the pattern used by esbuild/@biomejs/@nuphus: the root package is a thin
|
|
6
6
|
// meta package whose optionalDependencies install only the binary for the current
|
|
@@ -87,7 +87,11 @@ or reinstall the meta package:
|
|
|
87
87
|
npm install -g @lujoai/lujo-mcp`);
|
|
88
88
|
process.exit(1);
|
|
89
89
|
}
|
|
90
|
-
|
|
90
|
+
// npm users get the useful local mode out of the box: one process serves both
|
|
91
|
+
// MCP stdio and localhost HTTP, so Browser SDK /ingest events are immediately
|
|
92
|
+
// visible to the MCP client. Keep an explicit --no-http escape hatch for
|
|
93
|
+
// clients that require a pure stdio process (and for release smoke tests).
|
|
94
|
+
const child = spawn(bin, translateArgs(process.argv.slice(2)), {
|
|
91
95
|
stdio: 'inherit',
|
|
92
96
|
windowsHide: true,
|
|
93
97
|
});
|
|
@@ -95,10 +99,53 @@ or reinstall the meta package:
|
|
|
95
99
|
console.error(`[lujo-mcp-server] failed to spawn ${bin}: ${err.message}`);
|
|
96
100
|
process.exit(1);
|
|
97
101
|
});
|
|
102
|
+
|
|
103
|
+
// FIX(R8): 终止信号必须转发。宿主(Claude / Codex / Trae 等)停止 MCP 服务
|
|
104
|
+
// 时只处理它直接启动的那个进程——也就是本启动器——被 spawn 出来的二进制不会
|
|
105
|
+
// 被自动带走(Windows 没有 POSIX 的进程组/信号语义,实测杀掉启动器后二进制
|
|
106
|
+
// 存活并继续监听统一模式的 HTTP 端口)。孤儿会接收浏览器 SDK 发往该端口的
|
|
107
|
+
// 全部上报,新起的实例抢不到端口,当前会话因此表现为「报过错但
|
|
108
|
+
// diagnose_issue 查不到任何现场」。
|
|
109
|
+
// 子进程自身退出时由下面的 exit 处理器决定本进程退出码,这里只负责带离。
|
|
110
|
+
let forwarding = false;
|
|
111
|
+
function forward(signal) {
|
|
112
|
+
if (forwarding) return;
|
|
113
|
+
forwarding = true;
|
|
114
|
+
try {
|
|
115
|
+
child.kill(signal);
|
|
116
|
+
} catch {
|
|
117
|
+
// 子进程可能已经退出:无需要做的,交给 exit 兜底
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Windows 收不到 SIGTERM/SIGHUP(注册无害且永不触发),但能收到 SIGBREAK。
|
|
121
|
+
for (const sig of ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGBREAK']) {
|
|
122
|
+
process.on(sig, () => forward('SIGTERM'));
|
|
123
|
+
}
|
|
124
|
+
process.on('uncaughtException', (err) => {
|
|
125
|
+
console.error(`[lujo-mcp-server] launcher error: ${err && err.message}`);
|
|
126
|
+
forward('SIGTERM');
|
|
127
|
+
process.exit(1);
|
|
128
|
+
});
|
|
129
|
+
// 任何原因导致的本进程退出(含上面的 process.exit 路径)都不能把子进程留下。
|
|
130
|
+
process.on('exit', () => forward('SIGTERM'));
|
|
131
|
+
|
|
98
132
|
child.on('exit', (code, signal) => {
|
|
99
133
|
if (signal) process.kill(process.pid, signal);
|
|
100
134
|
else process.exit(code == null ? 0 : code);
|
|
101
135
|
});
|
|
102
136
|
}
|
|
103
137
|
|
|
104
|
-
|
|
138
|
+
// 参数拼装与 npm 默认模式:抽出以便在无平台二进制的环境下直接单测。
|
|
139
|
+
function translateArgs(requestedArgs) {
|
|
140
|
+
const args = Array.isArray(requestedArgs) ? requestedArgs.slice() : [];
|
|
141
|
+
const disableHttp = args.includes('--no-http');
|
|
142
|
+
const childArgs = args.filter((arg) => arg !== '--no-http');
|
|
143
|
+
if (!disableHttp && !childArgs.includes('--http')) childArgs.push('--http');
|
|
144
|
+
return childArgs;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (require.main === module) {
|
|
148
|
+
run();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = { platformPackageName, translateArgs, binaryNameFor };
|
package/browser-sdk/ai-debug.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lujo-mcp Browser SDK v0.7.
|
|
2
|
+
* lujo-mcp Browser SDK v0.7.7
|
|
3
3
|
*
|
|
4
4
|
* 版本以 browser-sdk/package.json 的 version 为准(本注释仅为可读性,
|
|
5
5
|
* 升级时随版本 bump 一并更新,避免再次漂移)。
|
|
@@ -861,6 +861,8 @@
|
|
|
861
861
|
message: String(msg),
|
|
862
862
|
frames: frames,
|
|
863
863
|
trace_id: _traceId,
|
|
864
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
865
|
+
session_id: _sessionId,
|
|
864
866
|
source: "browser-sdk",
|
|
865
867
|
extra: {
|
|
866
868
|
session_id: _sessionId,
|
|
@@ -906,6 +908,8 @@
|
|
|
906
908
|
message: message,
|
|
907
909
|
frames: frames,
|
|
908
910
|
trace_id: _traceId,
|
|
911
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
912
|
+
session_id: _sessionId,
|
|
909
913
|
source: "browser-sdk",
|
|
910
914
|
extra: {
|
|
911
915
|
session_id: _sessionId,
|
|
@@ -1042,6 +1046,8 @@
|
|
|
1042
1046
|
_send("/ingest/network", {
|
|
1043
1047
|
record: record,
|
|
1044
1048
|
trace_id: _traceId,
|
|
1049
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
1050
|
+
session_id: _sessionId,
|
|
1045
1051
|
source: "browser-sdk",
|
|
1046
1052
|
extra: { session_id: _sessionId },
|
|
1047
1053
|
}, force);
|
|
@@ -1478,6 +1484,8 @@
|
|
|
1478
1484
|
_send("/ingest/ui-event", {
|
|
1479
1485
|
event: uiEvent,
|
|
1480
1486
|
trace_id: _traceId,
|
|
1487
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
1488
|
+
session_id: _sessionId,
|
|
1481
1489
|
source: "browser-sdk",
|
|
1482
1490
|
extra: { session_id: _sessionId },
|
|
1483
1491
|
});
|
|
@@ -1543,6 +1551,8 @@
|
|
|
1543
1551
|
level: level,
|
|
1544
1552
|
message: messages.join(" "),
|
|
1545
1553
|
trace_id: _traceId,
|
|
1554
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
1555
|
+
session_id: _sessionId,
|
|
1546
1556
|
source: "browser-sdk",
|
|
1547
1557
|
extra: {
|
|
1548
1558
|
session_id: _sessionId,
|
|
@@ -1765,6 +1775,8 @@
|
|
|
1765
1775
|
observed: silentPayload.observed,
|
|
1766
1776
|
observed_events: silentPayload.observed_events,
|
|
1767
1777
|
trace_id: silentPayload.trace_id,
|
|
1778
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
1779
|
+
session_id: _sessionId,
|
|
1768
1780
|
source: silentPayload.source,
|
|
1769
1781
|
extra: silentPayload.extra,
|
|
1770
1782
|
}, true);
|
|
@@ -1792,6 +1804,8 @@
|
|
|
1792
1804
|
message: error ? error.message || String(error) : "",
|
|
1793
1805
|
frames: error && error.stack ? _parseStack(error.stack) : [],
|
|
1794
1806
|
trace_id: _traceId,
|
|
1807
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
1808
|
+
session_id: _sessionId,
|
|
1795
1809
|
source: "browser-sdk",
|
|
1796
1810
|
extra: Object.assign({
|
|
1797
1811
|
session_id: _sessionId,
|
|
@@ -1815,6 +1829,8 @@
|
|
|
1815
1829
|
route_path: event.route_path || (global.location ? global.location.pathname : ""),
|
|
1816
1830
|
},
|
|
1817
1831
|
trace_id: _traceId,
|
|
1832
|
+
// FIX: R2 —— session_id 上移到顶层规范位置(extra 内保留兼容旧服务端)
|
|
1833
|
+
session_id: _sessionId,
|
|
1818
1834
|
source: "browser-sdk",
|
|
1819
1835
|
extra: { session_id: _sessionId },
|
|
1820
1836
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lujoai/lujo-mcp",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"description": "Lujo-MCP — MCP Runtime Debugging Context Server for AI coding agents. Gives Claude, Cursor, Trae and any MCP-compatible client real runtime debugging context: browser errors, console logs, network failures, UI interaction traces and session context. Zero-config, install via npm.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"prepublishOnly": "node ./scripts/check-clean-bin.js"
|
|
44
44
|
},
|
|
45
45
|
"optionalDependencies": {
|
|
46
|
-
"@lujoai/lujo-mcp-win32-x64": "0.7.
|
|
47
|
-
"@lujoai/lujo-mcp-linux-x64": "0.7.
|
|
48
|
-
"@lujoai/lujo-mcp-osx-arm64": "0.7.
|
|
46
|
+
"@lujoai/lujo-mcp-win32-x64": "0.7.7",
|
|
47
|
+
"@lujoai/lujo-mcp-linux-x64": "0.7.7",
|
|
48
|
+
"@lujoai/lujo-mcp-osx-arm64": "0.7.7"
|
|
49
49
|
}
|
|
50
50
|
}
|