dembrandt 0.1.0 → 0.2.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/README.md +33 -5
- package/index.js +9 -6
- package/lib/display.js +410 -213
- package/lib/extractors.js +626 -69
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
A CLI tool for extracting design tokens and brand assets from any website. Powered by Playwright with advanced bot detection avoidance.
|
|
8
8
|
|
|
9
|
-

|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
@@ -21,13 +21,15 @@ No installation required! Extract design tokens from any website in seconds. Or
|
|
|
21
21
|
Dembrandt analyzes live websites and extracts their complete design system:
|
|
22
22
|
|
|
23
23
|
- **Logo** — Logo detection (img/svg) with dimensions and source URL
|
|
24
|
-
- **
|
|
24
|
+
- **Favicons** — All favicon variants with sizes and types
|
|
25
|
+
- **Colors** — Semantic colors, color palette with confidence scoring, CSS variables (both hex and RGB formats)
|
|
25
26
|
- **Typography** — Font families, sizes, weights, line heights, font sources (Google Fonts, Adobe Fonts, custom)
|
|
26
27
|
- **Spacing** — Margin and padding scales with grid system detection (4px/8px/custom)
|
|
27
28
|
- **Border Radius** — Corner radius patterns with usage frequency
|
|
28
29
|
- **Shadows** — Box shadow values for elevation systems
|
|
29
30
|
- **Buttons** — Component styles with variants and states
|
|
30
31
|
- **Inputs** — Form field styles (input, textarea, select)
|
|
32
|
+
- **Links** — Link styles with hover states and decorations
|
|
31
33
|
- **Breakpoints** — Responsive design breakpoints from media queries
|
|
32
34
|
- **Icons** — Icon system detection (Font Awesome, Material Icons, SVG)
|
|
33
35
|
- **Frameworks** — CSS framework detection (Tailwind, Bootstrap, Material-UI, Chakra)
|
|
@@ -148,6 +150,30 @@ dembrandt stripe.com --debug
|
|
|
148
150
|
|
|
149
151
|
Useful for troubleshooting bot detection, timeouts, or extraction issues.
|
|
150
152
|
|
|
153
|
+
**`--verbose-colors`** - Show medium and low confidence colors in terminal output
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
dembrandt stripe.com --verbose-colors
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
By default, only high-confidence colors are shown. Use this flag to see all detected colors.
|
|
160
|
+
|
|
161
|
+
**`--dark-mode`** - Extract colors from dark mode
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
dembrandt stripe.com --dark-mode
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Enables dark mode preference detection for sites that support it.
|
|
168
|
+
|
|
169
|
+
**`--mobile`** - Extract from mobile viewport
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
dembrandt stripe.com --mobile
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Simulates a mobile device viewport for responsive design token extraction.
|
|
176
|
+
|
|
151
177
|
## Output
|
|
152
178
|
|
|
153
179
|
### Automatic JSON Saves
|
|
@@ -324,12 +350,12 @@ Use `--debug` to see:
|
|
|
324
350
|
|
|
325
351
|
## Limitations
|
|
326
352
|
|
|
327
|
-
-
|
|
353
|
+
- Dark mode requires `--dark-mode` flag (not automatically detected)
|
|
328
354
|
- Hover/focus states extracted from CSS (not fully interactive)
|
|
329
355
|
- Canvas/WebGL-rendered sites cannot be analyzed (e.g., Tesla, Apple Vision Pro demos)
|
|
330
356
|
- JavaScript-heavy sites require hydration time (8s initial + 4s stabilization)
|
|
331
357
|
- Some dynamically-loaded content may be missed
|
|
332
|
-
-
|
|
358
|
+
- Default viewport is 1920x1080 (use `--mobile` for responsive analysis)
|
|
333
359
|
|
|
334
360
|
## Architecture
|
|
335
361
|
|
|
@@ -371,7 +397,9 @@ MIT
|
|
|
371
397
|
|
|
372
398
|
## Roadmap
|
|
373
399
|
|
|
374
|
-
- [
|
|
400
|
+
- [x] Dark mode extraction (via `--dark-mode` flag)
|
|
401
|
+
- [x] Mobile viewport support (via `--mobile` flag)
|
|
402
|
+
- [x] Clickable terminal links for modern terminals
|
|
375
403
|
- [ ] Animation/transition detection
|
|
376
404
|
- [ ] Interactive state capture (hover, focus, active)
|
|
377
405
|
- [ ] Multi-page analysis
|
package/index.js
CHANGED
|
@@ -14,10 +14,7 @@ import { chromium } from "playwright";
|
|
|
14
14
|
import { extractBranding } from "./lib/extractors.js";
|
|
15
15
|
import { displayResults } from "./lib/display.js";
|
|
16
16
|
import { writeFileSync, mkdirSync } from "fs";
|
|
17
|
-
import { join
|
|
18
|
-
import { fileURLToPath } from "url";
|
|
19
|
-
|
|
20
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
import { join } from "path";
|
|
21
18
|
|
|
22
19
|
program
|
|
23
20
|
.name("dembrandt")
|
|
@@ -26,6 +23,9 @@ program
|
|
|
26
23
|
.argument("<url>")
|
|
27
24
|
.option("--json-only", "Output raw JSON")
|
|
28
25
|
.option("-d, --debug", "Force visible browser")
|
|
26
|
+
.option("--verbose-colors", "Show medium and low confidence colors")
|
|
27
|
+
.option("--dark-mode", "Extract colors from dark mode")
|
|
28
|
+
.option("--mobile", "Extract from mobile viewport")
|
|
29
29
|
.action(async (input, opts) => {
|
|
30
30
|
let url = input;
|
|
31
31
|
if (!url.match(/^https?:\/\//)) url = "https://" + url;
|
|
@@ -62,6 +62,8 @@ program
|
|
|
62
62
|
try {
|
|
63
63
|
result = await extractBranding(url, spinner, browser, {
|
|
64
64
|
navigationTimeout: 90000,
|
|
65
|
+
darkMode: opts.darkMode,
|
|
66
|
+
mobile: opts.mobile,
|
|
65
67
|
});
|
|
66
68
|
break;
|
|
67
69
|
} catch (err) {
|
|
@@ -97,7 +99,8 @@ program
|
|
|
97
99
|
.toISOString()
|
|
98
100
|
.replace(/[:.]/g, "-")
|
|
99
101
|
.split(".")[0];
|
|
100
|
-
|
|
102
|
+
// Save to current working directory, not installation directory
|
|
103
|
+
const outputDir = join(process.cwd(), "output", domain);
|
|
101
104
|
mkdirSync(outputDir, { recursive: true });
|
|
102
105
|
|
|
103
106
|
const filename = `${timestamp}.json`;
|
|
@@ -122,7 +125,7 @@ program
|
|
|
122
125
|
if (opts.jsonOnly) {
|
|
123
126
|
console.log(JSON.stringify(result, null, 2));
|
|
124
127
|
} else {
|
|
125
|
-
displayResults(result);
|
|
128
|
+
displayResults(result, { verboseColors: opts.verboseColors });
|
|
126
129
|
}
|
|
127
130
|
} catch (err) {
|
|
128
131
|
spinner.fail("Failed");
|