safari-devtools-mcp 1.8.0 → 1.8.1

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 CHANGED
@@ -293,12 +293,7 @@ The server exposes guided debugging workflows as MCP prompts. Clients that suppo
293
293
  | `inspect_viewport_meta` | Parse the viewport meta tag and validate against iOS best practices (width, zoom, viewport-fit) |
294
294
  | `get_safe_area_insets` | Read CSS safe-area-inset values and check whether the page handles notched devices correctly |
295
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 |
296
+ | `check_webkit_compatibility` | Check page CSS against the live Safari session via CSS.supports() |
302
297
 
303
298
  ## Architecture
304
299
 
@@ -1,11 +1,10 @@
1
1
  /**
2
2
  * WebKit CSS compatibility checker.
3
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
4
+ * Runs inside a live Safari WebDriver session. Extracts CSS from the page
5
+ * using structured DOM APIs (rule.style iteration — no regex, no false
6
+ * positives on custom properties), then runs CSS.supports() in the actual
7
+ * browser to report what is genuinely broken right now.
9
8
  */
10
9
  export declare const tools: import("./types.js").ToolDef<import("zod").ZodRawShape>[];
11
10
  //# sourceMappingURL=webkit-compat.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"webkit-compat.d.ts","sourceRoot":"","sources":["../../../src/tools/webkit-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuBH,eAAO,MAAM,KAAK,2DAkKjB,CAAC"}
@@ -1,217 +1,164 @@
1
1
  /**
2
2
  * WebKit CSS compatibility checker.
3
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
4
+ * Runs inside a live Safari WebDriver session. Extracts CSS from the page
5
+ * using structured DOM APIs (rule.style iteration — no regex, no false
6
+ * positives on custom properties), then runs CSS.supports() in the actual
7
+ * browser to report what is genuinely broken right now.
9
8
  */
10
9
  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
- },
10
+ /**
11
+ * Behavioral quirks that CSS.supports() cannot detect — the property IS
12
+ * "supported", it just renders incorrectly. Keep this list small, precise,
13
+ * and each entry must be a confirmed Safari rendering bug.
14
+ */
15
+ const BEHAVIORAL_QUIRKS = [
110
16
  {
111
- prefix: '-webkit-user-select',
112
- standard: 'user-select',
113
- message: 'Unprefixed since Safari 16.4. Keep prefix only if supporting older iOS.',
17
+ property: 'position',
18
+ matchValue: 'sticky',
19
+ message: 'position:sticky silently fails inside an overflow:hidden or overflow:auto ' +
20
+ 'ancestor in Safari. Use overflow:clip on the ancestor instead.',
114
21
  },
115
22
  ];
116
23
  export const tools = [
117
24
  defineTool({
118
25
  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.',
26
+ description: 'Check CSS on the current page against the live Safari session. ' +
27
+ 'Extracts every CSS property via structured DOM APIs, runs CSS.supports() ' +
28
+ 'in the actual browser, and reports what is broken right now — unsupported ' +
29
+ 'properties, missing -webkit- prefixes, and known Safari rendering quirks.',
30
+ slimDescription: 'Check CSS against live Safari via CSS.supports().',
124
31
  schema: {},
125
32
  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);
33
+ // -----------------------------------------------------------------
34
+ // Step 1: Extract structured CSS from the page + run CSS.supports()
35
+ // in one round-trip. Uses rule.style iteration for canonical property
36
+ // names — custom properties (--*) are excluded automatically.
37
+ // -----------------------------------------------------------------
38
+ const results = await driver.runScript(`(() => {
39
+ // Collect unique property:value pairs from all accessible stylesheets
40
+ const seen = new Map();
41
+
42
+ function collectFromStyle(style) {
43
+ for (const prop of style) {
44
+ if (prop.startsWith('--')) continue;
45
+ if (seen.has(prop)) continue;
46
+ seen.set(prop, style.getPropertyValue(prop).trim());
47
+ }
48
+ }
49
+
50
+ function processRules(rules) {
51
+ for (const rule of rules) {
52
+ // Skip @font-face — its descriptors (src, font-display, unicode-range)
53
+ // are not CSS properties and CSS.supports() always returns false for them
54
+ if (rule.constructor?.name === 'CSSFontFaceRule') continue;
55
+ if (rule.style) collectFromStyle(rule.style);
56
+ if (rule.cssRules) {
57
+ try { processRules(rule.cssRules); } catch {}
133
58
  }
134
- } catch {}
59
+ }
135
60
  }
136
- // Also check inline styles in style attributes
61
+
62
+ for (const sheet of document.styleSheets) {
63
+ try { processRules(sheet.cssRules); } catch {}
64
+ }
65
+
66
+ // Inline styles
137
67
  for (const el of document.querySelectorAll('[style]')) {
138
- texts.push(el.getAttribute('style') || '');
68
+ collectFromStyle(el.style);
139
69
  }
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
- }
70
+
71
+ const totalProperties = seen.size;
72
+ const unsupported = [];
73
+ const needsPrefix = [];
74
+
75
+ for (const [prop, value] of seen) {
76
+ let supported = false;
77
+ try { supported = CSS.supports(prop, value); } catch {}
78
+
79
+ if (!supported) {
80
+ // Try again with a generic value — the extracted value might be
81
+ // a computed/resolved form CSS.supports doesn't accept
82
+ try { supported = CSS.supports(prop, 'initial'); } catch {}
83
+ }
84
+
85
+ if (supported) continue;
86
+
87
+ // Not supported unprefixed check if -webkit- variant works
88
+ const webkitProp = '-webkit-' + prop;
89
+ let webkitSupported = false;
90
+ try { webkitSupported = CSS.supports(webkitProp, value); } catch {}
91
+ if (!webkitSupported) {
92
+ try { webkitSupported = CSS.supports(webkitProp, 'initial'); } catch {}
93
+ }
94
+
95
+ if (webkitSupported) {
96
+ needsPrefix.push({ property: prop, value });
97
+ } else {
98
+ unsupported.push({ property: prop, value });
99
+ }
100
+ }
101
+
102
+ // Collect a subset of computed properties for behavioral quirk checks
103
+ const body = document.body;
104
+ const computedProperties = {};
105
+ if (body) {
106
+ const quirkProps = ${JSON.stringify(BEHAVIORAL_QUIRKS.map(q => q.property))};
107
+ for (const prop of quirkProps) {
108
+ if (seen.has(prop)) {
109
+ computedProperties[prop] = seen.get(prop);
177
110
  }
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
- }
111
+ }
112
+ }
113
+
114
+ return { totalProperties, unsupported, needsPrefix, computedProperties };
115
+ })()`);
116
+ // -----------------------------------------------------------------
117
+ // Step 2: Check behavioral quirks
118
+ // -----------------------------------------------------------------
119
+ const quirks = [];
120
+ for (const quirk of BEHAVIORAL_QUIRKS) {
121
+ const value = results.computedProperties[quirk.property];
122
+ if (value === undefined)
123
+ continue;
124
+ if (quirk.matchValue && !value.includes(quirk.matchValue))
125
+ continue;
126
+ quirks.push(quirk.message);
187
127
  }
188
- // Build output
128
+ // -----------------------------------------------------------------
129
+ // Step 3: Format output
130
+ // -----------------------------------------------------------------
131
+ const total = results.unsupported.length + results.needsPrefix.length + quirks.length;
189
132
  const lines = [];
190
- if (findings.length === 0) {
191
- lines.push('✅ No WebKit CSS compatibility issues found in accessible stylesheets.');
133
+ if (total === 0) {
134
+ lines.push(`✅ No issues found. ${results.totalProperties} CSS properties checked via CSS.supports() in this Safari session.`);
192
135
  }
193
136
  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:`);
137
+ lines.push(`Found ${total} issue(s) — ${results.totalProperties} properties checked via CSS.supports() in this Safari session.`);
197
138
  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}`);
139
+ if (results.unsupported.length > 0) {
140
+ lines.push(`❌ Unsupported in this Safari (${results.unsupported.length}):`);
141
+ for (const { property, value } of results.unsupported) {
142
+ const preview = value.length > 60 ? value.slice(0, 57) + '...' : value;
143
+ lines.push(` ${property}: ${preview}`);
144
+ }
145
+ lines.push('');
146
+ }
147
+ if (results.needsPrefix.length > 0) {
148
+ lines.push(`⚠ Needs -webkit- prefix (${results.needsPrefix.length}):`);
149
+ for (const { property } of results.needsPrefix) {
150
+ lines.push(` ${property} → use -webkit-${property} alongside it`);
202
151
  }
203
152
  lines.push('');
204
153
  }
205
- if (infos.length > 0) {
206
- lines.push(`ℹ Informational (${infos.length}):`);
207
- for (const f of infos) {
208
- lines.push(` [${f.category}] ${f.message}`);
154
+ if (quirks.length > 0) {
155
+ lines.push(`ℹ Known Safari rendering quirks (${quirks.length}):`);
156
+ for (const msg of quirks) {
157
+ lines.push(` ${msg}`);
209
158
  }
210
159
  }
211
160
  }
212
- return {
213
- content: [{ type: 'text', text: lines.join('\n') }],
214
- };
161
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
215
162
  },
216
163
  }),
217
164
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"webkit-compat.js","sourceRoot":"","sources":["../../../src/tools/webkit-compat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webkit-compat.js","sourceRoot":"","sources":["../../../src/tools/webkit-compat.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "1.8.0";
1
+ export declare const VERSION = "1.8.1";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // x-release-please-start-version
2
- export const VERSION = '1.8.0';
2
+ export const VERSION = '1.8.1';
3
3
  // x-release-please-end
4
4
  //# sourceMappingURL=version.js.map
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.8.0",
4
+ "version": "1.8.1",
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",
@@ -7,18 +7,23 @@ or when debugging WebKit-specific behavior.
7
7
 
8
8
  ### CSS issues
9
9
 
10
- Safari lags behind on some CSS features and requires `-webkit-` prefixes
11
- for others. Debug with:
10
+ Start by running `check_webkit_compatibility` it checks every CSS property
11
+ on the page against the live Safari session via `CSS.supports()` and reports
12
+ what is actually broken (unsupported properties, missing `-webkit-` prefixes):
13
+
14
+ ```
15
+ check_webkit_compatibility
16
+ ```
17
+
18
+ For specific elements, inspect computed styles directly:
12
19
 
13
20
  ```
14
21
  get_computed_style uid="<element-uid>" properties=["display", "gap", "aspect-ratio", "container-type", "backdrop-filter"]
15
22
  ```
16
23
 
17
- **Known Safari CSS quirks:**
24
+ **Common Safari CSS gotchas:**
18
25
 
19
- - `gap` in flexbox: Supported since Safari 14.1, but older versions fail silently.
20
- - `aspect-ratio`: Works, but may not apply in some flex/grid contexts.
21
- - `-webkit-backdrop-filter`: Still requires prefix in some versions.
26
+ - `-webkit-backdrop-filter`: Still requires prefix in Safari <18.
22
27
  - `100vh` on iOS Safari includes the address bar — use `100dvh` instead.
23
28
  - `position: sticky` inside `overflow: auto` containers often breaks.
24
29
  - `:has()` selector: Safari was first to ship it, but edge cases may differ.
@@ -115,7 +120,13 @@ see what the a11y tree reports, then `take_screenshot` for visual comparison.
115
120
  evaluate_script function="() => { /* feature detection code */ }"
116
121
  ```
117
122
 
118
- 6. Check CSS rendering:
123
+ 6. Check CSS compatibility across the page:
124
+
125
+ ```
126
+ check_webkit_compatibility
127
+ ```
128
+
129
+ 7. Inspect a specific element's styles:
119
130
  ```
120
131
  get_computed_style uid="<element-uid>"
121
132
  ```