designlang 6.0.0 → 7.1.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.
Files changed (92) hide show
  1. package/.github/FUNDING.yml +1 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
  3. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  4. package/.github/ISSUE_TEMPLATE/feature_request.yml +28 -0
  5. package/.vercel/README.txt +11 -0
  6. package/.vercel/project.json +1 -0
  7. package/CHANGELOG.md +58 -0
  8. package/CONTRIBUTING.md +25 -0
  9. package/README.md +120 -8
  10. package/bin/design-extract.js +106 -3
  11. package/chrome-extension/README.md +41 -0
  12. package/chrome-extension/icons/favicon.svg +7 -0
  13. package/chrome-extension/icons/icon-128.png +0 -0
  14. package/chrome-extension/icons/icon-16.png +0 -0
  15. package/chrome-extension/icons/icon-32.png +0 -0
  16. package/chrome-extension/icons/icon-48.png +0 -0
  17. package/chrome-extension/manifest.json +26 -0
  18. package/chrome-extension/popup.html +167 -0
  19. package/chrome-extension/popup.js +59 -0
  20. package/docs/superpowers/plans/2026-04-18-designlang-v7.md +1121 -0
  21. package/docs/superpowers/specs/2026-04-18-designlang-v7-design.md +150 -0
  22. package/docs/superpowers/specs/2026-04-18-website-redesign-design.md +120 -0
  23. package/docs/superpowers/specs/2026-04-19-designlang-v7-1-design.md +111 -0
  24. package/package.json +5 -4
  25. package/src/config.js +26 -0
  26. package/src/crawler.js +136 -2
  27. package/src/extractors/a11y-remediation.js +47 -0
  28. package/src/extractors/component-clusters.js +39 -0
  29. package/src/extractors/css-health.js +151 -0
  30. package/src/extractors/scoring.js +20 -1
  31. package/src/extractors/semantic-regions.js +44 -0
  32. package/src/extractors/stack-fingerprint.js +88 -0
  33. package/src/formatters/_token-ref.js +44 -0
  34. package/src/formatters/agent-rules.js +116 -0
  35. package/src/formatters/android-compose.js +164 -0
  36. package/src/formatters/dtcg-tokens.js +175 -0
  37. package/src/formatters/flutter-dart.js +130 -0
  38. package/src/formatters/ios-swiftui.js +161 -0
  39. package/src/formatters/markdown.js +25 -0
  40. package/src/formatters/wordpress.js +183 -0
  41. package/src/index.js +30 -0
  42. package/src/mcp/resources.js +64 -0
  43. package/src/mcp/server.js +110 -0
  44. package/src/mcp/tools.js +149 -0
  45. package/src/utils-cookies.js +73 -0
  46. package/tests/cli.test.js +50 -0
  47. package/tests/cookies.test.js +98 -0
  48. package/tests/extractors.test.js +131 -0
  49. package/tests/formatters.test.js +232 -0
  50. package/tests/mcp.test.js +68 -0
  51. package/website/app/api/extract/route.js +216 -56
  52. package/website/app/components/A11ySlider.js +369 -0
  53. package/website/app/components/Comparison.js +286 -0
  54. package/website/app/components/CssHealth.js +243 -0
  55. package/website/app/components/HeroExtractor.js +455 -0
  56. package/website/app/components/Marginalia.js +3 -0
  57. package/website/app/components/McpSection.js +223 -0
  58. package/website/app/components/PlatformTabs.js +250 -0
  59. package/website/app/components/RegionsComponents.js +429 -0
  60. package/website/app/components/Rule.js +13 -0
  61. package/website/app/components/Specimens.js +237 -0
  62. package/website/app/components/StructuredData.js +144 -0
  63. package/website/app/components/TokenBrowser.js +344 -0
  64. package/website/app/components/token-browser-sample.js +65 -0
  65. package/website/app/globals.css +415 -633
  66. package/website/app/icon.svg +7 -0
  67. package/website/app/layout.js +113 -6
  68. package/website/app/opengraph-image.js +170 -0
  69. package/website/app/page.js +325 -148
  70. package/website/app/robots.js +15 -0
  71. package/website/app/seo-config.js +82 -0
  72. package/website/app/sitemap.js +18 -0
  73. package/website/lib/cache.js +73 -0
  74. package/website/lib/rate-limit.js +30 -0
  75. package/website/lib/rate-limit.test.js +55 -0
  76. package/website/lib/specimens.json +86 -0
  77. package/website/lib/token-helpers.js +70 -0
  78. package/website/lib/url-safety.js +103 -0
  79. package/website/lib/url-safety.test.js +116 -0
  80. package/website/lib/zip-files.js +15 -0
  81. package/website/package-lock.json +85 -0
  82. package/website/package.json +1 -0
  83. package/website/public/favicon.svg +7 -0
  84. package/website/public/logo-specimen.svg +76 -0
  85. package/website/public/mark.svg +12 -0
  86. package/website/public/site.webmanifest +13 -0
  87. package/website/app/favicon.ico +0 -0
  88. package/website/public/file.svg +0 -1
  89. package/website/public/globe.svg +0 -1
  90. package/website/public/next.svg +0 -1
  91. package/website/public/vercel.svg +0 -1
  92. package/website/public/window.svg +0 -1
@@ -0,0 +1 @@
1
+ github: [Manavarya09]
@@ -0,0 +1,62 @@
1
+ name: Bug report
2
+ description: Something in designlang is broken or produces wrong output.
3
+ title: "[Bug]: "
4
+ labels: ["bug"]
5
+ body:
6
+ - type: input
7
+ id: url
8
+ attributes:
9
+ label: URL extracted
10
+ description: The site you ran designlang against.
11
+ placeholder: https://example.com
12
+ validations:
13
+ required: true
14
+ - type: input
15
+ id: command
16
+ attributes:
17
+ label: Command used
18
+ description: The exact command you ran.
19
+ placeholder: npx designlang https://example.com --full
20
+ validations:
21
+ required: true
22
+ - type: textarea
23
+ id: expected
24
+ attributes:
25
+ label: What you expected
26
+ validations:
27
+ required: true
28
+ - type: textarea
29
+ id: actual
30
+ attributes:
31
+ label: What actually happened
32
+ description: Include stack traces, log output, or relevant snippets from output files.
33
+ validations:
34
+ required: true
35
+ - type: input
36
+ id: version
37
+ attributes:
38
+ label: designlang version
39
+ description: Output of `npx designlang --version` (or the version in package.json)
40
+ placeholder: 7.0.0
41
+ validations:
42
+ required: true
43
+ - type: input
44
+ id: node
45
+ attributes:
46
+ label: Node.js version
47
+ description: Output of `node --version`
48
+ placeholder: v20.11.0
49
+ validations:
50
+ required: true
51
+ - type: input
52
+ id: os
53
+ attributes:
54
+ label: OS
55
+ placeholder: macOS 14.5 / Ubuntu 22.04 / Windows 11
56
+ validations:
57
+ required: true
58
+ - type: textarea
59
+ id: extra
60
+ attributes:
61
+ label: Anything else
62
+ description: Screenshots, env variables, network constraints, auth requirements, etc.
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Question or discussion
4
+ url: https://github.com/Manavarya09/design-extract/discussions
5
+ about: Ask a question, share an extraction, or discuss ideas.
6
+ - name: designlang website
7
+ url: https://website-five-lime-65.vercel.app
8
+ about: Read more about what designlang does.
@@ -0,0 +1,28 @@
1
+ name: Feature request
2
+ description: Suggest a new extraction, output format, or CLI capability.
3
+ title: "[Feature]: "
4
+ labels: ["enhancement"]
5
+ body:
6
+ - type: textarea
7
+ id: problem
8
+ attributes:
9
+ label: Problem
10
+ description: What are you trying to do that designlang doesn't support today?
11
+ validations:
12
+ required: true
13
+ - type: textarea
14
+ id: proposal
15
+ attributes:
16
+ label: Proposal
17
+ description: What should designlang do? CLI flag, command, new extractor, new output format?
18
+ validations:
19
+ required: true
20
+ - type: textarea
21
+ id: alternatives
22
+ attributes:
23
+ label: Alternatives you've considered
24
+ - type: textarea
25
+ id: context
26
+ attributes:
27
+ label: Additional context
28
+ description: Example sites, example outputs, links to similar tools, screenshots.
@@ -0,0 +1,11 @@
1
+ > Why do I have a folder named ".vercel" in my project?
2
+ The ".vercel" folder is created when you link a directory to a Vercel project.
3
+
4
+ > What does the "project.json" file contain?
5
+ The "project.json" file contains:
6
+ - The ID of the Vercel project that you linked ("projectId")
7
+ - The ID of the user or team your Vercel project is owned by ("orgId")
8
+
9
+ > Should I commit the ".vercel" folder?
10
+ No, you should not share the ".vercel" folder with anyone.
11
+ Upon creation, it will be automatically added to your ".gitignore" file.
@@ -0,0 +1 @@
1
+ {"projectId":"prj_g6gBbA5TU1e3vLtU6w8FHJhy9Wmk","orgId":"team_NOd0BEOy4vNKC9vTwIRo0qdF","projectName":"website"}
package/CHANGELOG.md ADDED
@@ -0,0 +1,58 @@
1
+ # Changelog
2
+
3
+ ## [7.1.0] — 2026-04-19
4
+
5
+ ### Added
6
+
7
+ - **Cookie file support** — `--cookie-file <path>` loads cookies from a JSON array, a Playwright `storageState.json`, or a Netscape `cookies.txt` (browser extensions, curl exports). The new loader lives in `src/utils-cookies.js` and merges cleanly with the existing `--cookie name=value` flag.
8
+ - **`--insecure`** — ignores HTTPS/SSL certificate errors. Useful for self-signed dev servers, internal staging environments behind corporate proxies, and local extraction through MITM tools. Passes `ignoreHTTPSErrors: true` to the Playwright context plus the matching Chromium launch flags.
9
+ - **`--user-agent <ua>`** — override the browser User-Agent string for extraction.
10
+ - **Chrome extension** — `chrome-extension/` ships a Manifest v3 popup that hands the current tab off to [designlang.manavaryasingh.com](https://designlang.manavaryasingh.com) with the URL prefilled. Also emits a "Copy CLI" button that drops `npx designlang <url>` into the clipboard. Developer-mode install for now; Chrome Web Store listing pending.
11
+ - **Website URL query parameter** — the extractor input on the hosted site now honours `?url=<encoded>` so the Chrome extension (and any deep link) can prefill.
12
+ - **CONTRIBUTING**: "Good first issues" and "Credits" sections.
13
+
14
+ ### Thanks
15
+
16
+ - A developer from China opened a conversation proposing cookie-file handling, SSL bypass, and a Chrome packaging story — this release ships all three.
17
+
18
+ ## [7.0.0] — 2026-04-18
19
+
20
+ ### Breaking
21
+
22
+ - **Design token JSON format** — the default `*-design-tokens.json` now follows the W3C Design Tokens Community Group (DTCG) v1 spec: every leaf is `{ "$value": ..., "$type": ... }`, with two layers (`primitive.*` and `semantic.*`) and composite tokens for typography, shadow, border, and gradient. If a downstream consumer expects the pre-v7 flat shape, pass `--tokens-legacy` to preserve it.
23
+
24
+ Before (v6):
25
+ ```json
26
+ { "color": { "primary": "#3b82f6" }, "fontFamily": { "sans": "Inter" } }
27
+ ```
28
+
29
+ After (v7, default):
30
+ ```json
31
+ {
32
+ "$metadata": { "generator": "designlang", "version": "7.0.0" },
33
+ "primitive": { "color": { "brand": { "primary": { "$value": "#3b82f6", "$type": "color" } } } },
34
+ "semantic": { "color": { "action": { "primary": { "$value": "{primitive.color.brand.primary}", "$type": "color" } } } }
35
+ }
36
+ ```
37
+
38
+ Migration: either (a) update consumers to read the DTCG shape (recommended — long-term stable, ecosystem-compatible), or (b) add `--tokens-legacy` to the CLI invocation.
39
+
40
+ ### Added
41
+
42
+ - **MCP server** — new `designlang mcp --output-dir <dir>` subcommand. Stdio JSON-RPC. Resources: `designlang://tokens/primitive`, `designlang://tokens/semantic`, `designlang://regions`, `designlang://components`, `designlang://health`. Tools: `search_tokens`, `find_nearest_color`, `get_region`, `get_component`, `list_failing_contrast_pairs`.
43
+ - **Agent rules emitter** — `--emit-agent-rules` writes `.cursor/rules/designlang.mdc`, `.claude/skills/designlang/SKILL.md`, `CLAUDE.md.fragment`, and `agents.md`. All four template from the resolved semantic tokens.
44
+ - **Multi-platform emitters** — `--platforms <csv>` (values `web`, `ios`, `android`, `flutter`, `wordpress`, `all`). Additive to default web output. Emits iOS SwiftUI, Android Compose + XML, Flutter Dart + ThemeData, and a full WordPress block-theme skeleton (`theme.json` v3, `style.css`, `functions.php`, `index.php`, `templates/index.html`).
45
+ - **Stack + Tailwind fingerprint** — framework detection, Tailwind utility-class frequency map, analytics stack inventory. Surfaced on `design.stack`.
46
+ - **CSS health audit** — specificity distribution, `!important` count, duplicate declarations, unused CSS via Playwright Coverage API, `@keyframes` catalog, vendor-prefix audit. Surfaced on `design.cssHealth` and added as an additive `cssHealth` dimension in the design score.
47
+ - **A11y remediation** — for every failing WCAG contrast pair, suggests the nearest palette color that passes AA (4.5:1 / 3:1) or AAA (7:1 / 4.5:1). Surfaced on `design.accessibility.remediation`.
48
+ - **Semantic regions** — classifies page sections into `nav`, `hero`, `features`, `pricing`, `testimonials`, `cta`, `footer`, `sidebar`, `content`. Surfaced on `design.regions`.
49
+ - **Reusable component detection** — DOM subtree structural hash + cosine-similarity style vector clustering with variant detection. Surfaced on `design.componentClusters` and rendered in the markdown output.
50
+ - **MCP companion file** — `*-mcp.json` written at extract time so later `designlang mcp` invocations can serve regions / components / health / remediation from disk, not just memory.
51
+
52
+ ### Dependencies
53
+
54
+ - Added `@modelcontextprotocol/sdk` (runtime).
55
+
56
+ ### Tests
57
+
58
+ - 241/241 passing (baseline 186 + 55 new tests).
package/CONTRIBUTING.md CHANGED
@@ -61,3 +61,28 @@ When filing a bug, please include:
61
61
  - One feature/fix per PR
62
62
  - Keep PRs focused and small when possible
63
63
  - Add a brief description of what changed and why
64
+
65
+ ## Good first issues
66
+
67
+ Some work that's already scoped and ready for someone to pick up:
68
+
69
+ - **Extra cookie formats** — add support for browser-specific exports (EditThisCookie, Cookie-Editor) on top of the existing JSON / Playwright / Netscape loaders in `src/utils-cookies.js`.
70
+ - **Proxy support** — add `--proxy <url>` that passes through to Playwright's `proxy` launch option, paired with the existing `--insecure` flag for corporate networks.
71
+ - **Chrome extension: DevTools panel** — extend `chrome-extension/` with a DevTools panel that shows tokens for the current tab without leaving the browser. See the roadmap in `chrome-extension/README.md`.
72
+ - **Firefox + Edge packaging** — the manifest v3 extension already works in both; we just need store listings and icons.
73
+ - **Additional CSS-in-JS emitters** — Emotion, Stitches, Vanilla Extract, Panda, styled-components. Each is a thin formatter module under `src/formatters/`.
74
+
75
+ ## Credits
76
+
77
+ Shipped thanks to a few specific contributors — PRs welcome for the list:
78
+
79
+ - [@Manavarya09](https://github.com/Manavarya09) — author, maintainer.
80
+ - Community suggestions that landed as features: cookie-file loading, `--insecure` SSL bypass, and the first Chrome extension popup came from an external developer's proposal in mid-April 2026.
81
+
82
+ If you open a PR or file an issue that materially shapes a release, we'll add you here.
83
+
84
+ ## Code of conduct
85
+
86
+ Be decent. Disagreements about design, code, or approach are welcome — personal
87
+ attacks are not. Maintainer reserves the right to close issues and PRs that
88
+ don't engage in good faith.
package/README.md CHANGED
@@ -1,13 +1,12 @@
1
1
  <p align="center">
2
- <h1 align="center">DESIGNLANG</h1>
3
- <p align="center">Reverse-engineer any website's complete design system in one command.</p>
2
+ <img src="website/public/logo-specimen.svg" alt="designlang — reads a website the way a developer reads a stylesheet" width="900">
4
3
  </p>
5
4
 
6
5
  <p align="center">
7
- <a href="https://www.npmjs.com/package/designlang"><img src="https://img.shields.io/npm/v/designlang?color=blue&label=npm" alt="npm version"></a>
8
- <a href="https://github.com/Manavarya09/design-extract/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Manavarya09/design-extract" alt="license"></a>
9
- <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/designlang" alt="node version"></a>
10
- <a href="https://website-five-lime-65.vercel.app"><img src="https://img.shields.io/badge/website-live-red" alt="website"></a>
6
+ <a href="https://www.npmjs.com/package/designlang"><img src="https://img.shields.io/npm/v/designlang?color=0A0908&labelColor=F3F1EA&label=npm" alt="npm version"></a>
7
+ <a href="https://github.com/Manavarya09/design-extract/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Manavarya09/design-extract?color=0A0908&labelColor=F3F1EA" alt="license"></a>
8
+ <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/designlang?color=0A0908&labelColor=F3F1EA" alt="node version"></a>
9
+ <a href="https://designlang.manavaryasingh.com/"><img src="https://img.shields.io/badge/website-live-FF4800?labelColor=F3F1EA" alt="website"></a>
11
10
  </p>
12
11
 
13
12
  ---
@@ -47,6 +46,8 @@ npx designlang https://stripe.com --full
47
46
 
48
47
  The markdown output has **19 sections**: Color Palette, Typography, Spacing, Border Radii, Box Shadows, CSS Custom Properties, Breakpoints, Transitions & Animations, Component Patterns (with full CSS snippets), Layout System, Responsive Design, Interaction States, Accessibility (WCAG 2.1), Gradients, Z-Index Map, SVG Icons, Font Files, Image Style Patterns, and Quick Start.
49
48
 
49
+ In v7 a companion `*-mcp.json` file is also written alongside the 8 outputs so that `designlang mcp` can serve regions, components, and health data from disk on later invocations. Opting into `--platforms <csv>` additively emits `ios/`, `android/`, `flutter/`, and/or `wordpress-theme/` directories in the output folder, and `--emit-agent-rules` adds a `.cursor/`, `.claude/`, `CLAUDE.md.fragment`, and `agents.md` set.
50
+
50
51
  ## Install
51
52
 
52
53
  ```bash
@@ -215,6 +216,101 @@ Compare light and dark mode side-by-side — see exactly which colors change and
215
216
  designlang https://vercel.com --dark
216
217
  ```
217
218
 
219
+ ### 17. MCP Server (NEW in v7)
220
+
221
+ One-command integration with any MCP-aware AI agent (Cursor, Claude Code, Windsurf, and more):
222
+
223
+ ```bash
224
+ designlang mcp --output-dir ./design-extract-output
225
+ ```
226
+
227
+ Launches a stdio JSON-RPC server that exposes the extracted design as MCP resources and tools.
228
+
229
+ **Resources:**
230
+
231
+ - `designlang://tokens/primitive` — primitive token layer
232
+ - `designlang://tokens/semantic` — semantic token layer (with DTCG alias references)
233
+ - `designlang://regions` — classified page regions (nav, hero, pricing, etc.)
234
+ - `designlang://components` — reusable component clusters with variants
235
+ - `designlang://health` — CSS health audit
236
+
237
+ **Tools:**
238
+
239
+ - `search_tokens` — query tokens by name, value, or type
240
+ - `find_nearest_color` — snap any color to the nearest palette token
241
+ - `get_region` — fetch a classified region by name
242
+ - `get_component` — fetch a component cluster by id
243
+ - `list_failing_contrast_pairs` — list every WCAG-failing fg/bg pair with remediation suggestions
244
+
245
+ ### 18. Multi-Platform Output (NEW in v7)
246
+
247
+ Emit iOS SwiftUI, Android Compose, Flutter, and WordPress block-theme files in a single run, in addition to the default web output:
248
+
249
+ ```bash
250
+ designlang https://stripe.com --platforms all
251
+ ```
252
+
253
+ Resulting tree:
254
+
255
+ ```
256
+ design-extract-output/
257
+ ├── stripe-com-*.{md,json,css,js,html} (default web output)
258
+ ├── ios/
259
+ │ └── DesignTokens.swift
260
+ ├── android/
261
+ │ ├── Theme.kt
262
+ │ ├── colors.xml
263
+ │ └── dimens.xml
264
+ ├── flutter/
265
+ │ └── design_tokens.dart (+ buildDesignlangTheme())
266
+ └── wordpress-theme/
267
+ ├── theme.json
268
+ ├── style.css
269
+ ├── functions.php
270
+ ├── index.php
271
+ └── templates/index.html
272
+ ```
273
+
274
+ Values for `--platforms` are any comma-separated subset of `web,ios,android,flutter,wordpress,all`. The flag is additive — the default web output is always emitted.
275
+
276
+ ### 19. Agent Rules Emitter (NEW in v7)
277
+
278
+ Write agent-facing rule files generated from the resolved semantic tokens:
279
+
280
+ ```bash
281
+ designlang https://stripe.com --emit-agent-rules
282
+ ```
283
+
284
+ Writes:
285
+
286
+ - `.cursor/rules/designlang.mdc` — Cursor rule
287
+ - `.claude/skills/designlang/SKILL.md` — Claude Code skill
288
+ - `CLAUDE.md.fragment` — snippet you can paste into your project's CLAUDE.md
289
+ - `agents.md` — generic, vendor-neutral agent guidance
290
+
291
+ Each file is templated from the semantic layer of the extracted token set, so the agent sees real token names and values — not placeholders.
292
+
293
+ ### 20. Stack + Tailwind Fingerprint (NEW in v7)
294
+
295
+ Automatic framework, utility-class, and analytics detection surfaced on `design.stack`:
296
+
297
+ - **Framework**: Next.js, Nuxt, Gatsby, Remix, Astro, Shopify, WordPress, Framer, Webflow, and more.
298
+ - **Tailwind**: when Tailwind is in use, records utility-class frequency so you see which utilities drive the design.
299
+ - **Analytics**: inventory of analytics scripts — GA4, Plausible, PostHog, Segment, Mixpanel, Amplitude, and friends.
300
+
301
+ ### 21. CSS Health Audit (NEW in v7)
302
+
303
+ A dedicated audit pass surfaced on `design.cssHealth`:
304
+
305
+ - Specificity graph (distribution, hotspots)
306
+ - `!important` count
307
+ - Duplicate declarations
308
+ - Unused CSS via the Playwright Coverage API
309
+ - `@keyframes` catalog
310
+ - Vendor-prefix audit
311
+
312
+ Also contributes a `cssHealth` dimension to the overall design score.
313
+
218
314
  ## All Features
219
315
 
220
316
  | Feature | Flag / Command | Description |
@@ -243,6 +339,15 @@ designlang https://vercel.com --dark
243
339
  | Multi-brand | `designlang brands <urls...>` | N-site comparison matrix |
244
340
  | Sync | `designlang sync <url>` | Update local tokens from live site |
245
341
  | History | `designlang history <url>` | Track design changes over time |
342
+ | MCP server | `designlang mcp` | Expose extraction as MCP resources + tools |
343
+ | Multi-platform | `--platforms <csv>` | Emit iOS / Android / Flutter / WordPress outputs |
344
+ | Agent rules | `--emit-agent-rules` | Cursor, Claude Code, generic agent rule files |
345
+ | Stack fingerprint | automatic | Framework + Tailwind + analytics detection |
346
+ | CSS health | automatic | Specificity, !important, unused CSS, keyframes |
347
+ | A11y remediation | automatic | Nearest palette color passing AA / AAA for every failing pair |
348
+ | Semantic regions | automatic | nav / hero / pricing / testimonials / cta / footer classification |
349
+ | Reusable components | automatic | DOM subtree + style-vector clustering with variants |
350
+ | DTCG tokens | default | W3C Design Tokens v1 with semantic + composite layers (`--tokens-legacy` for pre-v7) |
246
351
 
247
352
  ## Full CLI Reference
248
353
 
@@ -262,8 +367,14 @@ Options:
262
367
  --interactions Capture hover/focus/active states
263
368
  --full Enable all captures
264
369
  --cookie <cookies...> Cookies for authenticated pages (name=value)
370
+ --cookie-file <path> Load cookies from JSON / storageState / Netscape cookies.txt
265
371
  --header <headers...> Custom headers (name:value)
372
+ --user-agent <ua> Override the browser User-Agent string
373
+ --insecure Ignore HTTPS/SSL certificate errors (self-signed, dev, proxies)
266
374
  --framework <type> Only generate specific theme (react, shadcn)
375
+ --platforms <csv> Additional platforms: web,ios,android,flutter,wordpress,all (additive)
376
+ --emit-agent-rules Emit Cursor / Claude Code / CLAUDE.md / agents.md rule files
377
+ --tokens-legacy Emit pre-v7 flat design-tokens.json shape (backward compat)
267
378
  --no-history Skip saving to history
268
379
  --verbose Detailed progress output
269
380
 
@@ -276,6 +387,7 @@ Commands:
276
387
  brands <urls...> Multi-brand comparison matrix
277
388
  sync <url> Sync local tokens with live site
278
389
  history <url> View design change history
390
+ mcp Launch stdio MCP server (--output-dir <dir>)
279
391
  ```
280
392
 
281
393
  ## Example Output
@@ -343,7 +455,7 @@ In Claude Code, use `/extract-design <url>`.
343
455
 
344
456
  ## Website
345
457
 
346
- **[website-five-lime-65.vercel.app](https://website-five-lime-65.vercel.app)** — the brutalist product page.
458
+ **[design-extract-beta.vercel.app](https://design-extract-beta.vercel.app)** — the brutalist product page.
347
459
 
348
460
  ## Contributing
349
461
 
@@ -351,4 +463,4 @@ See [CONTRIBUTING.md](CONTRIBUTING.md). PRs welcome!
351
463
 
352
464
  ## License
353
465
 
354
- [MIT](LICENSE) - Manavarya Singh
466
+ [MIT](LICENSE) - Manav Arya Singh
@@ -8,14 +8,19 @@ import ora from 'ora';
8
8
  import { extractDesignLanguage } from '../src/index.js';
9
9
  import { formatMarkdown } from '../src/formatters/markdown.js';
10
10
  import { formatTokens } from '../src/formatters/tokens.js';
11
+ import { formatDtcgTokens } from '../src/formatters/dtcg-tokens.js';
11
12
  import { formatTailwind } from '../src/formatters/tailwind.js';
12
13
  import { formatCssVars } from '../src/formatters/css-vars.js';
13
14
  import { formatPreview } from '../src/formatters/preview.js';
14
15
  import { formatFigma } from '../src/formatters/figma.js';
15
16
  import { formatReactTheme, formatShadcnTheme } from '../src/formatters/theme.js';
16
- import { formatWordPress } from '../src/formatters/wordpress.js';
17
+ import { formatWordPress, formatWordPressTheme } from '../src/formatters/wordpress.js';
18
+ import { formatIosSwiftUI } from '../src/formatters/ios-swiftui.js';
19
+ import { formatAndroidCompose } from '../src/formatters/android-compose.js';
20
+ import { formatFlutterDart } from '../src/formatters/flutter-dart.js';
17
21
  import { formatVueTheme } from '../src/formatters/vue-theme.js';
18
22
  import { formatSvelteTheme } from '../src/formatters/svelte-theme.js';
23
+ import { formatAgentRules } from '../src/formatters/agent-rules.js';
19
24
  import { loadConfig, mergeConfig } from '../src/config.js';
20
25
  import { diffDesigns, formatDiffMarkdown, formatDiffHtml } from '../src/diff.js';
21
26
  import { saveSnapshot, getHistory, formatHistoryMarkdown } from '../src/history.js';
@@ -60,8 +65,14 @@ program
60
65
  .option('--interactions', 'capture hover/focus/active states')
61
66
  .option('--full', 'enable all extra captures (screenshots, responsive, interactions)')
62
67
  .option('--cookie <cookies...>', 'cookies for authenticated pages (name=value)')
68
+ .option('--cookie-file <path>', 'load cookies from JSON, Playwright storageState, or Netscape cookies.txt')
63
69
  .option('--header <headers...>', 'custom headers (name:value)')
70
+ .option('--user-agent <ua>', 'override the browser User-Agent string')
71
+ .option('--insecure', 'ignore HTTPS/SSL certificate errors (self-signed, dev, proxies)')
64
72
  .option('--ignore <selectors...>', 'CSS selectors to remove before extraction')
73
+ .option('--tokens-legacy', 'Emit pre-v7 flat token JSON (backward compat)')
74
+ .option('--platforms <csv>', 'Additional platforms: web,ios,android,flutter,wordpress,all (web is always emitted)', 'web')
75
+ .option('--emit-agent-rules', 'Emit Cursor/Claude Code/generic agent rules')
65
76
  .option('--json', 'output raw JSON to stdout (for CI/CD)')
66
77
  .option('--json-pretty', 'output formatted JSON to stdout')
67
78
  .option('--no-history', 'skip saving to history')
@@ -107,7 +118,19 @@ program
107
118
  try {
108
119
  spinner.text = `Crawling${merged.depth > 0 ? ` (depth: ${merged.depth})` : ''}...`;
109
120
  // Parse auth options
110
- const cookies = merged.cookie || [];
121
+ const cliCookies = merged.cookie || [];
122
+ const fileCookies = [];
123
+ if (merged.cookieFile) {
124
+ try {
125
+ const { loadCookiesFromFile } = await import('../src/utils-cookies.js');
126
+ fileCookies.push(...loadCookiesFromFile(resolve(merged.cookieFile), url));
127
+ } catch (e) {
128
+ console.error(chalk.red(`\n cookie-file load failed: ${e.message}\n`));
129
+ process.exit(1);
130
+ }
131
+ }
132
+ const { mergeCookies } = await import('../src/utils-cookies.js');
133
+ const cookies = mergeCookies(cliCookies, fileCookies, url);
111
134
  const headers = {};
112
135
  if (merged.header) {
113
136
  for (const h of merged.header) {
@@ -127,6 +150,8 @@ program
127
150
  ignore: merged.ignore,
128
151
  cookies: cookies.length > 0 ? cookies : undefined,
129
152
  headers: Object.keys(headers).length > 0 ? headers : undefined,
153
+ insecure: merged.insecure || false,
154
+ userAgent: merged.userAgent,
130
155
  });
131
156
 
132
157
  // Responsive capture
@@ -153,7 +178,7 @@ program
153
178
 
154
179
  const files = [
155
180
  { name: `${prefix}-design-language.md`, content: formatMarkdown(design), label: 'Markdown (AI-optimized)' },
156
- { name: `${prefix}-design-tokens.json`, content: formatTokens(design), label: 'Design Tokens (W3C)' },
181
+ { name: `${prefix}-design-tokens.json`, content: merged.tokensLegacy ? formatTokens(design) : JSON.stringify(formatDtcgTokens(design), null, 2), label: merged.tokensLegacy ? 'Design Tokens (legacy)' : 'Design Tokens (DTCG v1)' },
157
182
  { name: `${prefix}-tailwind.config.js`, content: formatTailwind(design), label: 'Tailwind Config' },
158
183
  { name: `${prefix}-variables.css`, content: formatCssVars(design), label: 'CSS Variables' },
159
184
  { name: `${prefix}-preview.html`, content: formatPreview(design), label: 'Visual Preview' },
@@ -178,10 +203,72 @@ program
178
203
  // WordPress theme (always generated)
179
204
  files.push({ name: `${prefix}-wordpress-theme.json`, content: formatWordPress(design), label: 'WordPress Theme' });
180
205
 
206
+ // MCP companion — the subset of `design` the MCP server serves when a
207
+ // user runs `designlang mcp --output-dir <dir>` later.
208
+ const mcpPayload = {
209
+ colors: { all: design.colors?.all || [] },
210
+ regions: design.regions || [],
211
+ componentClusters: design.componentClusters || [],
212
+ accessibility: { remediation: design.accessibility?.remediation || [] },
213
+ cssHealth: design.cssHealth || null,
214
+ };
215
+ files.push({ name: `${prefix}-mcp.json`, content: JSON.stringify(mcpPayload, null, 2), label: 'MCP companion' });
216
+
181
217
  for (const file of files) {
182
218
  writeFileSync(join(outDir, file.name), file.content, 'utf-8');
183
219
  }
184
220
 
221
+ // Multi-platform emission (v7.0). web is already emitted above.
222
+ const platforms = merged.platforms || ['web'];
223
+ const dtcgTokens = formatDtcgTokens(design);
224
+ const platformFiles = [];
225
+ if (platforms.includes('ios')) {
226
+ const dir = join(outDir, 'ios');
227
+ mkdirSync(dir, { recursive: true });
228
+ const path = join(dir, 'DesignTokens.swift');
229
+ writeFileSync(path, formatIosSwiftUI(dtcgTokens), 'utf-8');
230
+ platformFiles.push({ path, label: 'iOS SwiftUI' });
231
+ }
232
+ if (platforms.includes('android')) {
233
+ const dir = join(outDir, 'android');
234
+ mkdirSync(dir, { recursive: true });
235
+ const out = formatAndroidCompose(dtcgTokens);
236
+ for (const name of Object.keys(out)) {
237
+ const p = join(dir, name);
238
+ writeFileSync(p, out[name], 'utf-8');
239
+ platformFiles.push({ path: p, label: `Android (${name})` });
240
+ }
241
+ }
242
+ if (platforms.includes('flutter')) {
243
+ const dir = join(outDir, 'flutter');
244
+ mkdirSync(dir, { recursive: true });
245
+ const p = join(dir, 'design_tokens.dart');
246
+ writeFileSync(p, formatFlutterDart(dtcgTokens), 'utf-8');
247
+ platformFiles.push({ path: p, label: 'Flutter Dart' });
248
+ }
249
+ if (platforms.includes('wordpress')) {
250
+ const dir = join(outDir, 'wordpress-theme');
251
+ mkdirSync(dir, { recursive: true });
252
+ const out = formatWordPressTheme(dtcgTokens, design);
253
+ for (const name of Object.keys(out)) {
254
+ const p = join(dir, name);
255
+ mkdirSync(join(p, '..'), { recursive: true });
256
+ writeFileSync(p, out[name], 'utf-8');
257
+ platformFiles.push({ path: p, label: `WordPress (${name})` });
258
+ }
259
+ }
260
+
261
+ // Agent rules (opt-in, also enabled by --full)
262
+ if (merged.emitAgentRules || merged.full) {
263
+ const agentFiles = formatAgentRules({ design, tokens: dtcgTokens, url });
264
+ for (const rel of Object.keys(agentFiles)) {
265
+ const p = join(outDir, rel);
266
+ mkdirSync(join(p, '..'), { recursive: true });
267
+ writeFileSync(p, agentFiles[rel], 'utf-8');
268
+ platformFiles.push({ path: p, label: `Agent rules (${rel})` });
269
+ }
270
+ }
271
+
185
272
  // Save to history
186
273
  if (opts.history !== false) {
187
274
  const histInfo = saveSnapshot(design);
@@ -197,6 +284,9 @@ program
197
284
  for (const file of files) {
198
285
  console.log(join(outDir, file.name));
199
286
  }
287
+ for (const pf of platformFiles) {
288
+ console.log(pf.path);
289
+ }
200
290
  } else {
201
291
  console.log('');
202
292
  console.log(chalk.bold(' Output files:'));
@@ -205,6 +295,9 @@ program
205
295
  const sizeStr = size > 1024 ? `${(size / 1024).toFixed(1)}KB` : `${size}B`;
206
296
  console.log(` ${chalk.green('✓')} ${chalk.cyan(file.name)} ${chalk.gray(`(${sizeStr})`)} — ${file.label}`);
207
297
  }
298
+ for (const pf of platformFiles) {
299
+ console.log(` ${chalk.green('✓')} ${chalk.cyan(pf.path)} — ${pf.label}`);
300
+ }
208
301
  if (opts.screenshots && design.componentScreenshots && Object.keys(design.componentScreenshots).length > 0) {
209
302
  for (const [, info] of Object.entries(design.componentScreenshots)) {
210
303
  console.log(` ${chalk.green('✓')} ${chalk.cyan(info.path)} — ${info.label} screenshot`);
@@ -685,4 +778,14 @@ program
685
778
  }
686
779
  });
687
780
 
781
+ // ── MCP server command ─────────────────────────────────────
782
+ program
783
+ .command('mcp')
784
+ .description('Launch designlang MCP server over stdio (exposes latest extraction as resources + tools)')
785
+ .option('--output-dir <path>', 'Source extraction directory', './design-extract-output')
786
+ .action(async (opts) => {
787
+ const { run } = await import('../src/mcp/server.js');
788
+ await run(opts);
789
+ });
790
+
688
791
  program.parse();
@@ -0,0 +1,41 @@
1
+ # designlang — Chrome extension
2
+
3
+ Right-click → Extract design on any page. The extension opens
4
+ [designlang.manavaryasingh.com](https://designlang.manavaryasingh.com) with the
5
+ current tab's URL prefilled, so extraction starts with one click instead of
6
+ switching windows and pasting.
7
+
8
+ ## Features
9
+
10
+ - One-click handoff from any `http(s)://` page to the hosted extractor
11
+ - "Copy CLI" button — drops `npx designlang <url>` straight into your clipboard
12
+ - Zero tracking, zero analytics, zero permissions beyond `activeTab`
13
+
14
+ ## Install (developer mode, pending Chrome Web Store publish)
15
+
16
+ 1. Clone this repo.
17
+ 2. Open `chrome://extensions` in Chromium / Chrome / Edge / Arc / Brave.
18
+ 3. Toggle **Developer mode** (top right).
19
+ 4. Click **Load unpacked** and pick the `chrome-extension/` folder in this repo.
20
+ 5. Pin the extension from the puzzle-piece menu.
21
+
22
+ ## Permissions
23
+
24
+ - `activeTab` — to read the URL of the tab you triggered the popup on.
25
+ - `host_permissions` scoped to `https://designlang.manavaryasingh.com/*` for the
26
+ handoff.
27
+
28
+ No content scripts, no remote code, no background service worker. The whole
29
+ extension is ~3 KB of static HTML/JS/CSS.
30
+
31
+ ## Roadmap
32
+
33
+ - Chrome Web Store listing.
34
+ - Optional right-click context menu on links: *"Extract design from this link"*.
35
+ - DevTools panel that shows the extracted tokens for the current tab alongside
36
+ the real DOM selector that produced them.
37
+ - Firefox + Edge listings (the same MV3 manifest works for both).
38
+
39
+ ## Contributing
40
+
41
+ PRs welcome. See the root [`CONTRIBUTING.md`](../CONTRIBUTING.md).
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="designlang">
2
+ <title>designlang</title>
3
+ <rect width="32" height="32" fill="#F3F1EA"/>
4
+ <circle cx="13" cy="20" r="7.5" fill="none" stroke="#0A0908" stroke-width="4.5"/>
5
+ <rect x="19" y="4" width="4.5" height="25" fill="#0A0908"/>
6
+ <rect x="25" y="25" width="4" height="4" fill="#FF4800"/>
7
+ </svg>