safari-devtools-mcp 1.6.0 → 1.8.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/README.md +15 -1
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +6 -1
- package/build/src/index.js.map +1 -1
- package/build/src/tools/emulation.d.ts +1 -0
- package/build/src/tools/emulation.d.ts.map +1 -1
- package/build/src/tools/emulation.js +239 -0
- package/build/src/tools/emulation.js.map +1 -1
- package/build/src/tools/ios-validation.d.ts +8 -0
- package/build/src/tools/ios-validation.d.ts.map +1 -0
- package/build/src/tools/ios-validation.js +282 -0
- package/build/src/tools/ios-validation.js.map +1 -0
- package/build/src/tools/webkit-compat.d.ts +11 -0
- package/build/src/tools/webkit-compat.d.ts.map +1 -0
- package/build/src/tools/webkit-compat.js +218 -0
- package/build/src/tools/webkit-compat.js.map +1 -0
- package/build/src/version.d.ts +1 -1
- package/build/src/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -208,7 +208,7 @@ The server exposes guided debugging workflows as MCP prompts. Clients that suppo
|
|
|
208
208
|
| `safari-specific-debugging` | Debug WebKit quirks — CSS prefixes, JS feature gaps, ITP/CORS issues |
|
|
209
209
|
| `performance-debugging` | Performance analysis — Navigation Timing, Core Web Vitals, resource waterfall |
|
|
210
210
|
|
|
211
|
-
## Tools (
|
|
211
|
+
## Tools (45)
|
|
212
212
|
|
|
213
213
|
### Debugging
|
|
214
214
|
|
|
@@ -286,6 +286,20 @@ The server exposes guided debugging workflows as MCP prompts. Clients that suppo
|
|
|
286
286
|
| `press_key` | Press a key or combination (e.g., `Meta+A`, `Enter`) |
|
|
287
287
|
| `upload_file` | Upload a file through a file input |
|
|
288
288
|
|
|
289
|
+
### iOS Safari validation
|
|
290
|
+
|
|
291
|
+
| Tool | Description |
|
|
292
|
+
| ----------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
293
|
+
| `inspect_viewport_meta` | Parse the viewport meta tag and validate against iOS best practices (width, zoom, viewport-fit) |
|
|
294
|
+
| `get_safe_area_insets` | Read CSS safe-area-inset values and check whether the page handles notched devices correctly |
|
|
295
|
+
| `check_ios_web_app_readiness` | Audit the page for Add to Home Screen / PWA readiness (apple-touch-icon, manifest, splash screens, status bar) |
|
|
296
|
+
|
|
297
|
+
### WebKit CSS compatibility
|
|
298
|
+
|
|
299
|
+
| Tool | Description |
|
|
300
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
301
|
+
| `check_webkit_compatibility` | Scan stylesheets for Safari CSS issues — missing -webkit- prefixes, known WebKit quirks, and deprecated syntax |
|
|
302
|
+
|
|
289
303
|
## Architecture
|
|
290
304
|
|
|
291
305
|
```
|
package/build/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAyC/C,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,aAAkB,GAAG;IAClE,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,YAAY,CAAC;CACtB,CA2CA"}
|
package/build/src/index.js
CHANGED
|
@@ -21,7 +21,9 @@ import { tools as cssTools } from './tools/css.js';
|
|
|
21
21
|
import { tools as cookieTools } from './tools/cookies.js';
|
|
22
22
|
import { tools as storageTools } from './tools/storage.js';
|
|
23
23
|
import { tools as inputTools } from './tools/input.js';
|
|
24
|
-
import { tools as emulationTools } from './tools/emulation.js';
|
|
24
|
+
import { tools as emulationTools, deviceTools } from './tools/emulation.js';
|
|
25
|
+
import { tools as iosValidationTools } from './tools/ios-validation.js';
|
|
26
|
+
import { tools as webkitCompatTools } from './tools/webkit-compat.js';
|
|
25
27
|
const allTools = [
|
|
26
28
|
...consoleTools,
|
|
27
29
|
...networkTools,
|
|
@@ -36,6 +38,9 @@ const allTools = [
|
|
|
36
38
|
...storageTools,
|
|
37
39
|
...inputTools,
|
|
38
40
|
...emulationTools,
|
|
41
|
+
...deviceTools,
|
|
42
|
+
...iosValidationTools,
|
|
43
|
+
...webkitCompatTools,
|
|
39
44
|
];
|
|
40
45
|
export function createSafariMcpServer(options = {}) {
|
|
41
46
|
const { slim = false } = options;
|
package/build/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAClE,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAGrC,8CAA8C;AAC9C,OAAO,EAAC,KAAK,IAAI,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAC,KAAK,IAAI,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAC,KAAK,IAAI,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAC,KAAK,IAAI,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAC,KAAK,IAAI,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAC,KAAK,IAAI,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAC,KAAK,IAAI,gBAAgB,EAAC,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAC,KAAK,IAAI,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAC,KAAK,IAAI,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAC,KAAK,IAAI,WAAW,EAAC,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAC,KAAK,IAAI,YAAY,EAAC,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAC,KAAK,IAAI,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAC,KAAK,IAAI,cAAc,EAAC,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulation.d.ts","sourceRoot":"","sources":["../../../src/tools/emulation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAStB,eAAO,MAAM,KAAK,+CA2LjB,CAAC"}
|
|
1
|
+
{"version":3,"file":"emulation.d.ts","sourceRoot":"","sources":["../../../src/tools/emulation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAStB,eAAO,MAAM,KAAK,+CA2LjB,CAAC;AAiFF,eAAO,MAAM,WAAW,+CAoMvB,CAAC"}
|
|
@@ -193,4 +193,243 @@ export const tools = [
|
|
|
193
193
|
},
|
|
194
194
|
}),
|
|
195
195
|
];
|
|
196
|
+
const SAFARI_VERSION = '605.1.15';
|
|
197
|
+
const WEBKIT_VERSION = '605.1.15';
|
|
198
|
+
const OS_VERSION_IOS = '18_0';
|
|
199
|
+
const OS_VERSION_IPAD = '18_0';
|
|
200
|
+
const DEVICE_PRESETS = {
|
|
201
|
+
'iPhone SE': {
|
|
202
|
+
width: 375,
|
|
203
|
+
height: 667,
|
|
204
|
+
devicePixelRatio: 2,
|
|
205
|
+
userAgent: `Mozilla/5.0 (iPhone; CPU iPhone OS ${OS_VERSION_IOS} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
206
|
+
mobile: true,
|
|
207
|
+
},
|
|
208
|
+
'iPhone 14': {
|
|
209
|
+
width: 390,
|
|
210
|
+
height: 844,
|
|
211
|
+
devicePixelRatio: 3,
|
|
212
|
+
userAgent: `Mozilla/5.0 (iPhone; CPU iPhone OS ${OS_VERSION_IOS} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
213
|
+
mobile: true,
|
|
214
|
+
},
|
|
215
|
+
'iPhone 15 Pro': {
|
|
216
|
+
width: 393,
|
|
217
|
+
height: 852,
|
|
218
|
+
devicePixelRatio: 3,
|
|
219
|
+
userAgent: `Mozilla/5.0 (iPhone; CPU iPhone OS ${OS_VERSION_IOS} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
220
|
+
mobile: true,
|
|
221
|
+
},
|
|
222
|
+
'iPhone 16 Pro Max': {
|
|
223
|
+
width: 440,
|
|
224
|
+
height: 956,
|
|
225
|
+
devicePixelRatio: 3,
|
|
226
|
+
userAgent: `Mozilla/5.0 (iPhone; CPU iPhone OS ${OS_VERSION_IOS} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
227
|
+
mobile: true,
|
|
228
|
+
},
|
|
229
|
+
'iPad Mini': {
|
|
230
|
+
width: 744,
|
|
231
|
+
height: 1133,
|
|
232
|
+
devicePixelRatio: 2,
|
|
233
|
+
userAgent: `Mozilla/5.0 (iPad; CPU OS ${OS_VERSION_IPAD} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
234
|
+
mobile: true,
|
|
235
|
+
},
|
|
236
|
+
'iPad Air': {
|
|
237
|
+
width: 820,
|
|
238
|
+
height: 1180,
|
|
239
|
+
devicePixelRatio: 2,
|
|
240
|
+
userAgent: `Mozilla/5.0 (iPad; CPU OS ${OS_VERSION_IPAD} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
241
|
+
mobile: true,
|
|
242
|
+
},
|
|
243
|
+
'iPad Pro 11': {
|
|
244
|
+
width: 834,
|
|
245
|
+
height: 1194,
|
|
246
|
+
devicePixelRatio: 2,
|
|
247
|
+
userAgent: `Mozilla/5.0 (iPad; CPU OS ${OS_VERSION_IPAD} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
248
|
+
mobile: true,
|
|
249
|
+
},
|
|
250
|
+
'iPad Pro 13': {
|
|
251
|
+
width: 1024,
|
|
252
|
+
height: 1366,
|
|
253
|
+
devicePixelRatio: 2,
|
|
254
|
+
userAgent: `Mozilla/5.0 (iPad; CPU OS ${OS_VERSION_IPAD} like Mac OS X) AppleWebKit/${WEBKIT_VERSION} (KHTML, like Gecko) Version/18.0 Mobile/${SAFARI_VERSION} Safari/${SAFARI_VERSION}`,
|
|
255
|
+
mobile: true,
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
const PRESET_NAMES = Object.keys(DEVICE_PRESETS);
|
|
259
|
+
export const deviceTools = [
|
|
260
|
+
defineTool({
|
|
261
|
+
name: 'set_device_emulation',
|
|
262
|
+
description: 'Emulate an Apple device by resizing the viewport and overriding ' +
|
|
263
|
+
'device pixel ratio and touch support at the JS level. The user agent ' +
|
|
264
|
+
'is overridden via navigator.userAgent (JS-level only — HTTP request ' +
|
|
265
|
+
'headers are not affected). Choose a preset ' +
|
|
266
|
+
`(${PRESET_NAMES.join(', ')}) or provide custom values. ` +
|
|
267
|
+
'Use reset_device_emulation to restore defaults.',
|
|
268
|
+
slimDescription: 'Emulate iPhone/iPad viewport and UA.',
|
|
269
|
+
schema: {
|
|
270
|
+
device: z
|
|
271
|
+
.enum(PRESET_NAMES)
|
|
272
|
+
.optional()
|
|
273
|
+
.describe('Apple device preset name. Overrides width/height/dpr/userAgent if provided.'),
|
|
274
|
+
width: z
|
|
275
|
+
.number()
|
|
276
|
+
.min(200)
|
|
277
|
+
.max(3840)
|
|
278
|
+
.optional()
|
|
279
|
+
.describe('Viewport width in CSS pixels.'),
|
|
280
|
+
height: z
|
|
281
|
+
.number()
|
|
282
|
+
.min(200)
|
|
283
|
+
.max(2160)
|
|
284
|
+
.optional()
|
|
285
|
+
.describe('Viewport height in CSS pixels.'),
|
|
286
|
+
devicePixelRatio: z
|
|
287
|
+
.number()
|
|
288
|
+
.min(1)
|
|
289
|
+
.max(4)
|
|
290
|
+
.optional()
|
|
291
|
+
.describe('Device pixel ratio (e.g. 2 for Retina).'),
|
|
292
|
+
userAgent: z
|
|
293
|
+
.string()
|
|
294
|
+
.optional()
|
|
295
|
+
.describe('Custom user agent string (JS-level override only; HTTP headers unchanged).'),
|
|
296
|
+
},
|
|
297
|
+
handler: async (params, driver) => {
|
|
298
|
+
const preset = params.device ? DEVICE_PRESETS[params.device] : undefined;
|
|
299
|
+
const width = params.width ?? preset?.width;
|
|
300
|
+
const height = params.height ?? preset?.height;
|
|
301
|
+
const dpr = params.devicePixelRatio ?? preset?.devicePixelRatio;
|
|
302
|
+
const ua = params.userAgent ?? preset?.userAgent;
|
|
303
|
+
const mobile = preset?.mobile ?? false;
|
|
304
|
+
if (!width || !height) {
|
|
305
|
+
return {
|
|
306
|
+
content: [
|
|
307
|
+
{
|
|
308
|
+
type: 'text',
|
|
309
|
+
text: 'Provide a device preset or both width and height.',
|
|
310
|
+
},
|
|
311
|
+
],
|
|
312
|
+
isError: true,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// Save original window size before resizing
|
|
316
|
+
const originalSize = await driver.runScript(`({w: window.outerWidth, h: window.outerHeight})`);
|
|
317
|
+
// Resize the browser window
|
|
318
|
+
await driver.resizePage(width, height);
|
|
319
|
+
// Inject JS overrides for DPR, UA, and touch
|
|
320
|
+
const overrides = [];
|
|
321
|
+
if (dpr)
|
|
322
|
+
overrides.push(`dpr: ${dpr}`);
|
|
323
|
+
if (ua)
|
|
324
|
+
overrides.push(`ua: ${JSON.stringify(ua)}`);
|
|
325
|
+
overrides.push(`mobile: ${mobile}`);
|
|
326
|
+
overrides.push(`origW: ${originalSize.w}`);
|
|
327
|
+
overrides.push(`origH: ${originalSize.h}`);
|
|
328
|
+
await driver.runScript(`((opts) => {
|
|
329
|
+
// Save originals for reset (only on first call)
|
|
330
|
+
if (!window.__safariMcpDeviceOriginals) {
|
|
331
|
+
window.__safariMcpDeviceOriginals = {
|
|
332
|
+
windowWidth: opts.origW,
|
|
333
|
+
windowHeight: opts.origH,
|
|
334
|
+
hadOntouchstart: 'ontouchstart' in window,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (opts.dpr) {
|
|
339
|
+
Object.defineProperty(window, 'devicePixelRatio', {
|
|
340
|
+
get: () => opts.dpr, configurable: true
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (opts.ua) {
|
|
345
|
+
Object.defineProperty(navigator, 'userAgent', {
|
|
346
|
+
get: () => opts.ua, configurable: true
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (opts.mobile) {
|
|
351
|
+
Object.defineProperty(navigator, 'maxTouchPoints', {
|
|
352
|
+
get: () => 5, configurable: true
|
|
353
|
+
});
|
|
354
|
+
if (!window.__safariMcpDeviceOriginals.hadOntouchstart) {
|
|
355
|
+
window.ontouchstart = null;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
})({${overrides.join(', ')}})`);
|
|
359
|
+
const label = params.device ?? `${width}×${height}`;
|
|
360
|
+
const details = [
|
|
361
|
+
`viewport: ${width}×${height}`,
|
|
362
|
+
dpr ? `dpr: ${dpr}` : null,
|
|
363
|
+
ua ? 'user agent: overridden (JS-level)' : null,
|
|
364
|
+
mobile ? 'touch: enabled' : null,
|
|
365
|
+
]
|
|
366
|
+
.filter(Boolean)
|
|
367
|
+
.join(', ');
|
|
368
|
+
return {
|
|
369
|
+
content: [
|
|
370
|
+
{
|
|
371
|
+
type: 'text',
|
|
372
|
+
text: `Device emulation set to ${label} (${details}).`,
|
|
373
|
+
},
|
|
374
|
+
],
|
|
375
|
+
};
|
|
376
|
+
},
|
|
377
|
+
}),
|
|
378
|
+
defineTool({
|
|
379
|
+
name: 'reset_device_emulation',
|
|
380
|
+
description: 'Remove all device emulation overrides and restore the original ' +
|
|
381
|
+
'viewport size, JS-level user agent, device pixel ratio, and touch settings.',
|
|
382
|
+
slimDescription: 'Reset device emulation.',
|
|
383
|
+
schema: {},
|
|
384
|
+
handler: async (_params, driver) => {
|
|
385
|
+
const result = await driver.runScript(`(() => {
|
|
386
|
+
const orig = window.__safariMcpDeviceOriginals;
|
|
387
|
+
if (!orig) return { restored: false, windowWidth: 0, windowHeight: 0 };
|
|
388
|
+
|
|
389
|
+
// Delete own property overrides to expose prototype originals
|
|
390
|
+
const dprDesc = Object.getOwnPropertyDescriptor(window, 'devicePixelRatio');
|
|
391
|
+
if (dprDesc && dprDesc.configurable) delete window.devicePixelRatio;
|
|
392
|
+
|
|
393
|
+
const uaDesc = Object.getOwnPropertyDescriptor(navigator, 'userAgent');
|
|
394
|
+
if (uaDesc && uaDesc.configurable) delete navigator.userAgent;
|
|
395
|
+
|
|
396
|
+
const touchDesc = Object.getOwnPropertyDescriptor(navigator, 'maxTouchPoints');
|
|
397
|
+
if (touchDesc && touchDesc.configurable) delete navigator.maxTouchPoints;
|
|
398
|
+
|
|
399
|
+
// Only remove ontouchstart if we added it
|
|
400
|
+
if (!orig.hadOntouchstart && 'ontouchstart' in window) {
|
|
401
|
+
delete window.ontouchstart;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const ww = orig.windowWidth;
|
|
405
|
+
const wh = orig.windowHeight;
|
|
406
|
+
delete window.__safariMcpDeviceOriginals;
|
|
407
|
+
|
|
408
|
+
return { restored: true, windowWidth: ww, windowHeight: wh };
|
|
409
|
+
})()`);
|
|
410
|
+
if (!result.restored) {
|
|
411
|
+
return {
|
|
412
|
+
content: [
|
|
413
|
+
{
|
|
414
|
+
type: 'text',
|
|
415
|
+
text: 'No device emulation was active.',
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
// Restore original window size
|
|
421
|
+
if (result.windowWidth && result.windowHeight) {
|
|
422
|
+
await driver.resizePage(result.windowWidth, result.windowHeight);
|
|
423
|
+
}
|
|
424
|
+
return {
|
|
425
|
+
content: [
|
|
426
|
+
{
|
|
427
|
+
type: 'text',
|
|
428
|
+
text: 'Device emulation reset. Viewport, DPR, UA, and touch settings restored.',
|
|
429
|
+
},
|
|
430
|
+
],
|
|
431
|
+
};
|
|
432
|
+
},
|
|
433
|
+
}),
|
|
434
|
+
];
|
|
196
435
|
//# sourceMappingURL=emulation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulation.js","sourceRoot":"","sources":["../../../src/tools/emulation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,UAAU,EAAC,MAAM,YAAY,CAAC;AAEtC,MAAM,iBAAiB,GAAG,CAAC;KACxB,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;KAChC,QAAQ,CACP,iHAAiH,CAClH,CAAC;AAEJ,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,UAAU,CAAC;QACT,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,sEAAsE;YACtE,6DAA6D;YAC7D,gEAAgE;YAChE,kEAAkE;YAClE,qBAAqB;QACvB,eAAe,EAAE,0BAA0B;QAC3C,MAAM,EAAE;YACN,WAAW,EAAE,iBAAiB;SAC/B;QACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,EAAC,WAAW,EAAC,GAAG,MAAM,CAAC;YAE7B,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;gBAC5B,MAAM,MAAM,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA6BlB,CAAC,CAAC;gBAEP,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,yDAAyD;yBAChE;qBACF;iBACF,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAmFjB,WAAW,IAAI,CAAC,CAAC;YAEvB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,wBAAwB,WAAW,4EAA4E,WAAW,QAAQ;qBACzI;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,UAAU,CAAC;QACT,IAAI,EAAE,kBAAkB;QACxB,WAAW,EACT,qEAAqE;YACrE,6DAA6D;QAC/D,eAAe,EAAE,sCAAsC;QACvD,MAAM,EAAE,EAAE;QACV,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;YACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAGlC;;;;;;;WAOE,CAAC,CAAC;YAEP,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc;gBAClC,CAAC,CAAC,wBAAwB;gBAC1B,CAAC,CAAC,mBAAmB,CAAC;YACxB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,yBAAyB,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE;qBACxD;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;CACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"emulation.js","sourceRoot":"","sources":["../../../src/tools/emulation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iOS Safari validation tools.
|
|
3
|
+
*
|
|
4
|
+
* Inspect viewport meta tags, safe-area insets, and PWA readiness —
|
|
5
|
+
* the three things every iOS Safari developer has to fight with.
|
|
6
|
+
*/
|
|
7
|
+
export declare const tools: import("./types.js").ToolDef<import("zod").ZodRawShape>[];
|
|
8
|
+
//# sourceMappingURL=ios-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios-validation.d.ts","sourceRoot":"","sources":["../../../src/tools/ios-validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyEH,eAAO,MAAM,KAAK,2DA6QjB,CAAC"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iOS Safari validation tools.
|
|
3
|
+
*
|
|
4
|
+
* Inspect viewport meta tags, safe-area insets, and PWA readiness —
|
|
5
|
+
* the three things every iOS Safari developer has to fight with.
|
|
6
|
+
*/
|
|
7
|
+
import { defineTool } from './types.js';
|
|
8
|
+
function analyzeViewport(attrs) {
|
|
9
|
+
const issues = [];
|
|
10
|
+
if (Object.keys(attrs).length === 0) {
|
|
11
|
+
return [
|
|
12
|
+
{
|
|
13
|
+
severity: 'error',
|
|
14
|
+
message: 'No viewport meta tag found. iOS Safari will render at 980px width and scale down.',
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
if (!attrs.width) {
|
|
19
|
+
issues.push({
|
|
20
|
+
severity: 'error',
|
|
21
|
+
message: 'Missing "width=device-width". Without this, Safari uses a default 980px layout width.',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else if (attrs.width !== 'device-width') {
|
|
25
|
+
issues.push({
|
|
26
|
+
severity: 'warning',
|
|
27
|
+
message: `width="${attrs.width}" — consider using "device-width" for responsive layouts.`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (!attrs['initial-scale']) {
|
|
31
|
+
issues.push({
|
|
32
|
+
severity: 'warning',
|
|
33
|
+
message: 'Missing "initial-scale=1". Some iOS Safari versions may not zoom correctly without it.',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (attrs['user-scalable'] === 'no' || attrs['maximum-scale'] === '1') {
|
|
37
|
+
issues.push({
|
|
38
|
+
severity: 'error',
|
|
39
|
+
message: 'Zoom is disabled (user-scalable=no or maximum-scale=1). This is an accessibility violation (WCAG 1.4.4) and Safari 10+ ignores it anyway.',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (attrs['viewport-fit'] !== 'cover') {
|
|
43
|
+
issues.push({
|
|
44
|
+
severity: 'warning',
|
|
45
|
+
message: 'Missing "viewport-fit=cover". Required for safe-area-inset-* CSS env() values to work on notched devices (iPhone X+).',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (attrs['minimum-scale'] && parseFloat(attrs['minimum-scale']) < 1) {
|
|
49
|
+
issues.push({
|
|
50
|
+
severity: 'info',
|
|
51
|
+
message: `minimum-scale=${attrs['minimum-scale']}. Values below 1 allow zoom-out on iOS, which can cause layout issues.`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return issues;
|
|
55
|
+
}
|
|
56
|
+
// ---- Tools ----
|
|
57
|
+
export const tools = [
|
|
58
|
+
defineTool({
|
|
59
|
+
name: 'inspect_viewport_meta',
|
|
60
|
+
description: 'Parse the viewport meta tag and validate it against iOS Safari ' +
|
|
61
|
+
'best practices. Reports issues like missing width=device-width, ' +
|
|
62
|
+
'disabled zoom (accessibility violation), missing viewport-fit=cover ' +
|
|
63
|
+
'for safe areas, and other common misconfiguration.',
|
|
64
|
+
slimDescription: 'Validate iOS viewport meta tag.',
|
|
65
|
+
schema: {},
|
|
66
|
+
handler: async (_params, driver) => {
|
|
67
|
+
const result = await driver.runScript(`(() => {
|
|
68
|
+
const meta = document.querySelector('meta[name="viewport"]');
|
|
69
|
+
if (!meta) return { content: null, attrs: {} };
|
|
70
|
+
const content = meta.getAttribute('content') || '';
|
|
71
|
+
const attrs = {};
|
|
72
|
+
for (const part of content.split(',')) {
|
|
73
|
+
const [key, val] = part.split('=').map(s => s.trim());
|
|
74
|
+
if (key) attrs[key] = val || '';
|
|
75
|
+
}
|
|
76
|
+
return { content, attrs };
|
|
77
|
+
})()`);
|
|
78
|
+
const issues = analyzeViewport(result.attrs);
|
|
79
|
+
const lines = [];
|
|
80
|
+
if (result.content) {
|
|
81
|
+
lines.push(`Viewport meta: ${result.content}`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
lines.push('⚠ No <meta name="viewport"> tag found.');
|
|
85
|
+
}
|
|
86
|
+
lines.push('');
|
|
87
|
+
if (issues.length === 0) {
|
|
88
|
+
lines.push('✅ No issues found. Viewport is correctly configured for iOS Safari.');
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const errors = issues.filter(i => i.severity === 'error');
|
|
92
|
+
const warnings = issues.filter(i => i.severity === 'warning');
|
|
93
|
+
const infos = issues.filter(i => i.severity === 'info');
|
|
94
|
+
if (errors.length > 0) {
|
|
95
|
+
lines.push('Errors:');
|
|
96
|
+
for (const i of errors)
|
|
97
|
+
lines.push(` ❌ ${i.message}`);
|
|
98
|
+
}
|
|
99
|
+
if (warnings.length > 0) {
|
|
100
|
+
lines.push('Warnings:');
|
|
101
|
+
for (const i of warnings)
|
|
102
|
+
lines.push(` ⚠ ${i.message}`);
|
|
103
|
+
}
|
|
104
|
+
if (infos.length > 0) {
|
|
105
|
+
lines.push('Info:');
|
|
106
|
+
for (const i of infos)
|
|
107
|
+
lines.push(` ℹ ${i.message}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
}),
|
|
115
|
+
defineTool({
|
|
116
|
+
name: 'get_safe_area_insets',
|
|
117
|
+
description: 'Read the current CSS safe-area-inset values (top, right, bottom, left) ' +
|
|
118
|
+
'as seen by the page. These are non-zero on notched iPhones when ' +
|
|
119
|
+
'viewport-fit=cover is set. Also checks whether the page uses ' +
|
|
120
|
+
'env(safe-area-inset-*) in its stylesheets.',
|
|
121
|
+
slimDescription: 'Get iOS safe area inset values.',
|
|
122
|
+
schema: {},
|
|
123
|
+
handler: async (_params, driver) => {
|
|
124
|
+
const result = await driver.runScript(`(() => {
|
|
125
|
+
// Read computed env() values via a probe element
|
|
126
|
+
const probe = document.createElement('div');
|
|
127
|
+
probe.style.cssText =
|
|
128
|
+
'position:fixed;top:env(safe-area-inset-top,0px);' +
|
|
129
|
+
'right:env(safe-area-inset-right,0px);' +
|
|
130
|
+
'bottom:env(safe-area-inset-bottom,0px);' +
|
|
131
|
+
'left:env(safe-area-inset-left,0px);' +
|
|
132
|
+
'pointer-events:none;visibility:hidden;';
|
|
133
|
+
document.body.appendChild(probe);
|
|
134
|
+
const cs = getComputedStyle(probe);
|
|
135
|
+
const insets = {
|
|
136
|
+
top: cs.top, right: cs.right,
|
|
137
|
+
bottom: cs.bottom, left: cs.left,
|
|
138
|
+
};
|
|
139
|
+
probe.remove();
|
|
140
|
+
|
|
141
|
+
// Check viewport-fit=cover
|
|
142
|
+
const meta = document.querySelector('meta[name="viewport"]');
|
|
143
|
+
const viewportFitCover = meta
|
|
144
|
+
? (meta.getAttribute('content') || '').includes('viewport-fit=cover')
|
|
145
|
+
: false;
|
|
146
|
+
|
|
147
|
+
// Scan stylesheets for env(safe-area-inset usage
|
|
148
|
+
let usedInCSS = false;
|
|
149
|
+
try {
|
|
150
|
+
for (const sheet of document.styleSheets) {
|
|
151
|
+
try {
|
|
152
|
+
const text = [...sheet.cssRules].map(r => r.cssText).join(' ');
|
|
153
|
+
if (text.includes('safe-area-inset')) { usedInCSS = true; break; }
|
|
154
|
+
} catch {}
|
|
155
|
+
}
|
|
156
|
+
} catch {}
|
|
157
|
+
|
|
158
|
+
return { insets, viewportFitCover, usedInCSS };
|
|
159
|
+
})()`);
|
|
160
|
+
const lines = ['Safe area insets:'];
|
|
161
|
+
lines.push(` top: ${result.insets.top}`);
|
|
162
|
+
lines.push(` right: ${result.insets.right}`);
|
|
163
|
+
lines.push(` bottom: ${result.insets.bottom}`);
|
|
164
|
+
lines.push(` left: ${result.insets.left}`);
|
|
165
|
+
lines.push('');
|
|
166
|
+
if (!result.viewportFitCover) {
|
|
167
|
+
lines.push('⚠ viewport-fit=cover is NOT set. Safe area insets will always be 0 ' +
|
|
168
|
+
'even on notched devices. Add viewport-fit=cover to your viewport meta tag.');
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
lines.push('✅ viewport-fit=cover is set.');
|
|
172
|
+
}
|
|
173
|
+
lines.push(result.usedInCSS
|
|
174
|
+
? '✅ env(safe-area-inset-*) found in stylesheets.'
|
|
175
|
+
: '⚠ env(safe-area-inset-*) not found in any stylesheet. Content may be obscured by the notch/home indicator.');
|
|
176
|
+
return {
|
|
177
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
178
|
+
};
|
|
179
|
+
},
|
|
180
|
+
}),
|
|
181
|
+
defineTool({
|
|
182
|
+
name: 'check_ios_web_app_readiness',
|
|
183
|
+
description: 'Audit the page for iOS Safari "Add to Home Screen" / PWA readiness. ' +
|
|
184
|
+
'Checks apple-touch-icon, apple-mobile-web-app-capable, status bar style, ' +
|
|
185
|
+
'theme-color, manifest link, and splash screen configuration.',
|
|
186
|
+
slimDescription: 'Audit iOS PWA/home screen readiness.',
|
|
187
|
+
schema: {},
|
|
188
|
+
handler: async (_params, driver) => {
|
|
189
|
+
const result = await driver.runScript(`(() => {
|
|
190
|
+
const getMeta = (name) => {
|
|
191
|
+
const el = document.querySelector('meta[name="' + name + '"]');
|
|
192
|
+
return el ? el.getAttribute('content') : null;
|
|
193
|
+
};
|
|
194
|
+
const getLink = (rel) => {
|
|
195
|
+
const el = document.querySelector('link[rel="' + rel + '"]');
|
|
196
|
+
return el ? el.getAttribute('href') : null;
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const touchIcons = [...document.querySelectorAll('link[rel="apple-touch-icon"]')].map(el => ({
|
|
200
|
+
sizes: el.getAttribute('sizes') || 'unspecified',
|
|
201
|
+
href: el.getAttribute('href') || '',
|
|
202
|
+
}));
|
|
203
|
+
|
|
204
|
+
const splashScreens = document.querySelectorAll('link[rel="apple-touch-startup-image"]').length;
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
capable: getMeta('apple-mobile-web-app-capable'),
|
|
208
|
+
statusBarStyle: getMeta('apple-mobile-web-app-status-bar-style'),
|
|
209
|
+
themeColor: getMeta('theme-color'),
|
|
210
|
+
manifestHref: getLink('manifest'),
|
|
211
|
+
touchIcons,
|
|
212
|
+
title: document.title,
|
|
213
|
+
appleSplashScreens: splashScreens,
|
|
214
|
+
};
|
|
215
|
+
})()`);
|
|
216
|
+
const checks = [];
|
|
217
|
+
// apple-mobile-web-app-capable
|
|
218
|
+
checks.push({
|
|
219
|
+
pass: result.capable === 'yes',
|
|
220
|
+
label: 'apple-mobile-web-app-capable',
|
|
221
|
+
detail: result.capable === 'yes'
|
|
222
|
+
? 'Set to "yes" — app will run in standalone mode.'
|
|
223
|
+
: 'Not set or not "yes". The app will open in Safari, not standalone.',
|
|
224
|
+
});
|
|
225
|
+
// apple-touch-icon
|
|
226
|
+
const has180 = result.touchIcons.some(i => i.sizes === '180x180');
|
|
227
|
+
checks.push({
|
|
228
|
+
pass: result.touchIcons.length > 0,
|
|
229
|
+
label: 'apple-touch-icon',
|
|
230
|
+
detail: result.touchIcons.length > 0
|
|
231
|
+
? `${result.touchIcons.length} icon(s): ${result.touchIcons.map(i => i.sizes).join(', ')}` +
|
|
232
|
+
(has180 ? '' : '. ⚠ Missing 180x180 (recommended for iPhone).')
|
|
233
|
+
: 'No apple-touch-icon found. iOS will use a screenshot as the icon.',
|
|
234
|
+
});
|
|
235
|
+
// theme-color
|
|
236
|
+
checks.push({
|
|
237
|
+
pass: result.themeColor !== null,
|
|
238
|
+
label: 'theme-color',
|
|
239
|
+
detail: result.themeColor !== null
|
|
240
|
+
? `Set to "${result.themeColor}".`
|
|
241
|
+
: 'Not set. Safari 15+ uses theme-color for the tab bar tint.',
|
|
242
|
+
});
|
|
243
|
+
// status bar style
|
|
244
|
+
checks.push({
|
|
245
|
+
pass: result.statusBarStyle !== null,
|
|
246
|
+
label: 'apple-mobile-web-app-status-bar-style',
|
|
247
|
+
detail: result.statusBarStyle !== null
|
|
248
|
+
? `Set to "${result.statusBarStyle}".`
|
|
249
|
+
: 'Not set. Defaults to "default" (black text on white). Consider "black-translucent" for full-screen feel.',
|
|
250
|
+
});
|
|
251
|
+
// manifest
|
|
252
|
+
checks.push({
|
|
253
|
+
pass: result.manifestHref !== null,
|
|
254
|
+
label: 'Web App Manifest',
|
|
255
|
+
detail: result.manifestHref !== null
|
|
256
|
+
? `Found: ${result.manifestHref}`
|
|
257
|
+
: 'No <link rel="manifest"> found. Required for PWA install prompts.',
|
|
258
|
+
});
|
|
259
|
+
// splash screens
|
|
260
|
+
checks.push({
|
|
261
|
+
pass: result.appleSplashScreens > 0,
|
|
262
|
+
label: 'apple-touch-startup-image',
|
|
263
|
+
detail: result.appleSplashScreens > 0
|
|
264
|
+
? `${result.appleSplashScreens} splash screen(s) defined.`
|
|
265
|
+
: 'No splash screens. Users will see a white screen while the app loads.',
|
|
266
|
+
});
|
|
267
|
+
const passed = checks.filter(c => c.pass).length;
|
|
268
|
+
const lines = [
|
|
269
|
+
`iOS Web App Readiness: ${passed}/${checks.length} checks passed`,
|
|
270
|
+
'',
|
|
271
|
+
];
|
|
272
|
+
for (const c of checks) {
|
|
273
|
+
lines.push(`${c.pass ? '✅' : '❌'} ${c.label}`);
|
|
274
|
+
lines.push(` ${c.detail}`);
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
278
|
+
};
|
|
279
|
+
},
|
|
280
|
+
}),
|
|
281
|
+
];
|
|
282
|
+
//# sourceMappingURL=ios-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ios-validation.js","sourceRoot":"","sources":["../../../src/tools/ios-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebKit CSS compatibility checker.
|
|
3
|
+
*
|
|
4
|
+
* Scans stylesheets for known WebKit/Safari CSS issues:
|
|
5
|
+
* - Properties that need -webkit- prefix in Safari
|
|
6
|
+
* - Known WebKit rendering bugs with workarounds
|
|
7
|
+
* - Deprecated -webkit- properties that should be removed
|
|
8
|
+
* - Properties with different behavior in WebKit vs other engines
|
|
9
|
+
*/
|
|
10
|
+
export declare const tools: import("./types.js").ToolDef<import("zod").ZodRawShape>[];
|
|
11
|
+
//# sourceMappingURL=webkit-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webkit-compat.d.ts","sourceRoot":"","sources":["../../../src/tools/webkit-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiIH,eAAO,MAAM,KAAK,2DAyHjB,CAAC"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebKit CSS compatibility checker.
|
|
3
|
+
*
|
|
4
|
+
* Scans stylesheets for known WebKit/Safari CSS issues:
|
|
5
|
+
* - Properties that need -webkit- prefix in Safari
|
|
6
|
+
* - Known WebKit rendering bugs with workarounds
|
|
7
|
+
* - Deprecated -webkit- properties that should be removed
|
|
8
|
+
* - Properties with different behavior in WebKit vs other engines
|
|
9
|
+
*/
|
|
10
|
+
import { defineTool } from './types.js';
|
|
11
|
+
// Properties that still need -webkit- prefix in current Safari
|
|
12
|
+
const NEEDS_PREFIX = {
|
|
13
|
+
'backdrop-filter': 'Safari requires -webkit-backdrop-filter. Unprefixed is supported only in Safari 18+.',
|
|
14
|
+
'text-decoration-skip-ink': 'Safari <18 needs -webkit-text-decoration-skip-ink.',
|
|
15
|
+
'line-clamp': 'Use -webkit-line-clamp with display: -webkit-box and -webkit-box-orient: vertical.',
|
|
16
|
+
'initial-letter': 'Safari requires -webkit-initial-letter.',
|
|
17
|
+
'text-stroke': 'Non-standard. Use -webkit-text-stroke (Safari-only feature).',
|
|
18
|
+
'background-clip: text': 'Safari requires -webkit-background-clip: text for text clipping.',
|
|
19
|
+
'touch-callout': 'iOS-only. Use -webkit-touch-callout: none to disable long-press popups.',
|
|
20
|
+
'overflow-scrolling': 'Use -webkit-overflow-scrolling: touch for momentum scrolling on iOS <15.',
|
|
21
|
+
};
|
|
22
|
+
// Known WebKit CSS bugs and quirks
|
|
23
|
+
const KNOWN_QUIRKS = [
|
|
24
|
+
{
|
|
25
|
+
pattern: 'gap',
|
|
26
|
+
message: 'Flexbox "gap" is unsupported in Safari <14.1. Use margin-based spacing as fallback.',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
pattern: 'position:\\s*sticky',
|
|
30
|
+
message: 'position:sticky inside overflow:hidden parents is broken in Safari. The sticky element will not stick.',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
pattern: 'aspect-ratio',
|
|
34
|
+
message: 'aspect-ratio is unsupported in Safari <15. Use the padding-bottom hack as fallback.',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pattern: ':has\\(',
|
|
38
|
+
message: ':has() is supported in Safari 15.4+ but has performance edge cases with large DOM trees.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
pattern: 'container-type|@container',
|
|
42
|
+
message: 'Container queries require Safari 16+. No support in older iOS versions still in use.',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
pattern: 'color-mix\\(',
|
|
46
|
+
message: 'color-mix() requires Safari 16.2+.',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
pattern: '@layer',
|
|
50
|
+
message: '@layer (cascade layers) requires Safari 15.4+.',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
pattern: 'subgrid',
|
|
54
|
+
message: 'subgrid requires Safari 16+.',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
pattern: ':focus-visible',
|
|
58
|
+
message: ':focus-visible requires Safari 15.4+. Older versions need :focus fallback.',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
pattern: 'overscroll-behavior',
|
|
62
|
+
message: 'overscroll-behavior requires Safari 16+. No effect on older iOS.',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
pattern: 'dvh|svh|lvh',
|
|
66
|
+
message: 'Dynamic viewport units (dvh/svh/lvh) require Safari 15.4+. Use vh with JS fallback for older iOS.',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
pattern: 'content-visibility',
|
|
70
|
+
message: 'content-visibility requires Safari 18+. Not supported in most iOS versions in the wild.',
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
// Deprecated -webkit- prefixes that can be removed
|
|
74
|
+
const DEPRECATED_PREFIXES = [
|
|
75
|
+
{
|
|
76
|
+
prefix: '-webkit-border-radius',
|
|
77
|
+
standard: 'border-radius',
|
|
78
|
+
message: 'Unprefixed since Safari 5. Remove -webkit- prefix.',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
prefix: '-webkit-box-shadow',
|
|
82
|
+
standard: 'box-shadow',
|
|
83
|
+
message: 'Unprefixed since Safari 5.1. Remove -webkit- prefix.',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
prefix: '-webkit-transform',
|
|
87
|
+
standard: 'transform',
|
|
88
|
+
message: 'Unprefixed since Safari 9. Remove -webkit- prefix.',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
prefix: '-webkit-transition',
|
|
92
|
+
standard: 'transition',
|
|
93
|
+
message: 'Unprefixed since Safari 9. Remove -webkit- prefix.',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
prefix: '-webkit-animation',
|
|
97
|
+
standard: 'animation',
|
|
98
|
+
message: 'Unprefixed since Safari 9. Remove -webkit- prefix.',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
prefix: '-webkit-flex',
|
|
102
|
+
standard: 'flex',
|
|
103
|
+
message: 'Unprefixed since Safari 9. Remove -webkit-flex and -webkit-box-flex.',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
prefix: '-webkit-appearance',
|
|
107
|
+
standard: 'appearance',
|
|
108
|
+
message: 'Unprefixed since Safari 15.4. Keep prefix only if supporting older iOS.',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
prefix: '-webkit-user-select',
|
|
112
|
+
standard: 'user-select',
|
|
113
|
+
message: 'Unprefixed since Safari 16.4. Keep prefix only if supporting older iOS.',
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
export const tools = [
|
|
117
|
+
defineTool({
|
|
118
|
+
name: 'check_webkit_compatibility',
|
|
119
|
+
description: 'Scan all stylesheets on the current page for WebKit/Safari CSS ' +
|
|
120
|
+
'compatibility issues. Reports: properties that need -webkit- prefix, ' +
|
|
121
|
+
'known WebKit rendering bugs, deprecated prefixes to clean up, and ' +
|
|
122
|
+
'modern CSS features with limited Safari support.',
|
|
123
|
+
slimDescription: 'Scan CSS for Safari compatibility issues.',
|
|
124
|
+
schema: {},
|
|
125
|
+
handler: async (_params, driver) => {
|
|
126
|
+
// Collect all CSS text from stylesheets
|
|
127
|
+
const cssText = await driver.runScript(`(() => {
|
|
128
|
+
const texts = [];
|
|
129
|
+
for (const sheet of document.styleSheets) {
|
|
130
|
+
try {
|
|
131
|
+
for (const rule of sheet.cssRules) {
|
|
132
|
+
texts.push(rule.cssText);
|
|
133
|
+
}
|
|
134
|
+
} catch {}
|
|
135
|
+
}
|
|
136
|
+
// Also check inline styles in style attributes
|
|
137
|
+
for (const el of document.querySelectorAll('[style]')) {
|
|
138
|
+
texts.push(el.getAttribute('style') || '');
|
|
139
|
+
}
|
|
140
|
+
return texts.join('\\n');
|
|
141
|
+
})()`);
|
|
142
|
+
if (!cssText || cssText.length === 0) {
|
|
143
|
+
return {
|
|
144
|
+
content: [
|
|
145
|
+
{
|
|
146
|
+
type: 'text',
|
|
147
|
+
text: 'No accessible stylesheets found. Cross-origin stylesheets cannot be inspected.',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
const findings = [];
|
|
153
|
+
// Check for properties needing -webkit- prefix
|
|
154
|
+
for (const [prop, message] of Object.entries(NEEDS_PREFIX)) {
|
|
155
|
+
const propPattern = prop.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
156
|
+
// Match as a CSS declaration (word boundary before, colon or space after)
|
|
157
|
+
// to avoid false positives on custom properties like --backdrop-filter
|
|
158
|
+
const declPattern = `(?<![\\w-])${propPattern}`;
|
|
159
|
+
if (new RegExp(`(?<!-webkit-)${declPattern}`, 'i').test(cssText) &&
|
|
160
|
+
!new RegExp(`-webkit-${propPattern}`, 'i').test(cssText)) {
|
|
161
|
+
findings.push({
|
|
162
|
+
category: 'Missing prefix',
|
|
163
|
+
severity: 'warning',
|
|
164
|
+
message: `${prop}: ${message}`,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Check for known WebKit quirks
|
|
169
|
+
for (const quirk of KNOWN_QUIRKS) {
|
|
170
|
+
if (new RegExp(quirk.pattern, 'i').test(cssText)) {
|
|
171
|
+
findings.push({
|
|
172
|
+
category: 'Compatibility',
|
|
173
|
+
severity: 'info',
|
|
174
|
+
message: quirk.message,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// Check for deprecated -webkit- prefixes
|
|
179
|
+
for (const dep of DEPRECATED_PREFIXES) {
|
|
180
|
+
if (cssText.includes(dep.prefix)) {
|
|
181
|
+
findings.push({
|
|
182
|
+
category: 'Deprecated prefix',
|
|
183
|
+
severity: 'info',
|
|
184
|
+
message: `${dep.prefix} → ${dep.standard}: ${dep.message}`,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Build output
|
|
189
|
+
const lines = [];
|
|
190
|
+
if (findings.length === 0) {
|
|
191
|
+
lines.push('✅ No WebKit CSS compatibility issues found in accessible stylesheets.');
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
const warnings = findings.filter(f => f.severity === 'warning');
|
|
195
|
+
const infos = findings.filter(f => f.severity === 'info');
|
|
196
|
+
lines.push(`Found ${findings.length} issue(s) across accessible stylesheets:`);
|
|
197
|
+
lines.push('');
|
|
198
|
+
if (warnings.length > 0) {
|
|
199
|
+
lines.push(`⚠ Action needed (${warnings.length}):`);
|
|
200
|
+
for (const f of warnings) {
|
|
201
|
+
lines.push(` [${f.category}] ${f.message}`);
|
|
202
|
+
}
|
|
203
|
+
lines.push('');
|
|
204
|
+
}
|
|
205
|
+
if (infos.length > 0) {
|
|
206
|
+
lines.push(`ℹ Informational (${infos.length}):`);
|
|
207
|
+
for (const f of infos) {
|
|
208
|
+
lines.push(` [${f.category}] ${f.message}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
214
|
+
};
|
|
215
|
+
},
|
|
216
|
+
}),
|
|
217
|
+
];
|
|
218
|
+
//# sourceMappingURL=webkit-compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webkit-compat.js","sourceRoot":"","sources":["../../../src/tools/webkit-compat.ts"],"names":[],"mappings":"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"}
|
package/build/src/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
1
|
+
export declare const VERSION = "1.8.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/build/src/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "safari-devtools-mcp",
|
|
3
3
|
"mcpName": "io.github.HayoDev/safari-devtools-mcp",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.8.0",
|
|
5
5
|
"description": "Safari DevTools MCP — real browser debugging with network interception, DOM inspection, cookie/storage management, and CSS analysis for AI agents on macOS",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "build/src/index.js",
|