gravity-lite 3.0.0
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/LICENSE +21 -0
- package/README.md +126 -0
- package/dist/bridge.d.ts +12 -0
- package/dist/bridge.js +103 -0
- package/dist/bridge.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +73 -0
- package/dist/cli.js.map +1 -0
- package/dist/diagnostics.d.ts +67 -0
- package/dist/diagnostics.js +329 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/mcp-server.d.ts +18 -0
- package/dist/mcp-server.js +517 -0
- package/dist/mcp-server.js.map +1 -0
- package/extension/background.js +197 -0
- package/extension/icon128.svg +1 -0
- package/extension/icon16.svg +1 -0
- package/extension/icon48.svg +1 -0
- package/extension/manifest.json +24 -0
- package/extension/offscreen.html +4 -0
- package/extension/offscreen.js +74 -0
- package/extension/popup.html +105 -0
- package/extension/popup.js +84 -0
- package/package.json +59 -0
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* mcp-server.ts — Gravity MCP Server v3
|
|
3
|
+
*
|
|
4
|
+
* Tools built around the top real-world UI debugging pain points:
|
|
5
|
+
* 1. connect_browser — check extension connection status
|
|
6
|
+
* 2. diagnose_layout — offscreen, hidden, overflow issues
|
|
7
|
+
* 3. inspect_stacking — z-index traps, stacking context analysis
|
|
8
|
+
* 4. check_accessibility — contrast ratio, touch targets, ARIA
|
|
9
|
+
* 5. inspect_responsive — fixed widths, breakpoint analysis
|
|
10
|
+
* 6. debug_flexgrid — flexbox/grid container + children analysis
|
|
11
|
+
* 7. get_computed_layout — full computed style snapshot
|
|
12
|
+
* 8. highlight_element — visual overlay in browser
|
|
13
|
+
* 9. screenshot_element — capture element as PNG
|
|
14
|
+
* 10. get_page_performance — layout paint metrics from Chrome
|
|
15
|
+
*/
|
|
16
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
17
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
18
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
19
|
+
import { startBridge, sendCDP, isExtensionConnected, getBridgePort } from './bridge.js';
|
|
20
|
+
import { validateSelector, extractBounds, sortBySeverity, checkVisibility, checkOffscreen, checkOverflow, checkZIndex, checkStackingContextCreators, checkFlexGrid, checkResponsive, checkAccessibilityStyles, checkColorContrast, checkCustomProperties, } from './diagnostics.js';
|
|
21
|
+
// ── Tool definitions ──────────────────────────────────────────────────────────
|
|
22
|
+
const TOOLS = [
|
|
23
|
+
{
|
|
24
|
+
name: 'connect_browser',
|
|
25
|
+
description: 'Check whether the Gravity Chrome extension is connected and ready. Call this first to verify setup.',
|
|
26
|
+
inputSchema: { type: 'object', properties: {} },
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'diagnose_layout',
|
|
30
|
+
description: 'Full layout diagnosis for an element: detects overflow, offscreen positioning, hidden visibility, unresolved CSS variables, and responsive sizing issues. Best first tool to run on any broken element.',
|
|
31
|
+
inputSchema: {
|
|
32
|
+
type: 'object',
|
|
33
|
+
properties: {
|
|
34
|
+
selector: { type: 'string', description: "CSS selector, e.g. '#modal', '.nav-bar', 'button.primary'" },
|
|
35
|
+
},
|
|
36
|
+
required: ['selector'],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'inspect_stacking',
|
|
41
|
+
description: "Diagnose z-index and stacking context problems — the #1 CSS pain point. Reveals why 'z-index: 9999' still goes behind other elements, identifies which CSS properties trap elements in stacking contexts (transform, opacity, filter, etc.), and shows the full stacking context chain.",
|
|
42
|
+
inputSchema: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
selector: { type: 'string', description: 'CSS selector of the element with layering issues' },
|
|
46
|
+
},
|
|
47
|
+
required: ['selector'],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'check_accessibility',
|
|
52
|
+
description: 'Audit an element for accessibility issues: WCAG color contrast ratio (AA & AAA), touch target size (44×44px minimum), pointer-events blocking interaction, missing cursor feedback, and ARIA role from the accessibility tree.',
|
|
53
|
+
inputSchema: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
properties: {
|
|
56
|
+
selector: { type: 'string', description: 'CSS selector' },
|
|
57
|
+
},
|
|
58
|
+
required: ['selector'],
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'inspect_responsive',
|
|
63
|
+
description: 'Analyze how an element behaves across screen sizes: detects fixed pixel widths that will break on mobile, elements wider than the viewport, and missing responsive patterns. Also reports current viewport size.',
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
properties: {
|
|
67
|
+
selector: { type: 'string', description: 'CSS selector' },
|
|
68
|
+
},
|
|
69
|
+
required: ['selector'],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'debug_flexgrid',
|
|
74
|
+
description: 'Deep inspection of flexbox and CSS Grid containers: shows all layout properties, analyzes each child element for overflow/shrink issues, detects collapsed containers, and flags common flex/grid pitfalls.',
|
|
75
|
+
inputSchema: {
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: {
|
|
78
|
+
selector: { type: 'string', description: 'CSS selector of the flex or grid container' },
|
|
79
|
+
},
|
|
80
|
+
required: ['selector'],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'get_computed_layout',
|
|
85
|
+
description: 'Get a complete snapshot of computed CSS properties for an element: box model, all layout-related styles, custom property values, and applied CSS rules with specificity.',
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {
|
|
89
|
+
selector: { type: 'string', description: 'CSS selector' },
|
|
90
|
+
},
|
|
91
|
+
required: ['selector'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'highlight_element',
|
|
96
|
+
description: 'Visually highlight an element in the browser with color-coded overlays (content/padding/border/margin). Useful for confirming which element is being diagnosed.',
|
|
97
|
+
inputSchema: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
selector: { type: 'string', description: 'CSS selector' },
|
|
101
|
+
duration: { type: 'number', description: 'Highlight duration in ms (default: 3000, 0 = permanent until next call)' },
|
|
102
|
+
},
|
|
103
|
+
required: ['selector'],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'screenshot_element',
|
|
108
|
+
description: 'Capture a screenshot of a specific element. Returns a base64-encoded PNG. Use to visually document bugs or verify fixes.',
|
|
109
|
+
inputSchema: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
selector: { type: 'string', description: 'CSS selector' },
|
|
113
|
+
},
|
|
114
|
+
required: ['selector'],
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'get_page_performance',
|
|
119
|
+
description: 'Get page-level layout and performance metrics: viewport dimensions, scroll position, total page size, layout paint timings, and a count of elements that may be causing layout thrashing.',
|
|
120
|
+
inputSchema: { type: 'object', properties: {} },
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
// ── MCP server ────────────────────────────────────────────────────────────────
|
|
124
|
+
const server = new Server({ name: 'gravity', version: '3.0.0' }, { capabilities: { tools: {} } });
|
|
125
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
126
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
127
|
+
const { name, arguments: args } = request.params;
|
|
128
|
+
try {
|
|
129
|
+
// ── connect_browser ───────────────────────────────────────────────────────
|
|
130
|
+
if (name === 'connect_browser') {
|
|
131
|
+
const connected = isExtensionConnected();
|
|
132
|
+
return ok({
|
|
133
|
+
status: connected ? 'connected' : 'waiting',
|
|
134
|
+
port: getBridgePort(),
|
|
135
|
+
message: connected
|
|
136
|
+
? 'Gravity extension is connected and ready.'
|
|
137
|
+
: `Waiting for extension. Open Chrome → load the Gravity extension → click "Connect to Tab". Extension connects to ws://127.0.0.1:${getBridgePort()}.`,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// ── shared helpers ────────────────────────────────────────────────────────
|
|
141
|
+
async function resolveNode(selector) {
|
|
142
|
+
const v = validateSelector(selector);
|
|
143
|
+
if (!v.valid)
|
|
144
|
+
throw new Error(`Invalid selector: ${v.error}`);
|
|
145
|
+
const { root } = await cdp('DOM.getDocument', { depth: -1 });
|
|
146
|
+
const { nodeId } = await cdp('DOM.querySelector', { nodeId: root.nodeId, selector });
|
|
147
|
+
if (!nodeId)
|
|
148
|
+
throw new Error(`Element not found: ${selector}`);
|
|
149
|
+
return nodeId;
|
|
150
|
+
}
|
|
151
|
+
async function getStyles(nodeId) {
|
|
152
|
+
const { computedStyle } = await cdp('CSS.getComputedStyleForNode', { nodeId });
|
|
153
|
+
return new Map(computedStyle.map(p => [p.name, p.value]));
|
|
154
|
+
}
|
|
155
|
+
// ── diagnose_layout ───────────────────────────────────────────────────────
|
|
156
|
+
if (name === 'diagnose_layout') {
|
|
157
|
+
const selector = args?.selector;
|
|
158
|
+
if (!selector)
|
|
159
|
+
throw new Error('selector is required');
|
|
160
|
+
const nodeId = await resolveNode(selector);
|
|
161
|
+
const { model } = await cdp('DOM.getBoxModel', { nodeId });
|
|
162
|
+
const { layoutViewport: vp } = await cdp('Page.getLayoutMetrics');
|
|
163
|
+
const styles = await getStyles(nodeId);
|
|
164
|
+
const bounds = extractBounds(model);
|
|
165
|
+
const issues = sortBySeverity([
|
|
166
|
+
...checkVisibility(styles),
|
|
167
|
+
...checkOffscreen(bounds, vp),
|
|
168
|
+
...checkOverflow(styles),
|
|
169
|
+
...checkCustomProperties(styles),
|
|
170
|
+
...checkResponsive(styles, bounds, vp),
|
|
171
|
+
]);
|
|
172
|
+
return ok({
|
|
173
|
+
element: selector,
|
|
174
|
+
timestamp: new Date().toISOString(),
|
|
175
|
+
position: bounds,
|
|
176
|
+
viewport: { width: vp.clientWidth, height: vp.clientHeight },
|
|
177
|
+
computedStyles: pick(styles, ['display', 'position', 'width', 'height', 'overflow', 'z-index', 'visibility', 'opacity', 'max-width', 'min-height']),
|
|
178
|
+
issues: issues.length ? issues : [{ type: 'none', severity: 'low', message: 'No layout issues detected', suggestion: 'Element appears correctly positioned' }],
|
|
179
|
+
summary: summarize(issues),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// ── inspect_stacking ──────────────────────────────────────────────────────
|
|
183
|
+
if (name === 'inspect_stacking') {
|
|
184
|
+
const selector = args?.selector;
|
|
185
|
+
if (!selector)
|
|
186
|
+
throw new Error('selector is required');
|
|
187
|
+
const nodeId = await resolveNode(selector);
|
|
188
|
+
const styles = await getStyles(nodeId);
|
|
189
|
+
const zIssues = checkZIndex(styles);
|
|
190
|
+
const { creates, reasons } = checkStackingContextCreators(styles);
|
|
191
|
+
// Walk up ancestors to find stacking context creators
|
|
192
|
+
const ancestors = [];
|
|
193
|
+
try {
|
|
194
|
+
const { node } = await cdp('DOM.describeNode', { nodeId, depth: 0 });
|
|
195
|
+
let parentId = node.parentId;
|
|
196
|
+
let depth = 0;
|
|
197
|
+
while (parentId && depth < 10) {
|
|
198
|
+
const { node: parent } = await cdp('DOM.describeNode', { nodeId: parentId, depth: 0 });
|
|
199
|
+
if (!parent || parent.nodeType !== 1)
|
|
200
|
+
break; // element nodes only
|
|
201
|
+
const { computedStyle: ps } = await cdp('CSS.getComputedStyleForNode', { nodeId: parentId });
|
|
202
|
+
const parentStyles = new Map(ps.map(p => [p.name, p.value]));
|
|
203
|
+
const sc = checkStackingContextCreators(parentStyles);
|
|
204
|
+
if (sc.creates) {
|
|
205
|
+
ancestors.push({ tag: parent.localName, creates: true, reasons: sc.reasons });
|
|
206
|
+
}
|
|
207
|
+
parentId = parent.parentId;
|
|
208
|
+
depth++;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
// Ancestor walk is best-effort
|
|
213
|
+
}
|
|
214
|
+
return ok({
|
|
215
|
+
element: selector,
|
|
216
|
+
zIndex: styles.get('z-index') ?? 'auto',
|
|
217
|
+
position: styles.get('position') ?? 'static',
|
|
218
|
+
createsStackingContext: creates,
|
|
219
|
+
stackingContextReasons: reasons,
|
|
220
|
+
issues: sortBySeverity(zIssues),
|
|
221
|
+
ancestorsWithStackingContext: ancestors,
|
|
222
|
+
explanation: ancestors.length > 0
|
|
223
|
+
? `This element is nested inside ${ancestors.length} stacking context(s). Even with a high z-index, it cannot appear above elements outside these contexts.`
|
|
224
|
+
: 'No ancestor stacking contexts found. z-index should work normally relative to siblings.',
|
|
225
|
+
tip: 'The most common cause of z-index not working: a parent has transform, opacity < 1, or filter applied — these create isolated stacking contexts.',
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
// ── check_accessibility ───────────────────────────────────────────────────
|
|
229
|
+
if (name === 'check_accessibility') {
|
|
230
|
+
const selector = args?.selector;
|
|
231
|
+
if (!selector)
|
|
232
|
+
throw new Error('selector is required');
|
|
233
|
+
const nodeId = await resolveNode(selector);
|
|
234
|
+
const styles = await getStyles(nodeId);
|
|
235
|
+
const { model } = await cdp('DOM.getBoxModel', { nodeId });
|
|
236
|
+
const bounds = extractBounds(model);
|
|
237
|
+
const styleIssues = [
|
|
238
|
+
...checkAccessibilityStyles(styles),
|
|
239
|
+
...checkColorContrast(styles),
|
|
240
|
+
...checkResponsive(styles, bounds, { clientWidth: 375 }), // check against mobile viewport
|
|
241
|
+
].filter(i => i.type === 'small-touch-target' || i.type.startsWith('contrast') || i.type.startsWith('pointer') || i.type.startsWith('user-select') || i.type.startsWith('missing'));
|
|
242
|
+
// Get ARIA info from accessibility tree
|
|
243
|
+
let ariaInfo = {};
|
|
244
|
+
try {
|
|
245
|
+
await cdp('Accessibility.enable', {});
|
|
246
|
+
const { nodes } = await cdp('Accessibility.queryAXTree', { nodeId, accessibleNameMaxLength: 200 });
|
|
247
|
+
if (nodes?.length > 0) {
|
|
248
|
+
const n = nodes[0];
|
|
249
|
+
ariaInfo = {
|
|
250
|
+
role: n.role?.value,
|
|
251
|
+
name: n.name?.value,
|
|
252
|
+
description: n.description?.value,
|
|
253
|
+
focusable: n.focusable,
|
|
254
|
+
ignored: n.ignored,
|
|
255
|
+
ignoredReasons: n.ignoredReasons?.map((r) => r.value),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
ariaInfo = { note: 'Accessibility tree not available for this element' };
|
|
261
|
+
}
|
|
262
|
+
// Color contrast detail
|
|
263
|
+
const fg = styles.get('color');
|
|
264
|
+
const bg = styles.get('background-color');
|
|
265
|
+
const fontSize = parseFloat(styles.get('font-size') ?? '16');
|
|
266
|
+
return ok({
|
|
267
|
+
element: selector,
|
|
268
|
+
size: { width: bounds.width, height: bounds.height },
|
|
269
|
+
touchTargetOk: bounds.width >= 44 && bounds.height >= 44,
|
|
270
|
+
colorContrast: fg && bg ? {
|
|
271
|
+
foreground: fg,
|
|
272
|
+
background: bg,
|
|
273
|
+
fontSize: `${fontSize}px`,
|
|
274
|
+
} : null,
|
|
275
|
+
ariaInfo,
|
|
276
|
+
issues: sortBySeverity(styleIssues),
|
|
277
|
+
summary: summarize(styleIssues),
|
|
278
|
+
wcagReference: 'https://www.w3.org/WAI/WCAG21/quickref/',
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
// ── inspect_responsive ────────────────────────────────────────────────────
|
|
282
|
+
if (name === 'inspect_responsive') {
|
|
283
|
+
const selector = args?.selector;
|
|
284
|
+
if (!selector)
|
|
285
|
+
throw new Error('selector is required');
|
|
286
|
+
const nodeId = await resolveNode(selector);
|
|
287
|
+
const styles = await getStyles(nodeId);
|
|
288
|
+
const { model } = await cdp('DOM.getBoxModel', { nodeId });
|
|
289
|
+
const { layoutViewport: vp } = await cdp('Page.getLayoutMetrics');
|
|
290
|
+
const bounds = extractBounds(model);
|
|
291
|
+
const issues = sortBySeverity(checkResponsive(styles, bounds, vp));
|
|
292
|
+
const widthPercent = vp.clientWidth > 0 ? Math.round((bounds.width / vp.clientWidth) * 100) : 0;
|
|
293
|
+
return ok({
|
|
294
|
+
element: selector,
|
|
295
|
+
viewport: { width: vp.clientWidth, height: vp.clientHeight },
|
|
296
|
+
elementSize: { width: bounds.width, height: bounds.height },
|
|
297
|
+
widthVsViewport: `${widthPercent}%`,
|
|
298
|
+
cssWidth: styles.get('width'),
|
|
299
|
+
cssMaxWidth: styles.get('max-width'),
|
|
300
|
+
cssMinWidth: styles.get('min-width'),
|
|
301
|
+
mediaQueriesNote: 'Gravity reads computed styles — media queries are already applied for the current viewport size',
|
|
302
|
+
issues: issues.length ? issues : [{ type: 'none', severity: 'low', message: 'No responsive issues detected at current viewport size', suggestion: 'Resize the browser window and run again to test other breakpoints' }],
|
|
303
|
+
summary: summarize(issues),
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
// ── debug_flexgrid ────────────────────────────────────────────────────────
|
|
307
|
+
if (name === 'debug_flexgrid') {
|
|
308
|
+
const selector = args?.selector;
|
|
309
|
+
if (!selector)
|
|
310
|
+
throw new Error('selector is required');
|
|
311
|
+
const nodeId = await resolveNode(selector);
|
|
312
|
+
const styles = await getStyles(nodeId);
|
|
313
|
+
const { model } = await cdp('DOM.getBoxModel', { nodeId });
|
|
314
|
+
const bounds = extractBounds(model);
|
|
315
|
+
const display = styles.get('display') ?? 'block';
|
|
316
|
+
const isFlexOrGrid = display.includes('flex') || display.includes('grid');
|
|
317
|
+
const containerIssues = sortBySeverity(checkFlexGrid(styles));
|
|
318
|
+
// Get children and analyze each one
|
|
319
|
+
const children = [];
|
|
320
|
+
try {
|
|
321
|
+
const { node } = await cdp('DOM.describeNode', { nodeId, depth: 1 });
|
|
322
|
+
const childNodes = (node.children ?? []).filter((c) => c.nodeType === 1).slice(0, 10); // first 10 children
|
|
323
|
+
for (const child of childNodes) {
|
|
324
|
+
const { computedStyle: cs } = await cdp('CSS.getComputedStyleForNode', { nodeId: child.nodeId });
|
|
325
|
+
const childStyles = new Map(cs.map(p => [p.name, p.value]));
|
|
326
|
+
const { model: cm } = await cdp('DOM.getBoxModel', { nodeId: child.nodeId });
|
|
327
|
+
const childBounds = extractBounds(cm);
|
|
328
|
+
const { layoutViewport: vp } = await cdp('Page.getLayoutMetrics');
|
|
329
|
+
children.push({
|
|
330
|
+
tag: child.localName,
|
|
331
|
+
size: { width: childBounds.width, height: childBounds.height },
|
|
332
|
+
flexShrink: childStyles.get('flex-shrink'),
|
|
333
|
+
flexGrow: childStyles.get('flex-grow'),
|
|
334
|
+
flexBasis: childStyles.get('flex-basis'),
|
|
335
|
+
minWidth: childStyles.get('min-width'),
|
|
336
|
+
overflow: childStyles.get('overflow'),
|
|
337
|
+
overflowing: childBounds.right > bounds.right + 2,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
catch {
|
|
342
|
+
// Child analysis best-effort
|
|
343
|
+
}
|
|
344
|
+
return ok({
|
|
345
|
+
element: selector,
|
|
346
|
+
display,
|
|
347
|
+
isFlexOrGrid,
|
|
348
|
+
containerSize: { width: bounds.width, height: bounds.height },
|
|
349
|
+
containerProperties: isFlexOrGrid ? pick(styles, [
|
|
350
|
+
'display', 'flex-direction', 'flex-wrap', 'justify-content', 'align-items',
|
|
351
|
+
'align-content', 'gap', 'row-gap', 'column-gap',
|
|
352
|
+
'grid-template-columns', 'grid-template-rows', 'grid-auto-flow',
|
|
353
|
+
]) : pick(styles, ['display', 'width', 'height', 'overflow']),
|
|
354
|
+
children: children.length > 0 ? children : 'No child elements found (or selector is not a container)',
|
|
355
|
+
issues: containerIssues,
|
|
356
|
+
summary: summarize(containerIssues),
|
|
357
|
+
tip: display.includes('flex')
|
|
358
|
+
? 'Common flex issues: min-width: auto on children causes overflow; align-items: stretch needs explicit height on container'
|
|
359
|
+
: display.includes('grid')
|
|
360
|
+
? 'Common grid issues: no grid-template-columns defined; grid items escaping with absolute positioning'
|
|
361
|
+
: 'Element is not a flex or grid container. Switch display to flex or grid to use this tool effectively.',
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
// ── get_computed_layout ───────────────────────────────────────────────────
|
|
365
|
+
if (name === 'get_computed_layout') {
|
|
366
|
+
const selector = args?.selector;
|
|
367
|
+
if (!selector)
|
|
368
|
+
throw new Error('selector is required');
|
|
369
|
+
const nodeId = await resolveNode(selector);
|
|
370
|
+
const styles = await getStyles(nodeId);
|
|
371
|
+
const { model } = await cdp('DOM.getBoxModel', { nodeId });
|
|
372
|
+
// Get applied CSS rules with selectors (for specificity debugging)
|
|
373
|
+
let appliedRules = [];
|
|
374
|
+
try {
|
|
375
|
+
const { matchedCSSRules } = await cdp('CSS.getMatchedStylesForNode', { nodeId });
|
|
376
|
+
appliedRules = (matchedCSSRules ?? []).slice(0, 5).map((r) => ({
|
|
377
|
+
selector: r.rule?.selectorList?.text,
|
|
378
|
+
origin: r.rule?.origin,
|
|
379
|
+
styleText: r.rule?.style?.cssText?.slice(0, 200),
|
|
380
|
+
}));
|
|
381
|
+
}
|
|
382
|
+
catch { /* best-effort */ }
|
|
383
|
+
return ok({
|
|
384
|
+
selector,
|
|
385
|
+
boxModel: {
|
|
386
|
+
content: { width: model.width, height: model.height },
|
|
387
|
+
padding: `${model.width - model.content[2] + model.content[0]}px`,
|
|
388
|
+
},
|
|
389
|
+
layout: pick(styles, [
|
|
390
|
+
'display', 'position', 'top', 'right', 'bottom', 'left',
|
|
391
|
+
'width', 'height', 'max-width', 'min-width', 'max-height', 'min-height',
|
|
392
|
+
'margin', 'padding', 'box-sizing',
|
|
393
|
+
]),
|
|
394
|
+
flex: pick(styles, ['flex-direction', 'flex-wrap', 'justify-content', 'align-items', 'flex-grow', 'flex-shrink', 'flex-basis']),
|
|
395
|
+
grid: pick(styles, ['grid-template-columns', 'grid-template-rows', 'grid-column', 'grid-row', 'gap']),
|
|
396
|
+
visual: pick(styles, ['overflow', 'z-index', 'opacity', 'visibility', 'transform', 'filter', 'pointer-events']),
|
|
397
|
+
typography: pick(styles, ['font-size', 'font-weight', 'line-height', 'color', 'background-color']),
|
|
398
|
+
appliedRules: appliedRules.length > 0 ? appliedRules : 'Run from an active tab with CSS loaded',
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
// ── highlight_element ─────────────────────────────────────────────────────
|
|
402
|
+
if (name === 'highlight_element') {
|
|
403
|
+
const selector = args?.selector;
|
|
404
|
+
const duration = args?.duration ?? 3000;
|
|
405
|
+
if (!selector)
|
|
406
|
+
throw new Error('selector is required');
|
|
407
|
+
const nodeId = await resolveNode(selector);
|
|
408
|
+
await cdp('DOM.highlightNode', {
|
|
409
|
+
nodeId,
|
|
410
|
+
highlightConfig: {
|
|
411
|
+
showInfo: true,
|
|
412
|
+
showRulers: true,
|
|
413
|
+
contentColor: { r: 111, g: 168, b: 220, a: 0.66 },
|
|
414
|
+
paddingColor: { r: 147, g: 196, b: 125, a: 0.55 },
|
|
415
|
+
borderColor: { r: 255, g: 229, b: 153, a: 0.66 },
|
|
416
|
+
marginColor: { r: 246, g: 178, b: 107, a: 0.66 },
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
if (duration > 0)
|
|
420
|
+
setTimeout(() => cdp('DOM.hideHighlight', {}).catch(() => { }), duration);
|
|
421
|
+
return ok({ success: true, selector, duration, message: `Element highlighted in browser for ${duration}ms` });
|
|
422
|
+
}
|
|
423
|
+
// ── screenshot_element ────────────────────────────────────────────────────
|
|
424
|
+
if (name === 'screenshot_element') {
|
|
425
|
+
const selector = args?.selector;
|
|
426
|
+
if (!selector)
|
|
427
|
+
throw new Error('selector is required');
|
|
428
|
+
const nodeId = await resolveNode(selector);
|
|
429
|
+
const { model } = await cdp('DOM.getBoxModel', { nodeId });
|
|
430
|
+
const clip = { x: model.content[0], y: model.content[1], width: model.width, height: model.height, scale: 1 };
|
|
431
|
+
const { data } = await cdp('Page.captureScreenshot', { clip, format: 'png' });
|
|
432
|
+
return ok({ selector, screenshot: `data:image/png;base64,${data}`, bounds: clip });
|
|
433
|
+
}
|
|
434
|
+
// ── get_page_performance ──────────────────────────────────────────────────
|
|
435
|
+
if (name === 'get_page_performance') {
|
|
436
|
+
const { layoutViewport, contentSize } = await cdp('Page.getLayoutMetrics');
|
|
437
|
+
// Count potentially layout-thrashing elements (those with position:fixed/absolute, transform, etc.)
|
|
438
|
+
let heavyElements = 0;
|
|
439
|
+
try {
|
|
440
|
+
const { root } = await cdp('DOM.getDocument', { depth: 1 });
|
|
441
|
+
const result = await cdp('Runtime.evaluate', {
|
|
442
|
+
expression: `(() => {
|
|
443
|
+
const all = document.querySelectorAll('*');
|
|
444
|
+
let heavy = 0;
|
|
445
|
+
for (const el of all) {
|
|
446
|
+
const s = getComputedStyle(el);
|
|
447
|
+
if (s.transform !== 'none' || s.filter !== 'none' || s.willChange !== 'auto' || s.position === 'fixed') heavy++;
|
|
448
|
+
}
|
|
449
|
+
return heavy;
|
|
450
|
+
})()`,
|
|
451
|
+
returnByValue: true,
|
|
452
|
+
});
|
|
453
|
+
heavyElements = result?.result?.value ?? 0;
|
|
454
|
+
}
|
|
455
|
+
catch { /* best-effort */ }
|
|
456
|
+
// Get paint metrics
|
|
457
|
+
let paintMetrics = [];
|
|
458
|
+
try {
|
|
459
|
+
const { metrics } = await cdp('Performance.getMetrics');
|
|
460
|
+
paintMetrics = (metrics ?? []).filter((m) => ['LayoutDuration', 'RecalcStyleDuration', 'FirstMeaningfulPaint', 'DOMContentLoaded'].includes(m.name));
|
|
461
|
+
}
|
|
462
|
+
catch { /* best-effort */ }
|
|
463
|
+
return ok({
|
|
464
|
+
viewport: { width: layoutViewport.clientWidth, height: layoutViewport.clientHeight },
|
|
465
|
+
pageSize: { width: contentSize.width, height: contentSize.height },
|
|
466
|
+
scrollable: contentSize.height > layoutViewport.clientHeight,
|
|
467
|
+
scrollRatio: contentSize.height > 0 ? `${Math.round((contentSize.height / layoutViewport.clientHeight) * 100)}%` : '100%',
|
|
468
|
+
elementsWithHeavyCSSProperties: heavyElements,
|
|
469
|
+
performanceMetrics: paintMetrics,
|
|
470
|
+
tip: heavyElements > 50
|
|
471
|
+
? `${heavyElements} elements use transform/filter/will-change/fixed positioning — this can cause paint thrashing on scroll. Review with Chrome DevTools Layers panel.`
|
|
472
|
+
: 'Page appears lightweight from a CSS performance perspective.',
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
479
|
+
return {
|
|
480
|
+
content: [{ type: 'text', text: JSON.stringify({ error: msg, tool: name, timestamp: new Date().toISOString() }, null, 2) }],
|
|
481
|
+
isError: true,
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
// ── Utility helpers ───────────────────────────────────────────────────────────
|
|
486
|
+
async function cdp(method, params = {}) {
|
|
487
|
+
return sendCDP(method, params);
|
|
488
|
+
}
|
|
489
|
+
function ok(data) {
|
|
490
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
491
|
+
}
|
|
492
|
+
function pick(styles, keys) {
|
|
493
|
+
const out = {};
|
|
494
|
+
for (const k of keys)
|
|
495
|
+
out[k] = styles.get(k);
|
|
496
|
+
return out;
|
|
497
|
+
}
|
|
498
|
+
function summarize(issues) {
|
|
499
|
+
return {
|
|
500
|
+
total: issues.length,
|
|
501
|
+
high: issues.filter(i => i.severity === 'high').length,
|
|
502
|
+
medium: issues.filter(i => i.severity === 'medium').length,
|
|
503
|
+
low: issues.filter(i => i.severity === 'low').length,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
// ── GravityMCPServer ──────────────────────────────────────────────────────────
|
|
507
|
+
export class GravityMCPServer {
|
|
508
|
+
async run() {
|
|
509
|
+
await startBridge();
|
|
510
|
+
const transport = new StdioServerTransport();
|
|
511
|
+
await server.connect(transport);
|
|
512
|
+
console.error('[gravity] MCP server ready — 10 tools loaded');
|
|
513
|
+
process.on('SIGINT', () => process.exit(0));
|
|
514
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
//# 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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"}
|