gravity-core 1.0.22 → 1.0.23
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-server.js +1 -1
- package/dist/native-host.js +33 -127
- package/dist/native-host.js.map +1 -1
- package/extension/manifest.json +1 -1
- package/package.json +2 -1
package/dist/mcp-server.js
CHANGED
package/dist/native-host.js
CHANGED
|
@@ -10,94 +10,17 @@
|
|
|
10
10
|
* MCP Server ← WebSocket → Native Host ← Native Messaging → Extension ← CDP → Browser
|
|
11
11
|
*/
|
|
12
12
|
import { WebSocketServer, WebSocket } from 'ws';
|
|
13
|
+
// @ts-ignore - no types available
|
|
14
|
+
import nativeMessage from 'chrome-native-messaging';
|
|
13
15
|
const WS_PORT = 9224;
|
|
14
16
|
let wsServer = null;
|
|
15
17
|
let wsClient = null;
|
|
16
|
-
/**
|
|
17
|
-
* Read native messaging message from stdin
|
|
18
|
-
*/
|
|
19
|
-
function readNativeMessage() {
|
|
20
|
-
return new Promise((resolve, reject) => {
|
|
21
|
-
const headerBuffer = Buffer.alloc(4);
|
|
22
|
-
let headerBytesRead = 0;
|
|
23
|
-
const readHeader = () => {
|
|
24
|
-
const chunk = process.stdin.read(4 - headerBytesRead);
|
|
25
|
-
if (chunk === null) {
|
|
26
|
-
// No data available yet, wait for readable event
|
|
27
|
-
process.stdin.once('readable', readHeader);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
if (chunk.length === 0) {
|
|
31
|
-
// EOF
|
|
32
|
-
reject(new Error('EOF: stdin closed'));
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
chunk.copy(headerBuffer, headerBytesRead);
|
|
36
|
-
headerBytesRead += chunk.length;
|
|
37
|
-
if (headerBytesRead === 4) {
|
|
38
|
-
const messageLength = headerBuffer.readUInt32LE(0);
|
|
39
|
-
if (messageLength === 0 || messageLength > 1024 * 1024) {
|
|
40
|
-
reject(new Error(`Invalid message length: ${messageLength}`));
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
readMessage(messageLength);
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
process.stdin.once('readable', readHeader);
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
const readMessage = (length) => {
|
|
50
|
-
const messageBuffer = Buffer.alloc(length);
|
|
51
|
-
let messageBytesRead = 0;
|
|
52
|
-
const readChunk = () => {
|
|
53
|
-
const chunk = process.stdin.read(length - messageBytesRead);
|
|
54
|
-
if (chunk === null) {
|
|
55
|
-
// No data available yet, wait for readable event
|
|
56
|
-
process.stdin.once('readable', readChunk);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
if (chunk.length === 0) {
|
|
60
|
-
// EOF
|
|
61
|
-
reject(new Error('EOF: stdin closed during message read'));
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
chunk.copy(messageBuffer, messageBytesRead);
|
|
65
|
-
messageBytesRead += chunk.length;
|
|
66
|
-
if (messageBytesRead === length) {
|
|
67
|
-
try {
|
|
68
|
-
const message = JSON.parse(messageBuffer.toString('utf-8'));
|
|
69
|
-
resolve(message);
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
reject(new Error(`Failed to parse JSON: ${error}`));
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
process.stdin.once('readable', readChunk);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
readChunk();
|
|
80
|
-
};
|
|
81
|
-
readHeader();
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Send native messaging message to stdout
|
|
86
|
-
*/
|
|
87
|
-
function sendNativeMessage(message) {
|
|
88
|
-
const messageStr = JSON.stringify(message);
|
|
89
|
-
const messageBuffer = Buffer.from(messageStr, 'utf-8');
|
|
90
|
-
const headerBuffer = Buffer.alloc(4);
|
|
91
|
-
headerBuffer.writeUInt32LE(messageBuffer.length, 0);
|
|
92
|
-
process.stdout.write(headerBuffer);
|
|
93
|
-
process.stdout.write(messageBuffer);
|
|
94
|
-
}
|
|
95
18
|
/**
|
|
96
19
|
* Start WebSocket server for MCP connections
|
|
97
20
|
*/
|
|
98
21
|
function startWebSocketServer() {
|
|
99
22
|
wsServer = new WebSocketServer({ port: WS_PORT });
|
|
100
|
-
console.error(
|
|
23
|
+
console.error('[Native Host] WebSocket server listening on port', WS_PORT);
|
|
101
24
|
wsServer.on('connection', (ws) => {
|
|
102
25
|
console.error('[Native Host] MCP server connected');
|
|
103
26
|
wsClient = ws;
|
|
@@ -105,8 +28,8 @@ function startWebSocketServer() {
|
|
|
105
28
|
try {
|
|
106
29
|
const message = JSON.parse(data.toString());
|
|
107
30
|
console.error('[Native Host] MCP → Extension:', message.type || message.method);
|
|
108
|
-
// Forward to extension via native messaging
|
|
109
|
-
|
|
31
|
+
// Forward to extension via native messaging (stdout)
|
|
32
|
+
output.write(message);
|
|
110
33
|
}
|
|
111
34
|
catch (error) {
|
|
112
35
|
console.error('[Native Host] Error processing WebSocket message:', error.message);
|
|
@@ -126,57 +49,43 @@ function startWebSocketServer() {
|
|
|
126
49
|
});
|
|
127
50
|
}
|
|
128
51
|
/**
|
|
129
|
-
*
|
|
52
|
+
* Setup Native Messaging streams
|
|
130
53
|
*/
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
console.error('[Native Host] Extension → MCP:', message.type);
|
|
139
|
-
// Forward to MCP server via WebSocket
|
|
140
|
-
if (wsClient && wsClient.readyState === WebSocket.OPEN) {
|
|
141
|
-
wsClient.send(JSON.stringify(message));
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
console.error('[Native Host] No MCP client connected, message dropped');
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
if (error.message.includes('EOF') || error.message.includes('end')) {
|
|
149
|
-
console.error('[Native Host] Extension disconnected (stdin closed)');
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
console.error('[Native Host] Error reading from extension:', error.message);
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
54
|
+
const input = new nativeMessage.Input();
|
|
55
|
+
const output = new nativeMessage.Output();
|
|
56
|
+
const transform = new nativeMessage.Transform((msg, push, done) => {
|
|
57
|
+
console.error('[Native Host] Extension → MCP:', msg.type);
|
|
58
|
+
// Forward to MCP server via WebSocket
|
|
59
|
+
if (wsClient && wsClient.readyState === WebSocket.OPEN) {
|
|
60
|
+
wsClient.send(JSON.stringify(msg));
|
|
155
61
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (wsServer) {
|
|
159
|
-
wsServer.close();
|
|
62
|
+
else {
|
|
63
|
+
console.error('[Native Host] No MCP client connected, message dropped');
|
|
160
64
|
}
|
|
161
|
-
|
|
162
|
-
}
|
|
65
|
+
done();
|
|
66
|
+
});
|
|
163
67
|
/**
|
|
164
68
|
* Main entry point
|
|
165
69
|
*/
|
|
166
|
-
|
|
70
|
+
function main() {
|
|
167
71
|
console.error('[Native Host] Starting Gravity Native Host...');
|
|
168
|
-
// Set stdin to binary mode for Native Messaging
|
|
169
|
-
process.stdin.setEncoding('binary');
|
|
170
|
-
process.stdin.pause();
|
|
171
72
|
// Start WebSocket server
|
|
172
73
|
startWebSocketServer();
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
74
|
+
// Setup Native Messaging pipeline
|
|
75
|
+
process.stdin
|
|
76
|
+
.pipe(input)
|
|
77
|
+
.pipe(transform)
|
|
78
|
+
.pipe(output)
|
|
79
|
+
.pipe(process.stdout);
|
|
179
80
|
console.error('[Native Host] Ready and waiting for messages...');
|
|
81
|
+
// Handle stdin close
|
|
82
|
+
process.stdin.on('end', () => {
|
|
83
|
+
console.error('[Native Host] Extension disconnected (stdin closed)');
|
|
84
|
+
if (wsServer) {
|
|
85
|
+
wsServer.close();
|
|
86
|
+
}
|
|
87
|
+
process.exit(0);
|
|
88
|
+
});
|
|
180
89
|
}
|
|
181
90
|
// Handle graceful shutdown
|
|
182
91
|
process.on('SIGINT', () => {
|
|
@@ -193,8 +102,5 @@ process.on('SIGTERM', () => {
|
|
|
193
102
|
}
|
|
194
103
|
process.exit(0);
|
|
195
104
|
});
|
|
196
|
-
main()
|
|
197
|
-
console.error('[Native Host] Fatal error:', error);
|
|
198
|
-
process.exit(1);
|
|
199
|
-
});
|
|
105
|
+
main();
|
|
200
106
|
//# sourceMappingURL=native-host.js.map
|
package/dist/native-host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-host.js","sourceRoot":"","sources":["../src/native-host.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"native-host.js","sourceRoot":"","sources":["../src/native-host.ts"],"names":[],"mappings":"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"}
|
package/extension/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gravity-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.23",
|
|
4
4
|
"description": "Gravity - AI-powered CSS layout diagnostics for any IDE. Connect your browser to get real-time layout issue detection.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"node": ">=16.0.0"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
+
"chrome-native-messaging": "^0.2.0",
|
|
49
50
|
"ws": "^8.18.0"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|