snipkiwi-design-extract
CLAUDE.md1 starsChanged 34 days agoMITView on GitHub
Guidance for Claude Code when working in this repository. SnipKiwi: a Claude Code / Codex plugin that extracts the real CSS behind any element of a live web page and converts it to Tailwind. One TypeScript codebase, two entry points: - src/mcp-server.ts → src/server.ts: the MCP server (stdio). Six tools: screenshot_page, list_page_elements, extract_css_convert_tailwind, compare_to_reference, plus list_extension_snippets / get_extension_snippet (see "Extension inbox" below). - src/index.ts: the CLI (node dist/index.js --url … --selector …, or --list). Plus two shipped skills in skills/…
- Installs packages
In this repository6 other files it gives its agents.
- build-checkSkill
- test-compareSkill
- test-extractSkill
- test-mcpSkill
- clone-pageSkill
- extractSkill
The file
We split this CLAUDE.md into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 36
No test framework. Dev-only skills in .claude/skills/ (/build-check, /test-extract, /test-mcp, /test-compare) exercise the pieces.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
Guidance for Claude Code when working in this repository.
What this is
SnipKiwi: a Claude Code / Codex plugin that extracts the real CSS behind any element of a live web page and converts it to Tailwind. One TypeScript codebase, two entry points:
src/mcp-server.ts→src/server.ts: the MCP server (stdio). Six tools:screenshot_page,list_page_elements,extract_css_convert_tailwind,compare_to_reference, pluslist_extension_snippets/get_extension_snippet(see "Extension inbox" below).src/index.ts: the CLI (node dist/index.js --url … --selector …, or--list).
Plus two shipped skills in skills/ (extract, clone-page) that tell Claude how to chain the tools.
Everything is free and local. No account, no API key, no telemetry, no backend. Keep it that way: the privacy claim on snipkiwi.com/claude and in the README is "nothing leaves your machine except the page fetch".
This repo was created October 2026 from tailcode-plugin (branch tailcode-github-distribution),
itself a rename of snipcss-playwright-claudeplugin. The paid design-search stack (inspiration.ts,
PyWebview picker, pg/Voyage, section-shooter) and the Apify actor were removed here; they live on
in tailcode-plugin / tailcode-db-builder if the free plugin ever earns a paid tier.
Build, run, test
npm install
npm run build # tsc → dist/
npm run check # build + scripts/smoke.mjs (initialize + tools/list, expects the 6 tools)
node dist/index.js --url https://plugmyplugin.com --list
node dist/index.js --url https://plugmyplugin.com --selector header --format bothNo test framework. Dev-only skills in .claude/skills/ (/build-check, /test-extract, /test-mcp,
/test-compare) exercise the pieces. docs/EXTRACTOR_DEBUGGING.md covers debugging the extractor.
Distribution (GitHub only, no npm)
Users install with /plugin marketplace add mrieck/snipkiwi-design-extract then
/plugin install snipkiwi@snipkiwi. Claude Code copies the repo into its plugin cache and, because
package.json + package-lock.json are present, runs a frozen npm install there itself.
.mcp.json then launches node ${CLAUDE_PLUGIN_ROOT}/dist/mcp-server.js.
Consequences:
dist/*.jsis committed. Runnpm run buildand commitdist/with every source change..d.tsand sourcemaps are gitignored.package-lock.jsonis committed and must stay in sync withpackage.json.- Bump
versionin.claude-plugin/plugin.json(andSERVER_VERSIONinsrc/server.ts,package.json) for every release; Claude Code keys its cache on it. Then tagvX.Y.Z. package.jsonisprivate: true. Nothing is published to npm.src/preflight.tsruns before the server loads: ifnode_modulesis missing it prints the onenpm installcommand to run.browser-manager.tstries Google Chrome, then patchright's bundled Chromium, then fails with thenpx patchright install chromiumhint.
Local plugin test: /plugin marketplace add /abs/path/to/this/repo, /plugin install snipkiwi@snipkiwi,
/reload-plugins. The cache is a copy, not a symlink, so bump the version to pick up changes.
Codex users clone the repo, npm install --omit=dev, and codex mcp add snipkiwi -- node
~/snipkiwi/dist/mcp-server.js (README has the exact commands).
Architecture
Extraction pipeline (src/extraction/extraction-pipeline.ts)
- Open the page (
browser-manager.ts), attach a CDP session, collect stylesheets viaCSS.styleSheetAdded(stylesheet-collector.ts), navigate, wait for network idle. - Label the target subtree with
snipkiwi{id}-{level}-{parentId}-{currId}marker classes (dom-labeler.ts); original author classes are captured first. - Parse fonts (
font-collector.ts), variables (css-variable-resolver.ts), keyframes. - Pre-scan the collected CSS for
:hover/:checkedrules (pseudo-scanner.ts) so pseudo-state forcing is skipped when nothing can match (SNIPKIWI_NO_PSEUDO_SKIP=1disables the skip). - Per viewport (
viewport-manager.ts:all,responsive= desktop/tablet/mobile, or one):CSS.getMatchedStylesForNodein batches (style-matcher.ts), thenCSS.forcePseudoState(pseudo-state-handler.ts). Node ids are resolved once and reused across viewports. - Build CSS (
result-builder.ts,rule-deduplicator.ts,specificity.ts), convert to Tailwind (src/tailwind/), clean the HTML (html-cleaner.ts), strip markers.
ExtractionContext in src/types/index.ts is the mutable state passed through all of this.
Tailwind (src/tailwind/)
tailwind-converter.ts walks the labeled HTML with Cheerio and maps matched rules to classes using
css-to-tailwind.ts (property-level mapping), shorthand-expander.ts, tailwind-helpers.ts and
tailwind-reducer.ts. Media queries become sm:/md:/lg: prefixes, pseudo-classes become
hover: etc.
Element discovery (src/extraction/element-discovery.ts)
Shared by screenshot_page, list_page_elements and the CLI --list: segments the page into
labeled sections (#1 Header 1366x76 .nav), injects/removes the numbered overlay.
Compare (src/extraction/style-differ.ts)
captureElementStyles snapshots computed styles + rects for an element subtree; diffStyles and
formatDiffReport turn a reference/candidate pair into the deviation report returned by
compare_to_reference.
Extension inbox (src/extension/inbox.ts)
The SnipCSS Kiwi Chrome extension (snip-extension repo, branch snipkiwi-free, 3.1.0+) has a
Send to Claude Code button on its options page that writes
snipkiwi-<slug>-<uid>.snipkiwi.json to the browser's Downloads folder via FileSaver (no extra
extension permissions). inbox.ts scans $SNIPKIWI_INBOX and ~/Downloads for files whose
format is snipkiwi-snippet, tolerates Chrome's (1) duplicate suffix, and maps the record onto
the ExtractionResult shape so formatExtractionResult in server.ts renders it unchanged.
The JSON field names (html, css, cssNoResponsive, tailwindHtml, tailwindCss, tailwindBodyClasses,
fonts[{family,urls,stylesheetUrl}], fontUrls, createdAt, exportedAt) are the contract with
buildClaudeExport() in the extension's js/options/options_page.js; change both or neither.
It is a one-way file handoff on purpose: no localhost server, no pairing token, no daemon.
Conventions
- ES modules; imports use
.jsextensions. - Status and progress go to stderr. stdout is the MCP channel / CLI output. Never
console.login server code. - Uses raw CDP for CSS inspection because Playwright doesn't expose
getMatchedStylesForNodeorforcePseudoState.patchright(a stealth Playwright fork) is the browser driver. - Brand strings: SnipKiwi for the plugin, SnipCSS Kiwi for the Chrome extension. No "Pro", "upgrade", or account language anywhere.
- Marker-class prefix
snipkiwiappears indom-labeler.ts,tailwind-converter.ts,element-discovery.tsandutils/helpers.ts; change them together.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

