@productivemark/snipcss 1.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/.claude-plugin/marketplace.json +17 -0
- package/.claude-plugin/plugin.json +10 -0
- package/.mcp.json +8 -0
- package/dist/auth/config-manager.d.ts +13 -0
- package/dist/auth/config-manager.d.ts.map +1 -0
- package/dist/auth/config-manager.js +48 -0
- package/dist/auth/config-manager.js.map +1 -0
- package/dist/auth/usage-gate.d.ts +13 -0
- package/dist/auth/usage-gate.d.ts.map +1 -0
- package/dist/auth/usage-gate.js +69 -0
- package/dist/auth/usage-gate.js.map +1 -0
- package/dist/browser/browser-manager.d.ts +15 -0
- package/dist/browser/browser-manager.d.ts.map +1 -0
- package/dist/browser/browser-manager.js +61 -0
- package/dist/browser/browser-manager.js.map +1 -0
- package/dist/browser/viewport-manager.d.ts +8 -0
- package/dist/browser/viewport-manager.d.ts.map +1 -0
- package/dist/browser/viewport-manager.js +50 -0
- package/dist/browser/viewport-manager.js.map +1 -0
- package/dist/extraction/css-variable-resolver.d.ts +27 -0
- package/dist/extraction/css-variable-resolver.d.ts.map +1 -0
- package/dist/extraction/css-variable-resolver.js +105 -0
- package/dist/extraction/css-variable-resolver.js.map +1 -0
- package/dist/extraction/dom-labeler.d.ts +26 -0
- package/dist/extraction/dom-labeler.d.ts.map +1 -0
- package/dist/extraction/dom-labeler.js +124 -0
- package/dist/extraction/dom-labeler.js.map +1 -0
- package/dist/extraction/element-discovery.d.ts +59 -0
- package/dist/extraction/element-discovery.d.ts.map +1 -0
- package/dist/extraction/element-discovery.js +525 -0
- package/dist/extraction/element-discovery.js.map +1 -0
- package/dist/extraction/extraction-pipeline.d.ts +26 -0
- package/dist/extraction/extraction-pipeline.d.ts.map +1 -0
- package/dist/extraction/extraction-pipeline.js +200 -0
- package/dist/extraction/extraction-pipeline.js.map +1 -0
- package/dist/extraction/font-collector.d.ts +26 -0
- package/dist/extraction/font-collector.d.ts.map +1 -0
- package/dist/extraction/font-collector.js +160 -0
- package/dist/extraction/font-collector.js.map +1 -0
- package/dist/extraction/html-cleaner.d.ts +16 -0
- package/dist/extraction/html-cleaner.d.ts.map +1 -0
- package/dist/extraction/html-cleaner.js +149 -0
- package/dist/extraction/html-cleaner.js.map +1 -0
- package/dist/extraction/keyframe-collector.d.ts +16 -0
- package/dist/extraction/keyframe-collector.d.ts.map +1 -0
- package/dist/extraction/keyframe-collector.js +62 -0
- package/dist/extraction/keyframe-collector.js.map +1 -0
- package/dist/extraction/pseudo-state-handler.d.ts +36 -0
- package/dist/extraction/pseudo-state-handler.d.ts.map +1 -0
- package/dist/extraction/pseudo-state-handler.js +210 -0
- package/dist/extraction/pseudo-state-handler.js.map +1 -0
- package/dist/extraction/result-builder.d.ts +25 -0
- package/dist/extraction/result-builder.d.ts.map +1 -0
- package/dist/extraction/result-builder.js +136 -0
- package/dist/extraction/result-builder.js.map +1 -0
- package/dist/extraction/rule-deduplicator.d.ts +39 -0
- package/dist/extraction/rule-deduplicator.d.ts.map +1 -0
- package/dist/extraction/rule-deduplicator.js +107 -0
- package/dist/extraction/rule-deduplicator.js.map +1 -0
- package/dist/extraction/selector-fixer.d.ts +25 -0
- package/dist/extraction/selector-fixer.d.ts.map +1 -0
- package/dist/extraction/selector-fixer.js +111 -0
- package/dist/extraction/selector-fixer.js.map +1 -0
- package/dist/extraction/specificity.d.ts +17 -0
- package/dist/extraction/specificity.d.ts.map +1 -0
- package/dist/extraction/specificity.js +88 -0
- package/dist/extraction/specificity.js.map +1 -0
- package/dist/extraction/style-matcher.d.ts +33 -0
- package/dist/extraction/style-matcher.d.ts.map +1 -0
- package/dist/extraction/style-matcher.js +199 -0
- package/dist/extraction/style-matcher.js.map +1 -0
- package/dist/extraction/stylesheet-collector.d.ts +33 -0
- package/dist/extraction/stylesheet-collector.d.ts.map +1 -0
- package/dist/extraction/stylesheet-collector.js +71 -0
- package/dist/extraction/stylesheet-collector.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +235 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +349 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/tailwind/css-to-tailwind.d.ts +17 -0
- package/dist/tailwind/css-to-tailwind.d.ts.map +1 -0
- package/dist/tailwind/css-to-tailwind.js +1583 -0
- package/dist/tailwind/css-to-tailwind.js.map +1 -0
- package/dist/tailwind/shorthand-expander.d.ts +27 -0
- package/dist/tailwind/shorthand-expander.d.ts.map +1 -0
- package/dist/tailwind/shorthand-expander.js +812 -0
- package/dist/tailwind/shorthand-expander.js.map +1 -0
- package/dist/tailwind/tailwind-converter.d.ts +35 -0
- package/dist/tailwind/tailwind-converter.d.ts.map +1 -0
- package/dist/tailwind/tailwind-converter.js +1223 -0
- package/dist/tailwind/tailwind-converter.js.map +1 -0
- package/dist/tailwind/tailwind-helpers.d.ts +95 -0
- package/dist/tailwind/tailwind-helpers.d.ts.map +1 -0
- package/dist/tailwind/tailwind-helpers.js +593 -0
- package/dist/tailwind/tailwind-helpers.js.map +1 -0
- package/dist/tailwind/tailwind-reducer.d.ts +36 -0
- package/dist/tailwind/tailwind-reducer.d.ts.map +1 -0
- package/dist/tailwind/tailwind-reducer.js +189 -0
- package/dist/tailwind/tailwind-reducer.js.map +1 -0
- package/dist/types/index.d.ts +239 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +94 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/helpers.d.ts +34 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +120 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/parsel.d.ts +41 -0
- package/dist/utils/parsel.d.ts.map +1 -0
- package/dist/utils/parsel.js +314 -0
- package/dist/utils/parsel.js.map +1 -0
- package/package.json +41 -0
- package/skills/workflow/SKILL.md +95 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import yargs from 'yargs';
|
|
3
|
+
import { hideBin } from 'yargs/helpers';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { BrowserManager } from './browser/browser-manager.js';
|
|
7
|
+
import { ExtractionPipeline } from './extraction/extraction-pipeline.js';
|
|
8
|
+
import { setApiKey } from './auth/config-manager.js';
|
|
9
|
+
import { checkAccess, verifyApiKey } from './auth/usage-gate.js';
|
|
10
|
+
function makeFilename(urlStr, selector, variant, timestamp) {
|
|
11
|
+
const domain = new URL(urlStr).hostname.replace(/^www\./, '');
|
|
12
|
+
const sel = selector.replace(/^[.#]/, '').replace(/[^a-zA-Z0-9-]/g, '-');
|
|
13
|
+
const ts = timestamp.replace(/[-:T]/g, '').replace(/\..+/, '');
|
|
14
|
+
return `${domain}_${variant}_${sel}_${ts}.html`;
|
|
15
|
+
}
|
|
16
|
+
function buildTailwindHtmlFile(result, urlStr, selector, timestamp) {
|
|
17
|
+
const domain = new URL(urlStr).hostname.replace(/^www\./, '');
|
|
18
|
+
return `<!DOCTYPE html>
|
|
19
|
+
<html lang="en">
|
|
20
|
+
<head>
|
|
21
|
+
<meta charset="UTF-8">
|
|
22
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
23
|
+
<title>${selector} (tailwind) \u2014 ${domain}</title>
|
|
24
|
+
<script src="https://cdn.tailwindcss.com"><\/script>
|
|
25
|
+
<style>
|
|
26
|
+
/* Extracted CSS: variables, fonts, keyframes, fallback rules for unconverted properties */
|
|
27
|
+
${result.css.split('\n').map((l) => ' ' + l).join('\n')}
|
|
28
|
+
</style>
|
|
29
|
+
</head>
|
|
30
|
+
<body class="${result.tailwindBodyClasses || ''}">
|
|
31
|
+
<!-- Extracted from ${urlStr} | selector: ${selector} | ${timestamp} -->
|
|
32
|
+
${result.tailwindHtml || result.html}
|
|
33
|
+
</body>
|
|
34
|
+
</html>`;
|
|
35
|
+
}
|
|
36
|
+
function buildOriginalHtmlFile(result, urlStr, selector, timestamp) {
|
|
37
|
+
const domain = new URL(urlStr).hostname.replace(/^www\./, '');
|
|
38
|
+
return `<!DOCTYPE html>
|
|
39
|
+
<html lang="en">
|
|
40
|
+
<head>
|
|
41
|
+
<meta charset="UTF-8">
|
|
42
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
43
|
+
<title>${selector} (original CSS) \u2014 ${domain}</title>
|
|
44
|
+
<style>
|
|
45
|
+
${result.css.split('\n').map((l) => ' ' + l).join('\n')}
|
|
46
|
+
</style>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<!-- Extracted from ${urlStr} | selector: ${selector} | ${timestamp} -->
|
|
50
|
+
${result.html}
|
|
51
|
+
</body>
|
|
52
|
+
</html>`;
|
|
53
|
+
}
|
|
54
|
+
async function main() {
|
|
55
|
+
const argv = await yargs(hideBin(process.argv))
|
|
56
|
+
.usage('Usage: $0 --url <url> --selector <selector> [options]')
|
|
57
|
+
.option('url', {
|
|
58
|
+
alias: 'u',
|
|
59
|
+
type: 'string',
|
|
60
|
+
description: 'URL of the page to extract from',
|
|
61
|
+
demandOption: true,
|
|
62
|
+
})
|
|
63
|
+
.option('selector', {
|
|
64
|
+
alias: 's',
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'CSS selector for the target element',
|
|
67
|
+
demandOption: true,
|
|
68
|
+
})
|
|
69
|
+
.option('viewport', {
|
|
70
|
+
alias: 'v',
|
|
71
|
+
type: 'string',
|
|
72
|
+
description: 'Viewport: all, desktop, tablet, mobile, or a width in px',
|
|
73
|
+
default: 'all',
|
|
74
|
+
})
|
|
75
|
+
.option('format', {
|
|
76
|
+
alias: 'f',
|
|
77
|
+
type: 'string',
|
|
78
|
+
choices: ['css', 'tailwind', 'both', 'json', 'html'],
|
|
79
|
+
description: 'Output format (html writes preview files)',
|
|
80
|
+
default: 'both',
|
|
81
|
+
})
|
|
82
|
+
.option('resolve-vars', {
|
|
83
|
+
type: 'boolean',
|
|
84
|
+
description: 'Resolve CSS variables to computed values',
|
|
85
|
+
default: true,
|
|
86
|
+
})
|
|
87
|
+
.option('no-hover', {
|
|
88
|
+
type: 'boolean',
|
|
89
|
+
description: 'Skip hover/active state extraction',
|
|
90
|
+
default: false,
|
|
91
|
+
})
|
|
92
|
+
.option('keep-unused-classes', {
|
|
93
|
+
type: 'boolean',
|
|
94
|
+
description: 'Keep CSS classes not found in extracted rules',
|
|
95
|
+
default: false,
|
|
96
|
+
})
|
|
97
|
+
.option('keep-unused-attrs', {
|
|
98
|
+
type: 'boolean',
|
|
99
|
+
description: 'Keep data-* and other non-essential HTML attributes',
|
|
100
|
+
default: false,
|
|
101
|
+
})
|
|
102
|
+
.option('output', {
|
|
103
|
+
alias: 'o',
|
|
104
|
+
type: 'string',
|
|
105
|
+
description: 'Output file/directory path (default: stdout, or cwd for html format)',
|
|
106
|
+
})
|
|
107
|
+
.option('json', {
|
|
108
|
+
type: 'boolean',
|
|
109
|
+
description: 'Output as structured JSON',
|
|
110
|
+
default: false,
|
|
111
|
+
})
|
|
112
|
+
.option('timeout', {
|
|
113
|
+
type: 'number',
|
|
114
|
+
description: 'Page load timeout in ms',
|
|
115
|
+
default: 30000,
|
|
116
|
+
})
|
|
117
|
+
.option('api-key', {
|
|
118
|
+
type: 'string',
|
|
119
|
+
description: 'Set your SnipCSS Pro API key for unlimited extractions',
|
|
120
|
+
})
|
|
121
|
+
.help()
|
|
122
|
+
.argv;
|
|
123
|
+
// Handle --api-key: save and verify, then exit
|
|
124
|
+
if (argv['api-key']) {
|
|
125
|
+
const key = argv['api-key'];
|
|
126
|
+
console.error('Verifying API key...');
|
|
127
|
+
const result = await verifyApiKey(key);
|
|
128
|
+
if (result.isPro) {
|
|
129
|
+
setApiKey(key);
|
|
130
|
+
console.error(`API key verified and saved. Welcome, ${result.email}! You now have unlimited extractions.`);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
console.error(`API key verification failed: ${result.error || 'Not a Pro account'}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Check usage/Pro access
|
|
138
|
+
const access = await checkAccess();
|
|
139
|
+
if (!access.allowed) {
|
|
140
|
+
console.error(access.message || 'Access denied. Use --api-key to set your SnipCSS Pro API key.');
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
const browserManager = new BrowserManager();
|
|
144
|
+
try {
|
|
145
|
+
await browserManager.launch();
|
|
146
|
+
const pipeline = new ExtractionPipeline(browserManager);
|
|
147
|
+
const options = {
|
|
148
|
+
viewport: argv.viewport,
|
|
149
|
+
resolveVariables: argv['resolve-vars'],
|
|
150
|
+
includeHoverStates: !argv['no-hover'],
|
|
151
|
+
removeUnusedClasses: !argv['keep-unused-classes'],
|
|
152
|
+
removeUnusedAttributes: !argv['keep-unused-attrs'],
|
|
153
|
+
};
|
|
154
|
+
// Parse custom width viewport
|
|
155
|
+
if (options.viewport && /^\d+$/.test(options.viewport)) {
|
|
156
|
+
options.customWidth = parseInt(options.viewport, 10);
|
|
157
|
+
options.viewport = 'custom';
|
|
158
|
+
}
|
|
159
|
+
if (access.message) {
|
|
160
|
+
console.error(access.message);
|
|
161
|
+
}
|
|
162
|
+
console.error(`Extracting CSS from ${argv.url} for selector: ${argv.selector}`);
|
|
163
|
+
const result = await pipeline.extract(argv.url, argv.selector, options);
|
|
164
|
+
const format = argv.format;
|
|
165
|
+
const timestamp = new Date().toISOString();
|
|
166
|
+
// HTML preview mode: write both tailwind and original files
|
|
167
|
+
if (format === 'html') {
|
|
168
|
+
const outDir = argv.output || process.cwd();
|
|
169
|
+
const twFile = makeFilename(argv.url, argv.selector, 'tailwind', timestamp);
|
|
170
|
+
const origFile = makeFilename(argv.url, argv.selector, 'original', timestamp);
|
|
171
|
+
const twHtml = buildTailwindHtmlFile(result, argv.url, argv.selector, timestamp);
|
|
172
|
+
const origHtml = buildOriginalHtmlFile(result, argv.url, argv.selector, timestamp);
|
|
173
|
+
fs.writeFileSync(path.join(outDir, twFile), twHtml, 'utf-8');
|
|
174
|
+
fs.writeFileSync(path.join(outDir, origFile), origHtml, 'utf-8');
|
|
175
|
+
console.error(`Tailwind: ${path.join(outDir, twFile)}`);
|
|
176
|
+
console.error(`Original: ${path.join(outDir, origFile)}`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// JSON mode
|
|
180
|
+
const useJson = argv.json || format === 'json';
|
|
181
|
+
let output;
|
|
182
|
+
if (useJson) {
|
|
183
|
+
output = JSON.stringify({
|
|
184
|
+
url: argv.url,
|
|
185
|
+
selector: argv.selector,
|
|
186
|
+
timestamp,
|
|
187
|
+
html: result.html,
|
|
188
|
+
css: result.css,
|
|
189
|
+
tailwindHtml: result.tailwindHtml || result.html,
|
|
190
|
+
tailwindBodyClasses: result.tailwindBodyClasses,
|
|
191
|
+
fonts: result.fonts,
|
|
192
|
+
cssVariables: result.cssVariables,
|
|
193
|
+
}, null, 2);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
const sections = [];
|
|
197
|
+
if (format === 'css' || format === 'both') {
|
|
198
|
+
sections.push('=== HTML ===');
|
|
199
|
+
sections.push(result.html);
|
|
200
|
+
sections.push('');
|
|
201
|
+
sections.push('=== CSS ===');
|
|
202
|
+
sections.push(result.css);
|
|
203
|
+
}
|
|
204
|
+
if (format === 'tailwind' || format === 'both') {
|
|
205
|
+
if (result.tailwindHtml) {
|
|
206
|
+
sections.push('');
|
|
207
|
+
sections.push('=== TAILWIND HTML ===');
|
|
208
|
+
sections.push(result.tailwindHtml);
|
|
209
|
+
}
|
|
210
|
+
if (result.tailwindBodyClasses) {
|
|
211
|
+
sections.push('');
|
|
212
|
+
sections.push('=== TAILWIND BODY CLASSES ===');
|
|
213
|
+
sections.push(result.tailwindBodyClasses);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
output = sections.join('\n');
|
|
217
|
+
}
|
|
218
|
+
if (argv.output) {
|
|
219
|
+
fs.writeFileSync(argv.output, output, 'utf-8');
|
|
220
|
+
console.error(`Output written to ${argv.output}`);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
console.log(output);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
console.error('Extraction error:', error.message);
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
await browserManager.close();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
main();
|
|
235
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAEzE,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEjE,SAAS,YAAY,CACnB,MAAc,EACd,QAAgB,EAChB,OAAgC,EAChC,SAAiB;IAEjB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACzE,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/D,OAAO,GAAG,MAAM,IAAI,OAAO,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC;AAClD,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAAwB,EACxB,MAAc,EACd,QAAgB,EAChB,SAAiB;IAEjB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC9D,OAAO;;;;;WAKE,QAAQ,sBAAsB,MAAM;;;;EAI7C,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;eAGnD,MAAM,CAAC,mBAAmB,IAAI,EAAE;wBACvB,MAAM,gBAAgB,QAAQ,MAAM,SAAS;IACjE,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,IAAI;;QAE9B,CAAC;AACT,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAAwB,EACxB,MAAc,EACd,QAAgB,EAChB,SAAiB;IAEjB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC9D,OAAO;;;;;WAKE,QAAQ,0BAA0B,MAAM;;EAEjD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;;;;wBAI1C,MAAM,gBAAgB,QAAQ,MAAM,SAAS;IACjE,MAAM,CAAC,IAAI;;QAEP,CAAC;AACT,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAC5C,KAAK,CAAC,uDAAuD,CAAC;SAC9D,MAAM,CAAC,KAAK,EAAE;QACb,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,iCAAiC;QAC9C,YAAY,EAAE,IAAI;KACnB,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,qCAAqC;QAClD,YAAY,EAAE,IAAI;KACnB,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,0DAA0D;QACvE,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QAChB,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAU;QAC7D,WAAW,EAAE,2CAA2C;QACxD,OAAO,EAAE,MAAM;KAChB,CAAC;SACD,MAAM,CAAC,cAAc,EAAE;QACtB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,0CAA0C;QACvD,OAAO,EAAE,IAAI;KACd,CAAC;SACD,MAAM,CAAC,UAAU,EAAE;QAClB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,oCAAoC;QACjD,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,qBAAqB,EAAE;QAC7B,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,+CAA+C;QAC5D,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,mBAAmB,EAAE;QAC3B,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,qDAAqD;QAClE,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,QAAQ,EAAE;QAChB,KAAK,EAAE,GAAG;QACV,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,sEAAsE;KACpF,CAAC;SACD,MAAM,CAAC,MAAM,EAAE;QACd,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,SAAS,EAAE;QACjB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,KAAK;KACf,CAAC;SACD,MAAM,CAAC,SAAS,EAAE;QACjB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,wDAAwD;KACtE,CAAC;SACD,IAAI,EAAE;SACN,IAAI,CAAC;IAER,+CAA+C;IAC/C,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAW,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,wCAAwC,MAAM,CAAC,KAAK,uCAAuC,CAAC,CAAC;QAC7G,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,KAAK,IAAI,mBAAmB,EAAE,CAAC,CAAC;YACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,MAAM,GAAG,MAAM,WAAW,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,IAAI,+DAA+D,CAAC,CAAC;QACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,MAAM,EAAE,CAAC;QAE9B,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC,cAAc,CAAC,CAAC;QAExD,MAAM,OAAO,GAAsB;YACjC,QAAQ,EAAE,IAAI,CAAC,QAAkB;YACjC,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAY;YACjD,kBAAkB,EAAE,CAAE,IAAI,CAAC,UAAU,CAAa;YAClD,mBAAmB,EAAE,CAAE,IAAI,CAAC,qBAAqB,CAAa;YAC9D,sBAAsB,EAAE,CAAE,IAAI,CAAC,mBAAmB,CAAa;SAChE,CAAC;QAEF,8BAA8B;QAC9B,IAAI,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,OAAO,CAAC,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,QAAQ,GAAG,QAAe,CAAC;QACrC,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,GAAG,kBAAkB,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEhF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CACnC,IAAI,CAAC,GAAa,EAClB,IAAI,CAAC,QAAkB,EACvB,OAAO,CACR,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAgB,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,4DAA4D;QAC5D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,MAAM,MAAM,GAAI,IAAI,CAAC,MAAiB,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YACxD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,QAAkB,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YAChG,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,QAAkB,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;YAElG,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,QAAkB,EAAE,SAAS,CAAC,CAAC;YACrG,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,QAAkB,EAAE,SAAS,CAAC,CAAC;YAEvG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YAC7D,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEjE,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,YAAY;QACZ,MAAM,OAAO,GAAG,IAAI,CAAC,IAAe,IAAI,MAAM,KAAK,MAAM,CAAC;QAC1D,IAAI,MAAc,CAAC;QAEnB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;gBACtB,GAAG,EAAE,IAAI,CAAC,GAAG;gBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS;gBACT,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,IAAI;gBAChD,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;gBAC/C,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,YAAY,EAAE,MAAM,CAAC,YAAY;aAClC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACd,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAa,EAAE,CAAC;YAE9B,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC1C,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAC9B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAC7B,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;YAED,IAAI,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC/C,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;oBACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAClB,QAAQ,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;oBACvC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBACrC,CAAC;gBACD,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;oBAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAClB,QAAQ,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;oBAC/C,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YAED,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,MAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YACzD,OAAO,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,MAAM,cAAc,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import { BrowserManager } from './browser/browser-manager.js';
|
|
6
|
+
import { ExtractionPipeline } from './extraction/extraction-pipeline.js';
|
|
7
|
+
import { DEFAULT_VIEWPORTS } from './types/index.js';
|
|
8
|
+
import { setApiKey } from './auth/config-manager.js';
|
|
9
|
+
import { checkAccess, verifyApiKey } from './auth/usage-gate.js';
|
|
10
|
+
import { discoverElements, injectLabelOverlay, removeLabelOverlay, formatElementLegend, } from './extraction/element-discovery.js';
|
|
11
|
+
const browserManager = new BrowserManager();
|
|
12
|
+
let pipeline;
|
|
13
|
+
const server = new Server({
|
|
14
|
+
name: 'snipcss',
|
|
15
|
+
version: '1.0.0',
|
|
16
|
+
}, {
|
|
17
|
+
capabilities: {
|
|
18
|
+
tools: {},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
// List available tools
|
|
22
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
23
|
+
tools: [
|
|
24
|
+
{
|
|
25
|
+
name: 'extract_css_convert_tailwind',
|
|
26
|
+
description: 'Extract the CSS of an element subtree or get a Tailwind-converted version. ' +
|
|
27
|
+
'Navigates to the URL, finds the element by CSS selector, extracts all matched CSS rules ' +
|
|
28
|
+
'(including media queries, hover states, pseudo-elements), and converts to Tailwind utility classes.',
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
url: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'The URL of the page to extract from',
|
|
35
|
+
},
|
|
36
|
+
selector: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'CSS selector for the target element (e.g., ".hero-section", "#main-nav", "header")',
|
|
39
|
+
},
|
|
40
|
+
viewport: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
enum: ['all', 'desktop', 'tablet', 'mobile'],
|
|
43
|
+
default: 'all',
|
|
44
|
+
description: 'Viewport(s) to extract CSS for. "all" extracts at desktop, tablet, and mobile breakpoints.',
|
|
45
|
+
},
|
|
46
|
+
resolveVariables: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
default: true,
|
|
49
|
+
description: 'Whether to resolve CSS custom properties (--variables) to their computed values',
|
|
50
|
+
},
|
|
51
|
+
includeHoverStates: {
|
|
52
|
+
type: 'boolean',
|
|
53
|
+
default: true,
|
|
54
|
+
description: 'Whether to extract :hover, :active, and :focus pseudo-state styles',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ['url', 'selector'],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'set_api_key',
|
|
62
|
+
description: 'Set your SnipCSS Pro API key for unlimited CSS extractions. ' +
|
|
63
|
+
'Find your API key on your SnipCSS dashboard at snipcss.com/dashboard after upgrading to Pro.',
|
|
64
|
+
inputSchema: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
properties: {
|
|
67
|
+
api_key: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
description: 'Your SnipCSS Pro API key from your dashboard',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
required: ['api_key'],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'list_page_elements',
|
|
77
|
+
description: 'Navigate to a URL and list the major page elements with their CSS selectors, semantic types, ' +
|
|
78
|
+
'hierarchy context, and visual properties. Scans 2-3 levels deep to find cards, widgets, and forms. ' +
|
|
79
|
+
'Useful for discovering which elements to extract before calling extract_css_convert_tailwind.',
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
url: {
|
|
84
|
+
type: 'string',
|
|
85
|
+
description: 'The URL of the page to analyze',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
required: ['url'],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'screenshot_page',
|
|
93
|
+
description: 'Take an annotated screenshot of a webpage with numbered labels (#1, #2, #3...) overlaid on ' +
|
|
94
|
+
'discovered elements. Returns the screenshot image plus a legend mapping each number to its ' +
|
|
95
|
+
'CSS selector, semantic type, size, and content preview. Use this to visually identify which ' +
|
|
96
|
+
'element a user is describing (e.g., "the sidebar", "the pricing card") before extracting it.',
|
|
97
|
+
inputSchema: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
url: {
|
|
101
|
+
type: 'string',
|
|
102
|
+
description: 'The URL of the page to screenshot',
|
|
103
|
+
},
|
|
104
|
+
viewport: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
enum: ['desktop', 'tablet', 'mobile'],
|
|
107
|
+
default: 'desktop',
|
|
108
|
+
description: 'Viewport size for the screenshot',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
required: ['url'],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
}));
|
|
116
|
+
// Handle tool calls
|
|
117
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
118
|
+
const { name, arguments: args } = request.params;
|
|
119
|
+
if (name === 'set_api_key') {
|
|
120
|
+
try {
|
|
121
|
+
const apiKey = args.api_key;
|
|
122
|
+
const result = await verifyApiKey(apiKey);
|
|
123
|
+
if (result.isPro) {
|
|
124
|
+
setApiKey(apiKey);
|
|
125
|
+
return {
|
|
126
|
+
content: [{
|
|
127
|
+
type: 'text',
|
|
128
|
+
text: `API key verified and saved. Welcome, ${result.email}! You now have unlimited extractions.`,
|
|
129
|
+
}],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
content: [{
|
|
134
|
+
type: 'text',
|
|
135
|
+
text: `API key could not be verified as Pro. ${result.error || 'Please check your key and ensure you have an active Pro subscription.'}`,
|
|
136
|
+
}],
|
|
137
|
+
isError: true,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
return {
|
|
142
|
+
content: [{
|
|
143
|
+
type: 'text',
|
|
144
|
+
text: `Error verifying API key: ${error.message}`,
|
|
145
|
+
}],
|
|
146
|
+
isError: true,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (name === 'extract_css_convert_tailwind') {
|
|
151
|
+
try {
|
|
152
|
+
// Check usage/Pro access before launching browser
|
|
153
|
+
const access = await checkAccess();
|
|
154
|
+
if (!access.allowed) {
|
|
155
|
+
return {
|
|
156
|
+
content: [{
|
|
157
|
+
type: 'text',
|
|
158
|
+
text: access.message || 'Access denied. Please set your API key with the set_api_key tool.',
|
|
159
|
+
}],
|
|
160
|
+
isError: true,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
if (!pipeline) {
|
|
164
|
+
await browserManager.launch();
|
|
165
|
+
pipeline = new ExtractionPipeline(browserManager);
|
|
166
|
+
}
|
|
167
|
+
const options = {
|
|
168
|
+
viewport: args?.viewport || 'all',
|
|
169
|
+
resolveVariables: args?.resolveVariables !== false,
|
|
170
|
+
includeHoverStates: args?.includeHoverStates !== false,
|
|
171
|
+
};
|
|
172
|
+
const result = await pipeline.extract(args.url, args.selector, options);
|
|
173
|
+
let output = formatExtractionResult(result, args.url, args.selector);
|
|
174
|
+
// Append remaining extractions notice for free tier
|
|
175
|
+
if (access.message) {
|
|
176
|
+
output += `\n\n---\n_${access.message}_`;
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
content: [{ type: 'text', text: output }],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
return {
|
|
184
|
+
content: [
|
|
185
|
+
{
|
|
186
|
+
type: 'text',
|
|
187
|
+
text: `Error extracting CSS: ${error.message}`,
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
isError: true,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (name === 'list_page_elements') {
|
|
195
|
+
try {
|
|
196
|
+
await browserManager.launch();
|
|
197
|
+
const bp = await browserManager.createPage(args.url);
|
|
198
|
+
const elements = await discoverElements(bp.page);
|
|
199
|
+
await browserManager.closePage(bp);
|
|
200
|
+
let output = `## Page Elements for ${args.url}\n\n`;
|
|
201
|
+
output += `Found ${elements.length} elements:\n\n`;
|
|
202
|
+
output += `| # | Selector | Type | Size | Context | Preview |\n`;
|
|
203
|
+
output += `|---|----------|------|------|---------|--------|\n`;
|
|
204
|
+
for (const el of elements) {
|
|
205
|
+
const preview = el.textPreview.substring(0, 40).replace(/\|/g, '\\|').replace(/\n/g, ' ');
|
|
206
|
+
const bgNote = el.backgroundColor && el.backgroundColor !== 'transparent' ? ` bg:${el.backgroundColor}` : '';
|
|
207
|
+
output += `| #${el.label} | \`${el.selector}\` | ${el.semanticType} | ${el.rect.width}x${el.rect.height}${bgNote} | ${el.parentContext} | ${preview} |\n`;
|
|
208
|
+
}
|
|
209
|
+
output += `\n_Use screenshot_page to see these elements visually with numbered labels._`;
|
|
210
|
+
return {
|
|
211
|
+
content: [{ type: 'text', text: output }],
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
return {
|
|
216
|
+
content: [
|
|
217
|
+
{
|
|
218
|
+
type: 'text',
|
|
219
|
+
text: `Error listing elements: ${error.message}`,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
isError: true,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (name === 'screenshot_page') {
|
|
227
|
+
try {
|
|
228
|
+
await browserManager.launch();
|
|
229
|
+
// Determine viewport
|
|
230
|
+
const viewportName = args?.viewport || 'desktop';
|
|
231
|
+
const viewportConfig = viewportName === 'tablet'
|
|
232
|
+
? DEFAULT_VIEWPORTS.ipad
|
|
233
|
+
: viewportName === 'mobile'
|
|
234
|
+
? DEFAULT_VIEWPORTS.iphonexs
|
|
235
|
+
: DEFAULT_VIEWPORTS.default;
|
|
236
|
+
const bp = await browserManager.createPage(args.url);
|
|
237
|
+
// Set viewport if non-default
|
|
238
|
+
if (viewportName !== 'desktop') {
|
|
239
|
+
await bp.page.setViewportSize({
|
|
240
|
+
width: viewportConfig.width,
|
|
241
|
+
height: viewportConfig.height,
|
|
242
|
+
});
|
|
243
|
+
// Allow reflow
|
|
244
|
+
await bp.page.waitForTimeout(500);
|
|
245
|
+
}
|
|
246
|
+
// Discover elements
|
|
247
|
+
const elements = await discoverElements(bp.page);
|
|
248
|
+
// Inject labeled overlay
|
|
249
|
+
await injectLabelOverlay(bp.page, elements);
|
|
250
|
+
// Take screenshot
|
|
251
|
+
const screenshotBuffer = await bp.page.screenshot({
|
|
252
|
+
fullPage: true,
|
|
253
|
+
type: 'png',
|
|
254
|
+
});
|
|
255
|
+
// Remove overlay
|
|
256
|
+
await removeLabelOverlay(bp.page);
|
|
257
|
+
await browserManager.closePage(bp);
|
|
258
|
+
// Build legend text
|
|
259
|
+
const legend = formatElementLegend(elements);
|
|
260
|
+
const pageTitle = args.url;
|
|
261
|
+
return {
|
|
262
|
+
content: [
|
|
263
|
+
{
|
|
264
|
+
type: 'image',
|
|
265
|
+
data: screenshotBuffer.toString('base64'),
|
|
266
|
+
mimeType: 'image/png',
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
type: 'text',
|
|
270
|
+
text: `## Annotated Screenshot: ${pageTitle}\n\nViewport: ${viewportConfig.width}x${viewportConfig.height} (${viewportName})\n${elements.length} elements labeled:\n\n${legend}\n\n_Use the # number with list_page_elements output, then call extract_css_convert_tailwind with the selector._`,
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
return {
|
|
277
|
+
content: [
|
|
278
|
+
{
|
|
279
|
+
type: 'text',
|
|
280
|
+
text: `Error taking screenshot: ${error.message}`,
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
isError: true,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
289
|
+
isError: true,
|
|
290
|
+
};
|
|
291
|
+
});
|
|
292
|
+
function formatExtractionResult(result, url, selector) {
|
|
293
|
+
const sections = [];
|
|
294
|
+
sections.push(`## Extracted CSS for \`${selector}\` on ${url}\n`);
|
|
295
|
+
sections.push('### HTML\n');
|
|
296
|
+
sections.push('```html');
|
|
297
|
+
sections.push(result.html);
|
|
298
|
+
sections.push('```\n');
|
|
299
|
+
sections.push('### CSS\n');
|
|
300
|
+
sections.push('```css');
|
|
301
|
+
sections.push(result.css);
|
|
302
|
+
sections.push('```\n');
|
|
303
|
+
if (result.tailwindHtml) {
|
|
304
|
+
sections.push('### Tailwind HTML\n');
|
|
305
|
+
sections.push('```html');
|
|
306
|
+
sections.push(result.tailwindHtml);
|
|
307
|
+
sections.push('```\n');
|
|
308
|
+
}
|
|
309
|
+
if (result.tailwindBodyClasses) {
|
|
310
|
+
sections.push('### Tailwind Body Classes\n');
|
|
311
|
+
sections.push('```');
|
|
312
|
+
sections.push(result.tailwindBodyClasses);
|
|
313
|
+
sections.push('```\n');
|
|
314
|
+
}
|
|
315
|
+
if (result.fonts && result.fonts.length > 0) {
|
|
316
|
+
sections.push('### Fonts Used\n');
|
|
317
|
+
for (const font of result.fonts) {
|
|
318
|
+
sections.push(`- **${font.font_family}** (${font.font_weight || 'normal'}, ${font.font_style || 'normal'})`);
|
|
319
|
+
}
|
|
320
|
+
sections.push('');
|
|
321
|
+
}
|
|
322
|
+
if (result.cssVariables && Object.keys(result.cssVariables).length > 0) {
|
|
323
|
+
sections.push('### CSS Variables Resolved\n');
|
|
324
|
+
for (const [name, value] of Object.entries(result.cssVariables)) {
|
|
325
|
+
sections.push(`- \`${name}\`: \`${value}\``);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return sections.join('\n');
|
|
329
|
+
}
|
|
330
|
+
// Start the server
|
|
331
|
+
async function main() {
|
|
332
|
+
const transport = new StdioServerTransport();
|
|
333
|
+
await server.connect(transport);
|
|
334
|
+
console.error('SnipCSS MCP server running on stdio');
|
|
335
|
+
}
|
|
336
|
+
main().catch((error) => {
|
|
337
|
+
console.error('Server error:', error);
|
|
338
|
+
process.exit(1);
|
|
339
|
+
});
|
|
340
|
+
// Cleanup on exit
|
|
341
|
+
process.on('SIGINT', async () => {
|
|
342
|
+
await browserManager.close();
|
|
343
|
+
process.exit(0);
|
|
344
|
+
});
|
|
345
|
+
process.on('SIGTERM', async () => {
|
|
346
|
+
await browserManager.close();
|
|
347
|
+
process.exit(0);
|
|
348
|
+
});
|
|
349
|
+
//# 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,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS property to Tailwind class conversion.
|
|
3
|
+
* Port of tailwind_properties.js (4,001 lines)
|
|
4
|
+
*
|
|
5
|
+
* Exports:
|
|
6
|
+
* - cssToTailwind() main property→class mapper
|
|
7
|
+
* - getBestTailwindClasses() optimized margin/padding classes
|
|
8
|
+
* - getTransformClasses() transform value → Tailwind classes
|
|
9
|
+
* - getFilterClasses() filter/backdrop-filter → Tailwind classes
|
|
10
|
+
* - getFontClasses() font shorthand → Tailwind classes
|
|
11
|
+
*/
|
|
12
|
+
export declare function cssToTailwind(property: string, value: string): string | null;
|
|
13
|
+
export declare function getBestTailwindClasses(property: string, pOverwritten: Record<string, string>): string[];
|
|
14
|
+
export declare function getTransformClasses(value: string): string[];
|
|
15
|
+
export declare function getFilterClasses(value: string, isBackdrop?: boolean): string[];
|
|
16
|
+
export declare function getFontClasses(value: string): string[];
|
|
17
|
+
//# sourceMappingURL=css-to-tailwind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-to-tailwind.d.ts","sourceRoot":"","sources":["../../src/tailwind/css-to-tailwind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAqXH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0nB5E;AAID,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAiEvG;AA8BD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqH3D;AAID,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,UAAQ,GAAG,MAAM,EAAE,CAuE5E;AAID,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAgItD"}
|