gravity-core 1.0.2 → 1.0.3

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.
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Gravity MCP Server
3
+ *
4
+ * Strict JSON-RPC 2.0 protocol implementation
5
+ * - STDOUT: JSON-RPC messages only
6
+ * - STDERR: Diagnostics and errors only
7
+ * - No banners, emojis, or human-readable output on STDOUT
8
+ */
9
+ import { Gravity } from './index.js';
10
+ // Override console.log to route to stderr
11
+ console.log = (...args) => {
12
+ console.error(...args);
13
+ };
14
+ // Get port from environment or use default
15
+ const port = parseInt(process.env.GRAVITY_PORT || '9224', 10);
16
+ const timeout = parseInt(process.env.GRAVITY_TIMEOUT || '10000', 10);
17
+ // Initialize bridge
18
+ const bridge = new Gravity({ port, timeout });
19
+ // Tool definitions for MCP
20
+ const tools = [
21
+ {
22
+ name: 'diagnose_layout',
23
+ description: 'Diagnose CSS layout issues for a DOM element',
24
+ inputSchema: {
25
+ type: 'object',
26
+ properties: {
27
+ selector: {
28
+ type: 'string',
29
+ description: 'CSS selector for the element to diagnose (e.g., "#modal", ".button")',
30
+ },
31
+ },
32
+ required: ['selector'],
33
+ },
34
+ },
35
+ {
36
+ name: 'check_connection',
37
+ description: 'Check if browser is connected',
38
+ inputSchema: {
39
+ type: 'object',
40
+ properties: {},
41
+ },
42
+ },
43
+ {
44
+ name: 'highlight_element',
45
+ description: 'Highlight an element in the browser',
46
+ inputSchema: {
47
+ type: 'object',
48
+ properties: {
49
+ selector: {
50
+ type: 'string',
51
+ description: 'CSS selector for the element to highlight',
52
+ },
53
+ color: {
54
+ type: 'string',
55
+ description: 'Color for the highlight (default: red)',
56
+ },
57
+ duration: {
58
+ type: 'number',
59
+ description: 'Duration in milliseconds (default: 3000)',
60
+ },
61
+ },
62
+ required: ['selector'],
63
+ },
64
+ },
65
+ ];
66
+ /**
67
+ * Handle MCP tool calls
68
+ */
69
+ async function handleToolCall(toolName, params) {
70
+ switch (toolName) {
71
+ case 'diagnose_layout': {
72
+ if (!bridge.isConnected()) {
73
+ throw new Error('Not connected to browser. Make sure the Gravity extension is loaded and you clicked "Connect to Tab".');
74
+ }
75
+ const result = await bridge.diagnoseLayout(params.selector);
76
+ return result;
77
+ }
78
+ case 'check_connection': {
79
+ const status = bridge.getStatus();
80
+ return {
81
+ connected: status.connected,
82
+ message: status.message,
83
+ timestamp: status.timestamp,
84
+ };
85
+ }
86
+ case 'highlight_element': {
87
+ if (!bridge.isConnected()) {
88
+ throw new Error('Not connected to browser');
89
+ }
90
+ return {
91
+ success: true,
92
+ message: `Highlight request sent for ${params.selector}`,
93
+ };
94
+ }
95
+ default:
96
+ throw new Error(`Unknown tool: ${toolName}`);
97
+ }
98
+ }
99
+ /**
100
+ * Process MCP request
101
+ */
102
+ async function processRequest(request) {
103
+ try {
104
+ if (request.method === 'initialize') {
105
+ return {
106
+ jsonrpc: '2.0',
107
+ id: request.id,
108
+ result: {
109
+ protocolVersion: '2024-11-05',
110
+ capabilities: {
111
+ tools: {},
112
+ },
113
+ serverInfo: {
114
+ name: 'gravity',
115
+ version: '1.0.3',
116
+ },
117
+ },
118
+ };
119
+ }
120
+ if (request.method === 'tools/list') {
121
+ return {
122
+ jsonrpc: '2.0',
123
+ id: request.id,
124
+ result: {
125
+ tools,
126
+ },
127
+ };
128
+ }
129
+ if (request.method === 'tools/call') {
130
+ const { name, arguments: args } = request.params;
131
+ const result = await handleToolCall(name, args);
132
+ return {
133
+ jsonrpc: '2.0',
134
+ id: request.id,
135
+ result: {
136
+ type: 'text',
137
+ text: JSON.stringify(result, null, 2),
138
+ },
139
+ };
140
+ }
141
+ return {
142
+ jsonrpc: '2.0',
143
+ id: request.id,
144
+ error: {
145
+ code: -32601,
146
+ message: 'Method not found',
147
+ },
148
+ };
149
+ }
150
+ catch (error) {
151
+ return {
152
+ jsonrpc: '2.0',
153
+ id: request.id,
154
+ error: {
155
+ code: -32603,
156
+ message: error.message || 'Internal error',
157
+ data: {
158
+ type: error.constructor.name,
159
+ },
160
+ },
161
+ };
162
+ }
163
+ }
164
+ /**
165
+ * Main MCP server entry point
166
+ */
167
+ async function main() {
168
+ // Connect to browser (diagnostics to stderr only)
169
+ try {
170
+ await bridge.connectBrowser(port);
171
+ }
172
+ catch (error) {
173
+ console.error('Failed to connect to extension:', error.message);
174
+ process.exit(1);
175
+ }
176
+ // Listen for stdin (MCP protocol)
177
+ process.stdin.setEncoding('utf-8');
178
+ let buffer = '';
179
+ process.stdin.on('data', async (chunk) => {
180
+ buffer += chunk;
181
+ // Process complete JSON objects
182
+ const lines = buffer.split('\n');
183
+ buffer = lines[lines.length - 1]; // Keep incomplete line in buffer
184
+ for (let i = 0; i < lines.length - 1; i++) {
185
+ const line = lines[i].trim();
186
+ if (!line)
187
+ continue;
188
+ try {
189
+ const request = JSON.parse(line);
190
+ const response = await processRequest(request);
191
+ // STDOUT: JSON-RPC response only
192
+ process.stdout.write(JSON.stringify(response) + '\n');
193
+ }
194
+ catch (error) {
195
+ // STDERR: Parse errors only
196
+ console.error('Error processing request:', error.message);
197
+ }
198
+ }
199
+ });
200
+ process.stdin.on('end', async () => {
201
+ await bridge.disconnectBrowser();
202
+ process.exit(0);
203
+ });
204
+ // Handle errors
205
+ process.on('error', (error) => {
206
+ console.error('Fatal error:', error);
207
+ process.exit(1);
208
+ });
209
+ // Graceful shutdown
210
+ process.on('SIGINT', async () => {
211
+ await bridge.disconnectBrowser();
212
+ process.exit(0);
213
+ });
214
+ process.on('SIGTERM', async () => {
215
+ await bridge.disconnectBrowser();
216
+ process.exit(0);
217
+ });
218
+ }
219
+ main().catch((error) => {
220
+ console.error('Fatal error:', error);
221
+ process.exit(1);
222
+ });
223
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ @echo off
2
+ REM Gravity DevTools Bridge Native Host
3
+ REM This script handles native messaging between Chrome extension and the Gravity MCP server
4
+
5
+ setlocal enabledelayedexpansion
6
+
7
+ REM Get the directory where this script is located
8
+ set SCRIPT_DIR=%~dp0
9
+
10
+ REM Start the Gravity MCP server
11
+ node "%SCRIPT_DIR%..\dist\cli.js"
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "com.devtools.bridge",
3
+ "description": "Gravity DevTools Bridge - Native messaging host for Chrome extension",
4
+ "path": "PLACEHOLDER_PATH",
5
+ "type": "stdio",
6
+ "allowed_origins": [
7
+ "PLACEHOLDER_EXTENSION_ID"
8
+ ]
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gravity-core",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
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",
@@ -11,6 +11,7 @@
11
11
  "files": [
12
12
  "dist",
13
13
  "extension",
14
+ "native-host",
14
15
  "README.md",
15
16
  "LICENSE",
16
17
  "SETUP.md"