designlang 3.0.0 → 4.0.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 +188 -73
- package/bin/design-extract.js +149 -1
- package/package.json +1 -1
- package/src/clone.js +218 -0
- package/src/crawler.js +10 -6
- package/src/extractors/components.js +86 -0
- package/src/extractors/interactions.js +3 -2
- package/src/extractors/responsive.js +3 -2
- package/src/extractors/scoring.js +132 -0
- package/src/formatters/markdown.js +31 -0
- package/src/index.js +7 -0
- package/src/watch.js +47 -0
- package/website/.claude/launch.json +11 -0
- package/website/AGENTS.md +5 -0
- package/website/CLAUDE.md +1 -0
- package/website/README.md +36 -0
- package/website/app/favicon.ico +0 -0
- package/website/app/globals.css +432 -0
- package/website/app/layout.js +19 -0
- package/website/app/page.js +162 -0
- package/website/jsconfig.json +7 -0
- package/website/next.config.mjs +6 -0
- package/website/package-lock.json +912 -0
- package/website/package.json +15 -0
- package/website/public/file.svg +1 -0
- package/website/public/globe.svg +1 -0
- package/website/public/next.svg +1 -0
- package/website/public/vercel.svg +1 -0
- package/website/public/window.svg +1 -0
package/README.md
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<h1 align="center">
|
|
3
|
-
<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>
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
7
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
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
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>
|
|
10
11
|
</p>
|
|
11
12
|
|
|
12
13
|
---
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src="designlang.png" alt="designlang in action" width="100%">
|
|
17
|
+
</p>
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
**designlang** crawls any website with a headless browser, extracts every computed style from the live DOM, and generates **8 output files** — including an AI-optimized markdown file, visual HTML preview, Tailwind config, React theme, shadcn/ui theme, Figma variables, W3C design tokens, and CSS custom properties.
|
|
17
20
|
|
|
18
|
-
|
|
21
|
+
But unlike every other tool out there, it also extracts **layout patterns** (grids, flexbox, containers), captures **responsive behavior** across 4 breakpoints, records **interaction states** (hover, focus, active), scores **WCAG accessibility**, and lets you **compare multiple brands** or **sync live sites to local tokens**.
|
|
19
22
|
|
|
20
23
|
## Quick Start
|
|
21
24
|
|
|
@@ -23,18 +26,26 @@ It also does **WCAG accessibility scoring**, **component screenshot capture**, *
|
|
|
23
26
|
npx designlang https://stripe.com
|
|
24
27
|
```
|
|
25
28
|
|
|
29
|
+
Get everything at once:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx designlang https://stripe.com --full
|
|
33
|
+
```
|
|
34
|
+
|
|
26
35
|
## What You Get (8 Files)
|
|
27
36
|
|
|
28
37
|
| File | What it is |
|
|
29
38
|
|------|------------|
|
|
30
|
-
| `*-design-language.md` | AI-optimized markdown —
|
|
31
|
-
| `*-preview.html` | Visual
|
|
32
|
-
| `*-design-tokens.json` | [W3C Design Tokens](https://design-tokens.github.io/community-group/format/)
|
|
33
|
-
| `*-tailwind.config.js` | Drop-in Tailwind CSS theme
|
|
34
|
-
| `*-variables.css` | CSS custom properties
|
|
39
|
+
| `*-design-language.md` | AI-optimized markdown — feed it to any LLM to recreate the design |
|
|
40
|
+
| `*-preview.html` | Visual report with swatches, type scale, shadows, a11y score |
|
|
41
|
+
| `*-design-tokens.json` | [W3C Design Tokens](https://design-tokens.github.io/community-group/format/) format |
|
|
42
|
+
| `*-tailwind.config.js` | Drop-in Tailwind CSS theme |
|
|
43
|
+
| `*-variables.css` | CSS custom properties |
|
|
35
44
|
| `*-figma-variables.json` | Figma Variables import (with dark mode support) |
|
|
36
|
-
| `*-theme.js` | React/CSS-in-JS theme
|
|
37
|
-
| `*-shadcn-theme.css` | shadcn/ui globals.css
|
|
45
|
+
| `*-theme.js` | React/CSS-in-JS theme (Chakra, Stitches, Vanilla Extract) |
|
|
46
|
+
| `*-shadcn-theme.css` | shadcn/ui globals.css variables |
|
|
47
|
+
|
|
48
|
+
The markdown output has **14 sections**: Color Palette, Typography, Spacing, Border Radii, Box Shadows, CSS Custom Properties, Breakpoints, Transitions & Animations, Component Patterns, Layout System, Responsive Design, Interaction States, Accessibility (WCAG 2.1), and Quick Start.
|
|
38
49
|
|
|
39
50
|
## Install
|
|
40
51
|
|
|
@@ -44,94 +55,141 @@ npx designlang https://example.com
|
|
|
44
55
|
|
|
45
56
|
# Or install globally
|
|
46
57
|
npm install -g designlang
|
|
58
|
+
|
|
59
|
+
# As an agent skill (Claude Code, Cursor, Codex, 40+ agents)
|
|
60
|
+
npx skills add Manavarya09/design-extract
|
|
47
61
|
```
|
|
48
62
|
|
|
49
|
-
##
|
|
63
|
+
## What Makes This Different
|
|
50
64
|
|
|
51
|
-
|
|
65
|
+
Most design extraction tools give you colors and fonts. That's it. designlang fills 5 market gaps that no other tool addresses:
|
|
52
66
|
|
|
53
|
-
|
|
67
|
+
### 1. Layout System Extraction
|
|
54
68
|
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
Extracts the structural skeleton — grid column patterns, flex direction usage, container widths, gap values, and justify/align patterns.
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Layout: 55 grids, 492 flex containers
|
|
57
73
|
```
|
|
58
74
|
|
|
59
|
-
|
|
75
|
+
Every other tool gives you the paint. designlang gives you the architecture.
|
|
60
76
|
|
|
61
|
-
|
|
77
|
+
### 2. Responsive Multi-Breakpoint Capture
|
|
62
78
|
|
|
79
|
+
Crawls the site at 4 viewports (mobile, tablet, desktop, wide) and maps exactly what changes:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
designlang https://vercel.com --responsive
|
|
63
83
|
```
|
|
64
|
-
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
Responsive: 4 viewports, 3 breakpoint changes
|
|
87
|
+
375px → 768px: Nav visibility hidden → visible, Hamburger shown → hidden
|
|
88
|
+
768px → 1280px: Max grid columns 1 → 3, H1 size 32px → 48px
|
|
65
89
|
```
|
|
66
90
|
|
|
67
|
-
|
|
91
|
+
No other tool captures how the design *adapts*, just how it looks at one size.
|
|
68
92
|
|
|
69
|
-
###
|
|
93
|
+
### 3. Interaction State Capture
|
|
70
94
|
|
|
71
|
-
|
|
95
|
+
Programmatically hovers and focuses interactive elements, capturing the actual style transitions:
|
|
72
96
|
|
|
73
97
|
```bash
|
|
74
|
-
designlang https://
|
|
98
|
+
designlang https://stripe.com --interactions
|
|
75
99
|
```
|
|
76
100
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
```css
|
|
102
|
+
/* Button Hover */
|
|
103
|
+
background-color: rgb(83, 58, 253) → rgb(67, 47, 202);
|
|
104
|
+
box-shadow: none → 0 4px 12px rgba(83, 58, 253, 0.4);
|
|
80
105
|
|
|
81
|
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- Shadow cards with actual CSS shadows
|
|
86
|
-
- Accessibility score and failing pair analysis
|
|
87
|
-
- Component screenshots (when `--screenshots` is used)
|
|
106
|
+
/* Input Focus */
|
|
107
|
+
border-color: rgb(200, 200, 200) → rgb(83, 58, 253);
|
|
108
|
+
outline: none → 2px solid rgb(83, 58, 253);
|
|
109
|
+
```
|
|
88
110
|
|
|
89
|
-
###
|
|
111
|
+
### 4. Live Site Sync
|
|
90
112
|
|
|
91
|
-
|
|
113
|
+
Treat the deployed site as your source of truth, not Figma:
|
|
92
114
|
|
|
93
115
|
```bash
|
|
94
|
-
designlang
|
|
116
|
+
designlang sync https://stripe.com --out ./src/tokens
|
|
95
117
|
```
|
|
96
118
|
|
|
97
|
-
|
|
119
|
+
Detects design changes and auto-updates your local `design-tokens.json`, `tailwind.config.js`, and `variables.css`.
|
|
98
120
|
|
|
99
|
-
###
|
|
121
|
+
### 5. Multi-Brand Comparison
|
|
100
122
|
|
|
101
|
-
|
|
123
|
+
Compare N brands side-by-side:
|
|
102
124
|
|
|
103
125
|
```bash
|
|
104
|
-
|
|
105
|
-
|
|
126
|
+
designlang brands stripe.com vercel.com github.com linear.app
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Generates a matrix with color overlap analysis, typography comparison, spacing systems, and accessibility scores. Outputs both `brands.md` and `brands.html`.
|
|
130
|
+
|
|
131
|
+
### 6. Clone Command
|
|
132
|
+
|
|
133
|
+
Generate a working Next.js app with the extracted design applied:
|
|
106
134
|
|
|
107
|
-
|
|
108
|
-
designlang
|
|
135
|
+
```bash
|
|
136
|
+
designlang clone https://stripe.com
|
|
137
|
+
cd cloned-design && npm install && npm run dev
|
|
109
138
|
```
|
|
110
139
|
|
|
111
|
-
|
|
140
|
+
One command → a running app with the site's colors, fonts, spacing, and component patterns.
|
|
141
|
+
|
|
142
|
+
### 7. Design System Scoring
|
|
112
143
|
|
|
113
|
-
|
|
144
|
+
Rate any site's design quality across 7 categories:
|
|
114
145
|
|
|
115
|
-
|
|
146
|
+
```bash
|
|
147
|
+
designlang score https://vercel.com
|
|
148
|
+
```
|
|
116
149
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
150
|
+
```
|
|
151
|
+
68/100 Grade: D
|
|
152
|
+
|
|
153
|
+
Color Discipline ██████████░░░░░░░░░░ 50
|
|
154
|
+
Typography ██████████████░░░░░░ 70
|
|
155
|
+
Spacing System ████████████████░░░░ 80
|
|
156
|
+
Shadows ██████████░░░░░░░░░░ 50
|
|
157
|
+
Border Radii ████████░░░░░░░░░░░░ 40
|
|
158
|
+
Accessibility ███████████████████░ 94
|
|
159
|
+
Tokenization ████████████████████ 100
|
|
160
|
+
```
|
|
120
161
|
|
|
121
|
-
|
|
162
|
+
### 8. Watch Mode
|
|
122
163
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
|
134
|
-
|
|
164
|
+
Monitor a site for design changes:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
designlang watch https://stripe.com --interval 60
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Checks hourly and alerts when colors, fonts, or accessibility scores change.
|
|
171
|
+
|
|
172
|
+
## All Features
|
|
173
|
+
|
|
174
|
+
| Feature | Flag / Command | Description |
|
|
175
|
+
|---------|---------------|-------------|
|
|
176
|
+
| Base extraction | `designlang <url>` | Colors, typography, spacing, shadows, radii, CSS vars, breakpoints, animations, components |
|
|
177
|
+
| Layout system | automatic | Grid patterns, flex usage, container widths, gap values |
|
|
178
|
+
| Accessibility | automatic | WCAG 2.1 contrast ratios for all fg/bg pairs |
|
|
179
|
+
| Design scoring | automatic | 7-category quality rating (A-F) with actionable issues |
|
|
180
|
+
| Dark mode | `--dark` | Extracts dark color scheme |
|
|
181
|
+
| Multi-page | `--depth <n>` | Crawl N internal pages for site-wide tokens |
|
|
182
|
+
| Screenshots | `--screenshots` | Capture buttons, cards, inputs, nav, hero, full page |
|
|
183
|
+
| Responsive | `--responsive` | Crawl at 4 viewports, map breakpoint changes |
|
|
184
|
+
| Interactions | `--interactions` | Capture hover/focus/active state transitions |
|
|
185
|
+
| Everything | `--full` | Enable screenshots + responsive + interactions |
|
|
186
|
+
| Clone | `designlang clone <url>` | Generate a working Next.js starter with extracted design |
|
|
187
|
+
| Score | `designlang score <url>` | Rate design quality with visual bar chart breakdown |
|
|
188
|
+
| Watch | `designlang watch <url>` | Monitor for design changes on interval |
|
|
189
|
+
| Diff | `designlang diff <A> <B>` | Compare two sites (MD + HTML) |
|
|
190
|
+
| Multi-brand | `designlang brands <urls...>` | N-site comparison matrix |
|
|
191
|
+
| Sync | `designlang sync <url>` | Update local tokens from live site |
|
|
192
|
+
| History | `designlang history <url>` | Track design changes over time |
|
|
135
193
|
|
|
136
194
|
## Full CLI Reference
|
|
137
195
|
|
|
@@ -145,29 +203,86 @@ Options:
|
|
|
145
203
|
--height <px> Viewport height (default: 800)
|
|
146
204
|
--wait <ms> Wait after page load for SPAs (default: 0)
|
|
147
205
|
--dark Also extract dark mode styles
|
|
148
|
-
--depth <n>
|
|
206
|
+
--depth <n> Internal pages to crawl (default: 0)
|
|
149
207
|
--screenshots Capture component screenshots
|
|
208
|
+
--responsive Capture at multiple breakpoints
|
|
209
|
+
--interactions Capture hover/focus/active states
|
|
210
|
+
--full Enable all captures
|
|
150
211
|
--framework <type> Only generate specific theme (react, shadcn)
|
|
151
212
|
--no-history Skip saving to history
|
|
152
213
|
--verbose Detailed progress output
|
|
153
214
|
|
|
154
215
|
Commands:
|
|
216
|
+
clone <url> Generate a working Next.js starter from extracted design
|
|
217
|
+
score <url> Rate design quality (7 categories, A-F, bar chart)
|
|
218
|
+
watch <url> Monitor for design changes on interval
|
|
155
219
|
diff <urlA> <urlB> Compare two sites' design languages
|
|
156
|
-
|
|
220
|
+
brands <urls...> Multi-brand comparison matrix
|
|
221
|
+
sync <url> Sync local tokens with live site
|
|
222
|
+
history <url> View design change history
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Example Output
|
|
226
|
+
|
|
227
|
+
Running `designlang https://vercel.com --full`:
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
designlang
|
|
231
|
+
https://vercel.com
|
|
232
|
+
|
|
233
|
+
Output files:
|
|
234
|
+
✓ vercel-com-design-language.md (32.6KB)
|
|
235
|
+
✓ vercel-com-design-tokens.json (5.6KB)
|
|
236
|
+
✓ vercel-com-tailwind.config.js (3.4KB)
|
|
237
|
+
✓ vercel-com-variables.css (18.6KB)
|
|
238
|
+
✓ vercel-com-preview.html (31.8KB)
|
|
239
|
+
✓ vercel-com-figma-variables.json (12.4KB)
|
|
240
|
+
✓ vercel-com-theme.js (1.4KB)
|
|
241
|
+
✓ vercel-com-shadcn-theme.css (477B)
|
|
242
|
+
✓ screenshots/button.png
|
|
243
|
+
✓ screenshots/card.png
|
|
244
|
+
✓ screenshots/nav.png
|
|
245
|
+
✓ screenshots/hero.png
|
|
246
|
+
✓ screenshots/full-page.png
|
|
247
|
+
|
|
248
|
+
Summary:
|
|
249
|
+
Colors: 27 unique colors
|
|
250
|
+
Fonts: Geist, Geist Mono
|
|
251
|
+
Spacing: 18 values (base: 2px)
|
|
252
|
+
Shadows: 11 unique shadows
|
|
253
|
+
Radii: 10 unique values
|
|
254
|
+
Breakpoints: 45 breakpoints
|
|
255
|
+
Components: 11 types detected
|
|
256
|
+
CSS Vars: 407 custom properties
|
|
257
|
+
Layout: 55 grids, 492 flex containers
|
|
258
|
+
Responsive: 4 viewports, 3 breakpoint changes
|
|
259
|
+
Interactions: 8 state changes captured
|
|
260
|
+
A11y: 94% WCAG score (7 failing pairs)
|
|
261
|
+
Design Score: 68/100 (D) — 4 issues
|
|
157
262
|
```
|
|
158
263
|
|
|
159
264
|
## How It Works
|
|
160
265
|
|
|
161
|
-
1. **Crawl** — Launches headless Chromium via Playwright
|
|
162
|
-
2. **Extract** — `page.evaluate()` walks up to 5,000 DOM elements collecting computed
|
|
163
|
-
3. **Process** —
|
|
164
|
-
4. **Format** — 8 formatter modules generate
|
|
165
|
-
5. **Score** — Accessibility extractor calculates WCAG contrast ratios
|
|
166
|
-
6. **Capture** — Optional
|
|
266
|
+
1. **Crawl** — Launches headless Chromium via Playwright, waits for network idle and fonts
|
|
267
|
+
2. **Extract** — Single `page.evaluate()` walks up to 5,000 DOM elements collecting 25+ computed style properties including layout (grid, flex, container) data
|
|
268
|
+
3. **Process** — 12 extractor modules parse, deduplicate, cluster, and classify the raw data
|
|
269
|
+
4. **Format** — 8 formatter modules generate output files
|
|
270
|
+
5. **Score** — Accessibility extractor calculates WCAG contrast ratios for all color pairs
|
|
271
|
+
6. **Capture** — Optional: screenshots, responsive viewport crawling, interaction state recording
|
|
272
|
+
|
|
273
|
+
## Agent Skill
|
|
274
|
+
|
|
275
|
+
Works with **Claude Code, Cursor, Codex, and 40+ AI coding agents** via the skills ecosystem:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
npx skills add Manavarya09/design-extract
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
In Claude Code, use `/extract-design <url>`.
|
|
167
282
|
|
|
168
|
-
##
|
|
283
|
+
## Website
|
|
169
284
|
|
|
170
|
-
**
|
|
285
|
+
**[website-five-lime-65.vercel.app](https://website-five-lime-65.vercel.app)** — the brutalist product page.
|
|
171
286
|
|
|
172
287
|
## Contributing
|
|
173
288
|
|
package/bin/design-extract.js
CHANGED
|
@@ -19,6 +19,8 @@ import { captureResponsive } from '../src/extractors/responsive.js';
|
|
|
19
19
|
import { captureInteractions } from '../src/extractors/interactions.js';
|
|
20
20
|
import { syncDesign } from '../src/sync.js';
|
|
21
21
|
import { compareBrands, formatBrandMatrix, formatBrandMatrixHtml } from '../src/multibrand.js';
|
|
22
|
+
import { generateClone } from '../src/clone.js';
|
|
23
|
+
import { watchSite } from '../src/watch.js';
|
|
22
24
|
import { nameFromUrl } from '../src/utils.js';
|
|
23
25
|
|
|
24
26
|
const program = new Command();
|
|
@@ -26,7 +28,7 @@ const program = new Command();
|
|
|
26
28
|
program
|
|
27
29
|
.name('designlang')
|
|
28
30
|
.description('Extract the complete design language from any website')
|
|
29
|
-
.version('
|
|
31
|
+
.version('4.0.1');
|
|
30
32
|
|
|
31
33
|
// ── Main command: extract ──────────────────────────────────────
|
|
32
34
|
program
|
|
@@ -155,6 +157,11 @@ program
|
|
|
155
157
|
const total = ic.buttons.length + ic.links.length + ic.inputs.length;
|
|
156
158
|
console.log(` ${chalk.gray('Interactions:')} ${total} state changes captured`);
|
|
157
159
|
}
|
|
160
|
+
if (design.score) {
|
|
161
|
+
const s = design.score;
|
|
162
|
+
const gradeColor = s.grade === 'A' ? chalk.green : s.grade === 'B' ? chalk.cyan : s.grade === 'C' ? chalk.yellow : chalk.red;
|
|
163
|
+
console.log(` ${chalk.gray('Design Score:')} ${gradeColor(`${s.overall}/100 (${s.grade})`)}${s.issues.length > 0 ? ` — ${s.issues.length} issues` : ''}`);
|
|
164
|
+
}
|
|
158
165
|
|
|
159
166
|
// Accessibility summary
|
|
160
167
|
if (design.accessibility) {
|
|
@@ -338,4 +345,145 @@ program
|
|
|
338
345
|
}
|
|
339
346
|
});
|
|
340
347
|
|
|
348
|
+
// ── Clone command ───────────────────────────────────────────
|
|
349
|
+
program
|
|
350
|
+
.command('clone <url>')
|
|
351
|
+
.description('Generate a working Next.js starter from a site\'s design')
|
|
352
|
+
.option('-o, --out <dir>', 'output directory', './cloned-design')
|
|
353
|
+
.action(async (url, opts) => {
|
|
354
|
+
if (!url.startsWith('http')) url = `https://${url}`;
|
|
355
|
+
|
|
356
|
+
console.log('');
|
|
357
|
+
console.log(chalk.bold(' designlang clone'));
|
|
358
|
+
console.log(chalk.gray(` ${url}`));
|
|
359
|
+
console.log('');
|
|
360
|
+
|
|
361
|
+
const spinner = ora('Extracting design...').start();
|
|
362
|
+
|
|
363
|
+
try {
|
|
364
|
+
const design = await extractDesignLanguage(url);
|
|
365
|
+
spinner.text = 'Generating Next.js project...';
|
|
366
|
+
|
|
367
|
+
const result = generateClone(design, resolve(opts.out));
|
|
368
|
+
|
|
369
|
+
spinner.succeed('Clone generated!');
|
|
370
|
+
console.log('');
|
|
371
|
+
for (const f of result.files) {
|
|
372
|
+
console.log(` ${chalk.green('✓')} ${chalk.cyan(f)}`);
|
|
373
|
+
}
|
|
374
|
+
console.log('');
|
|
375
|
+
console.log(chalk.bold(' To run:'));
|
|
376
|
+
console.log(chalk.gray(` cd ${opts.out} && npm install && npm run dev`));
|
|
377
|
+
console.log('');
|
|
378
|
+
|
|
379
|
+
} catch (err) {
|
|
380
|
+
spinner.fail('Clone failed');
|
|
381
|
+
console.error(chalk.red(`\n ${err.message}\n`));
|
|
382
|
+
process.exit(1);
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
// ── Watch command ───────────────────────────────────────────
|
|
387
|
+
program
|
|
388
|
+
.command('watch <url>')
|
|
389
|
+
.description('Monitor a site for design changes')
|
|
390
|
+
.option('--interval <minutes>', 'check interval in minutes', parseInt, 60)
|
|
391
|
+
.action(async (url, opts) => {
|
|
392
|
+
if (!url.startsWith('http')) url = `https://${url}`;
|
|
393
|
+
const intervalMs = (opts.interval || 60) * 60 * 1000;
|
|
394
|
+
|
|
395
|
+
console.log('');
|
|
396
|
+
console.log(chalk.bold(' designlang watch'));
|
|
397
|
+
console.log(chalk.gray(` ${url} (every ${opts.interval || 60}min)`));
|
|
398
|
+
console.log('');
|
|
399
|
+
|
|
400
|
+
const check = async () => {
|
|
401
|
+
const spinner = ora('Checking for design changes...').start();
|
|
402
|
+
try {
|
|
403
|
+
const result = await watchSite(url);
|
|
404
|
+
|
|
405
|
+
if (result.isFirstRun) {
|
|
406
|
+
spinner.succeed('Baseline captured. Watching for changes...');
|
|
407
|
+
} else if (result.changes.length === 0) {
|
|
408
|
+
spinner.succeed(`No changes — ${new Date().toLocaleTimeString()}`);
|
|
409
|
+
} else {
|
|
410
|
+
spinner.warn(`${result.changes.length} changes detected!`);
|
|
411
|
+
for (const c of result.changes) {
|
|
412
|
+
console.log(` ${chalk.yellow('≠')} ${c.what}: ${c.from} → ${c.to}`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
} catch (err) {
|
|
416
|
+
spinner.fail(`Check failed: ${err.message}`);
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
await check();
|
|
421
|
+
console.log(chalk.gray(`\n Next check in ${opts.interval || 60} minutes. Press Ctrl+C to stop.\n`));
|
|
422
|
+
setInterval(check, intervalMs);
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
// ── Score command ───────────────────────────────────────────
|
|
426
|
+
program
|
|
427
|
+
.command('score <url>')
|
|
428
|
+
.description('Score a website\'s design system quality')
|
|
429
|
+
.action(async (url) => {
|
|
430
|
+
if (!url.startsWith('http')) url = `https://${url}`;
|
|
431
|
+
|
|
432
|
+
const spinner = ora('Analyzing design...').start();
|
|
433
|
+
|
|
434
|
+
try {
|
|
435
|
+
const design = await extractDesignLanguage(url);
|
|
436
|
+
const s = design.score;
|
|
437
|
+
|
|
438
|
+
spinner.stop();
|
|
439
|
+
console.log('');
|
|
440
|
+
console.log(chalk.bold(' Design System Score'));
|
|
441
|
+
console.log(chalk.gray(` ${url}`));
|
|
442
|
+
console.log('');
|
|
443
|
+
|
|
444
|
+
const gradeColor = s.grade === 'A' ? chalk.green : s.grade === 'B' ? chalk.cyan : s.grade === 'C' ? chalk.yellow : chalk.red;
|
|
445
|
+
console.log(` ${gradeColor.bold(` ${s.overall}/100 Grade: ${s.grade}`)}`);
|
|
446
|
+
console.log('');
|
|
447
|
+
|
|
448
|
+
// Category breakdown
|
|
449
|
+
const cats = [
|
|
450
|
+
['Color Discipline', s.scores.colorDiscipline],
|
|
451
|
+
['Typography', s.scores.typographyConsistency],
|
|
452
|
+
['Spacing System', s.scores.spacingSystem],
|
|
453
|
+
['Shadows', s.scores.shadowConsistency],
|
|
454
|
+
['Border Radii', s.scores.radiusConsistency],
|
|
455
|
+
['Accessibility', s.scores.accessibility],
|
|
456
|
+
['Tokenization', s.scores.tokenization],
|
|
457
|
+
];
|
|
458
|
+
|
|
459
|
+
for (const [name, score] of cats) {
|
|
460
|
+
const bar = '█'.repeat(Math.round(score / 5)) + '░'.repeat(20 - Math.round(score / 5));
|
|
461
|
+
const color = score >= 80 ? chalk.green : score >= 60 ? chalk.yellow : chalk.red;
|
|
462
|
+
console.log(` ${chalk.gray(name.padEnd(20))} ${color(bar)} ${score}`);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (s.strengths.length > 0) {
|
|
466
|
+
console.log('');
|
|
467
|
+
console.log(chalk.bold(' Strengths:'));
|
|
468
|
+
for (const str of s.strengths) {
|
|
469
|
+
console.log(` ${chalk.green('✓')} ${str}`);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (s.issues.length > 0) {
|
|
474
|
+
console.log('');
|
|
475
|
+
console.log(chalk.bold(' Issues:'));
|
|
476
|
+
for (const issue of s.issues) {
|
|
477
|
+
console.log(` ${chalk.yellow('!')} ${issue}`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
console.log('');
|
|
481
|
+
|
|
482
|
+
} catch (err) {
|
|
483
|
+
spinner.fail('Scoring failed');
|
|
484
|
+
console.error(chalk.red(`\n ${err.message}\n`));
|
|
485
|
+
process.exit(1);
|
|
486
|
+
}
|
|
487
|
+
});
|
|
488
|
+
|
|
341
489
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "designlang",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Extract the complete design language from any website — colors, typography, spacing, shadows, and more. Outputs AI-optimized markdown, W3C design tokens, Tailwind config, and CSS variables.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|