@mseep/dembrandt 0.19.5

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 (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +408 -0
  3. package/dist/index.d.ts +8 -0
  4. package/dist/index.js +532 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/browser.d.ts +16 -0
  7. package/dist/lib/browser.js +27 -0
  8. package/dist/lib/browser.js.map +1 -0
  9. package/dist/lib/colors.d.ts +101 -0
  10. package/dist/lib/colors.js +405 -0
  11. package/dist/lib/colors.js.map +1 -0
  12. package/dist/lib/compare.d.ts +31 -0
  13. package/dist/lib/compare.js +46 -0
  14. package/dist/lib/compare.js.map +1 -0
  15. package/dist/lib/discovery.d.ts +31 -0
  16. package/dist/lib/discovery.js +243 -0
  17. package/dist/lib/discovery.js.map +1 -0
  18. package/dist/lib/drift.d.ts +64 -0
  19. package/dist/lib/drift.js +383 -0
  20. package/dist/lib/drift.js.map +1 -0
  21. package/dist/lib/dtcg/validate.d.ts +51 -0
  22. package/dist/lib/dtcg/validate.js +1403 -0
  23. package/dist/lib/dtcg/validate.js.map +1 -0
  24. package/dist/lib/exit-codes.d.ts +29 -0
  25. package/dist/lib/exit-codes.js +26 -0
  26. package/dist/lib/exit-codes.js.map +1 -0
  27. package/dist/lib/extractors/breakpoints.d.ts +5 -0
  28. package/dist/lib/extractors/breakpoints.js +450 -0
  29. package/dist/lib/extractors/breakpoints.js.map +1 -0
  30. package/dist/lib/extractors/colors.d.ts +2 -0
  31. package/dist/lib/extractors/colors.js +657 -0
  32. package/dist/lib/extractors/colors.js.map +1 -0
  33. package/dist/lib/extractors/components.d.ts +4 -0
  34. package/dist/lib/extractors/components.js +370 -0
  35. package/dist/lib/extractors/components.js.map +1 -0
  36. package/dist/lib/extractors/index.d.ts +9 -0
  37. package/dist/lib/extractors/index.js +1257 -0
  38. package/dist/lib/extractors/index.js.map +1 -0
  39. package/dist/lib/extractors/logo.d.ts +2 -0
  40. package/dist/lib/extractors/logo.js +626 -0
  41. package/dist/lib/extractors/logo.js.map +1 -0
  42. package/dist/lib/extractors/spacing.d.ts +4 -0
  43. package/dist/lib/extractors/spacing.js +163 -0
  44. package/dist/lib/extractors/spacing.js.map +1 -0
  45. package/dist/lib/extractors/teach.d.ts +1 -0
  46. package/dist/lib/extractors/teach.js +66 -0
  47. package/dist/lib/extractors/teach.js.map +1 -0
  48. package/dist/lib/extractors/typography.d.ts +1 -0
  49. package/dist/lib/extractors/typography.js +163 -0
  50. package/dist/lib/extractors/typography.js.map +1 -0
  51. package/dist/lib/findings.d.ts +34 -0
  52. package/dist/lib/findings.js +166 -0
  53. package/dist/lib/findings.js.map +1 -0
  54. package/dist/lib/formatters/dtcg.d.ts +10 -0
  55. package/dist/lib/formatters/dtcg.js +416 -0
  56. package/dist/lib/formatters/dtcg.js.map +1 -0
  57. package/dist/lib/formatters/html.d.ts +25 -0
  58. package/dist/lib/formatters/html.js +479 -0
  59. package/dist/lib/formatters/html.js.map +1 -0
  60. package/dist/lib/formatters/markdown.d.ts +5 -0
  61. package/dist/lib/formatters/markdown.js +568 -0
  62. package/dist/lib/formatters/markdown.js.map +1 -0
  63. package/dist/lib/formatters/pdf.d.ts +12 -0
  64. package/dist/lib/formatters/pdf.js +1121 -0
  65. package/dist/lib/formatters/pdf.js.map +1 -0
  66. package/dist/lib/formatters/terminal.d.ts +6 -0
  67. package/dist/lib/formatters/terminal.js +954 -0
  68. package/dist/lib/formatters/terminal.js.map +1 -0
  69. package/dist/lib/formatters/theme.d.ts +35 -0
  70. package/dist/lib/formatters/theme.js +37 -0
  71. package/dist/lib/formatters/theme.js.map +1 -0
  72. package/dist/lib/merger.d.ts +14 -0
  73. package/dist/lib/merger.js +362 -0
  74. package/dist/lib/merger.js.map +1 -0
  75. package/dist/lib/normalize.d.ts +29 -0
  76. package/dist/lib/normalize.js +59 -0
  77. package/dist/lib/normalize.js.map +1 -0
  78. package/dist/lib/robots.d.ts +12 -0
  79. package/dist/lib/robots.js +110 -0
  80. package/dist/lib/robots.js.map +1 -0
  81. package/dist/lib/run-summary.d.ts +40 -0
  82. package/dist/lib/run-summary.js +64 -0
  83. package/dist/lib/run-summary.js.map +1 -0
  84. package/dist/lib/types.d.ts +329 -0
  85. package/dist/lib/types.js +7 -0
  86. package/dist/lib/types.js.map +1 -0
  87. package/dist/lib/version.d.ts +134 -0
  88. package/dist/lib/version.js +153 -0
  89. package/dist/lib/version.js.map +1 -0
  90. package/dist/mcp-server.d.ts +11 -0
  91. package/dist/mcp-server.js +311 -0
  92. package/dist/mcp-server.js.map +1 -0
  93. package/dist/package.json +106 -0
  94. package/dist/test/_vitest-shim.d.ts +13 -0
  95. package/dist/test/_vitest-shim.js +23 -0
  96. package/dist/test/_vitest-shim.js.map +1 -0
  97. package/dist/test/cli.test.d.ts +1 -0
  98. package/dist/test/cli.test.js +24 -0
  99. package/dist/test/cli.test.js.map +1 -0
  100. package/dist/test/colors.test.d.ts +1 -0
  101. package/dist/test/colors.test.js +64 -0
  102. package/dist/test/colors.test.js.map +1 -0
  103. package/dist/test/compare.test.d.ts +1 -0
  104. package/dist/test/compare.test.js +57 -0
  105. package/dist/test/compare.test.js.map +1 -0
  106. package/dist/test/drift.test.d.ts +1 -0
  107. package/dist/test/drift.test.js +53 -0
  108. package/dist/test/drift.test.js.map +1 -0
  109. package/dist/test/dtcg-formatter.test.d.ts +1 -0
  110. package/dist/test/dtcg-formatter.test.js +48 -0
  111. package/dist/test/dtcg-formatter.test.js.map +1 -0
  112. package/dist/test/dtcg-validate.test.d.ts +1 -0
  113. package/dist/test/dtcg-validate.test.js +2129 -0
  114. package/dist/test/dtcg-validate.test.js.map +1 -0
  115. package/dist/test/exit-codes.test.d.ts +1 -0
  116. package/dist/test/exit-codes.test.js +53 -0
  117. package/dist/test/exit-codes.test.js.map +1 -0
  118. package/dist/test/findings.test.d.ts +1 -0
  119. package/dist/test/findings.test.js +77 -0
  120. package/dist/test/findings.test.js.map +1 -0
  121. package/dist/test/html.test.d.ts +1 -0
  122. package/dist/test/html.test.js +95 -0
  123. package/dist/test/html.test.js.map +1 -0
  124. package/dist/test/markdown.test.d.ts +1 -0
  125. package/dist/test/markdown.test.js +145 -0
  126. package/dist/test/markdown.test.js.map +1 -0
  127. package/dist/test/merger.test.d.ts +1 -0
  128. package/dist/test/merger.test.js +98 -0
  129. package/dist/test/merger.test.js.map +1 -0
  130. package/dist/test/normalize.test.d.ts +1 -0
  131. package/dist/test/normalize.test.js +47 -0
  132. package/dist/test/normalize.test.js.map +1 -0
  133. package/dist/test/run-summary.test.d.ts +1 -0
  134. package/dist/test/run-summary.test.js +45 -0
  135. package/dist/test/run-summary.test.js.map +1 -0
  136. package/dist/test/version.test.d.ts +1 -0
  137. package/dist/test/version.test.js +73 -0
  138. package/dist/test/version.test.js.map +1 -0
  139. package/package.json +106 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 thevangelist
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,408 @@
1
+ # Dembrandt.
2
+
3
+ [![npm version](https://img.shields.io/npm/v/dembrandt.svg)](https://www.npmjs.com/package/dembrandt)
4
+ [![npm downloads](https://img.shields.io/npm/dm/dembrandt.svg)](https://www.npmjs.com/package/dembrandt)
5
+ [![license](https://img.shields.io/npm/l/dembrandt.svg)](https://github.com/dembrandt/dembrandt/blob/main/LICENSE)
6
+ [![GitHub Sponsors](https://img.shields.io/badge/Sponsor-me-pink?style=flat&logo=github-sponsors)](https://github.com/sponsors/dembrandt)
7
+
8
+ Extract a website's design system into design tokens in a few seconds: logo, colors, typography, borders, and more. One command.
9
+
10
+ ![Dembrandt: Any website to design tokens](https://raw.githubusercontent.com/dembrandt/dembrandt/main/docs/images/banner.png)
11
+
12
+ ## Install
13
+
14
+ Install globally: `npm install -g dembrandt`
15
+
16
+ ```bash
17
+ dembrandt example.com
18
+ ```
19
+
20
+ Or use npx without installing: `npx dembrandt example.com`
21
+
22
+ Requires Node.js 18+
23
+
24
+ ## AI Agent Integration (MCP)
25
+
26
+ Use Dembrandt as a tool in Claude Code, Cursor, Windsurf, or any MCP-compatible client. Ask your agent to "extract the color palette from example.com" and it calls Dembrandt automatically.
27
+
28
+ ```bash
29
+ claude mcp add --transport stdio dembrandt -- npx -y --package dembrandt dembrandt-mcp
30
+ ```
31
+
32
+ Or add to your project's `.mcp.json`:
33
+
34
+ ```json
35
+ {
36
+ "mcpServers": {
37
+ "dembrandt": {
38
+ "command": "npx",
39
+ "args": ["-y", "--package", "dembrandt", "dembrandt-mcp"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ Available tools include `get_design_tokens`, `get_color_palette`, `get_typography`, `get_component_styles`, `get_surfaces`, `get_spacing`, and `get_brand_identity`, plus drift, report, and job-control tools.
46
+
47
+ Pair with **[dembrandt-skills](https://github.com/dembrandt/dembrandt-skills)** to give your agent UX intelligence on top of extracted tokens — hierarchy, accessibility, interaction states, and a full 6-stage design pipeline orchestrator.
48
+
49
+ ```bash
50
+ npx skills add dembrandt/dembrandt-skills
51
+ ```
52
+
53
+ ## Dembrandt App (Beta)
54
+
55
+ Load extractions, track token drift, and compare snapshots. **[dembrandt.com/app](https://www.dembrandt.com/app)**
56
+
57
+ * **Drift tracking.** Pin a snapshot as your baseline. Run another extraction later. Get a visual report of what changed.
58
+ * **Visual diff.** Color swatches, before/after values, delta scores per category.
59
+ * **Snapshot history.** GitHub-style calendar per domain.
60
+ * **Copy tokens.** Paste values straight into Copilot, Claude, or Cursor.
61
+ * **No login.** Your data stays in the browser. Drift is computed locally — nothing is sent to any server.
62
+
63
+ ## Recipes
64
+
65
+ **[dembrandt.com/recipes](https://www.dembrandt.com/recipes)** — ready-to-run workflows. Copy a command, paste a prompt, get a result. Covers competitor benchmarking, WCAG audits, CI/CD drift detection, Figma token push, and agentic design system builds. Filterable by role.
66
+
67
+ ## What to expect from extraction?
68
+
69
+ - Colors (semantic, palette, CSS variables, gradients)
70
+ - Typography (fonts, sizes, weights, sources)
71
+ - Spacing (margin/padding scales)
72
+ - Borders (radius, widths, styles, colors)
73
+ - Shadows
74
+ - Motion (duration scale, easing curves, hover patterns per component type)
75
+ - Components (buttons, badges, inputs, links)
76
+ - Breakpoints
77
+ - Icons & frameworks
78
+
79
+ ## Usage
80
+
81
+ ```bash
82
+ dembrandt <url> # Basic extraction (terminal display only)
83
+ dembrandt example.com --json-only # Output raw JSON to terminal (no formatted display, no file save)
84
+ dembrandt example.com --save-output # Save JSON to output/example.com/YYYY-MM-DDTHH-MM-SS.json
85
+ dembrandt example.com --dtcg # Export in W3C Design Tokens (DTCG) format (auto-saves as .tokens.json)
86
+ dembrandt example.com --dark-mode # Extract colors from dark mode variant
87
+ dembrandt example.com --mobile # Use mobile viewport (390x844) for responsive analysis
88
+ dembrandt example.com --slow # 3x longer timeouts (24s hydration) for JavaScript-heavy sites
89
+ dembrandt example.com --brand-guide # Generate a brand guide PDF
90
+ dembrandt example.com --design-md # Generate a DESIGN.md file for AI agents
91
+ dembrandt example.com /pricing /docs # Extract specific paths and merge results into one output
92
+ dembrandt example.com --crawl 5 # Analyze 5 pages (homepage + 4 discovered pages), merges results
93
+ dembrandt example.com --sitemap # Discover pages from sitemap.xml instead of DOM links
94
+ dembrandt example.com --crawl 10 --sitemap # Combine: up to 10 pages discovered via sitemap
95
+ dembrandt example.com --no-sandbox # Disable Chromium sandbox (required for Docker/CI)
96
+ dembrandt example.com --browser=firefox # Use Firefox instead of Chromium (better for Cloudflare bypass)
97
+ dembrandt example.com --wcag # WCAG 2.1 contrast analysis — real DOM pairs, AA/AAA grades
98
+ dembrandt example.com --stealth # Opt-in anti-detection: navigator spoofing + human mouse simulation (use only when authorized)
99
+ dembrandt example.com --locale fi-FI --timezone Europe/Helsinki # Browser fingerprint: locale and timezone
100
+ dembrandt example.com --user-agent "Mozilla/5.0 ..." # Custom user agent string
101
+ dembrandt example.com --accept-language "fi,en;q=0.9" # Custom Accept-Language header
102
+ dembrandt example.com --screen-size 2560x1440 # Physical screen resolution to report
103
+ ```
104
+
105
+ Default: formatted terminal display only. Use `--save-output` to persist results as JSON files. Browser automatically retries in visible mode if headless extraction fails.
106
+
107
+ ### Multi-Page Extraction
108
+
109
+ Analyze multiple pages to get a more complete picture of a site's design system. Results are merged into a single unified output with cross-page confidence boosting: tokens appearing on multiple pages get higher confidence scores.
110
+
111
+ ```bash
112
+ # Analyze homepage + 4 auto-discovered pages (default: 5 total)
113
+ dembrandt example.com --crawl 5
114
+
115
+ # Use sitemap.xml for page discovery instead of DOM link scraping
116
+ dembrandt example.com --sitemap
117
+
118
+ # Combine both: up to 10 pages from sitemap
119
+ dembrandt example.com --crawl 10 --sitemap
120
+ ```
121
+
122
+ **Page discovery** works two ways:
123
+ - **DOM links** (default): Reads navigation, header, and footer links from the homepage, prioritizing key pages like /pricing, /about, /features
124
+ - **Sitemap** (`--sitemap`): Parses sitemap.xml (checks robots.txt first), follows sitemapindex references, and scores URLs by importance
125
+
126
+ Pages are fetched sequentially with polite delays. Failed pages are skipped without aborting the run.
127
+
128
+ ### Browser Selection
129
+
130
+ By default, dembrandt uses Chromium. If you encounter bot detection or timeouts (especially on sites behind Cloudflare), try Firefox which is often more successful at bypassing these protections:
131
+
132
+ ```bash
133
+ # Use Firefox instead of Chromium
134
+ dembrandt example.com --browser=firefox
135
+
136
+ # Combine with other flags
137
+ dembrandt example.com --browser=firefox --save-output --dtcg
138
+ ```
139
+
140
+ **When to use Firefox:**
141
+ - Sites behind Cloudflare or other bot detection systems
142
+ - Timeout issues on heavily protected sites
143
+ - WSL environments where headless Chromium may struggle
144
+
145
+ **Installation:**
146
+ Browsers are installed on demand, not by `npm install` (dembrandt depends on the lean `playwright-core`, which carries no browser binaries). Fetch the engine you need, matched to the installed `playwright-core`:
147
+
148
+ ```bash
149
+ npm run install-browser # chromium (default)
150
+ # or a specific engine:
151
+ npx playwright@$(node -p "require('playwright-core/package.json').version") install firefox
152
+ ```
153
+
154
+ ### Connect to an existing browser (CDP)
155
+
156
+ Skip the bundled browser entirely and drive an already-running Chromium over the DevTools Protocol. Useful in CI or containers where a browser is already up, and it needs no local browser download at all:
157
+
158
+ ```bash
159
+ BROWSER_CDP_ENDPOINT=http://localhost:9222 dembrandt example.com --browser chromium
160
+ ```
161
+
162
+ CDP is supported only with `--browser chromium`.
163
+
164
+ ### W3C Design Tokens (DTCG) Format
165
+
166
+ Use `--dtcg` to export in the standardized [W3C Design Tokens Community Group](https://www.designtokens.org/) format:
167
+
168
+ ```bash
169
+ dembrandt example.com --dtcg
170
+ # Saves to: output/example.com/TIMESTAMP.tokens.json
171
+ ```
172
+
173
+ The DTCG format is an industry-standard JSON schema that can be consumed by design tools and token transformation libraries like [Style Dictionary](https://styledictionary.com).
174
+
175
+ ### DESIGN.md
176
+
177
+ Use `--design-md` to generate a [DESIGN.md](https://stitch.withgoogle.com/docs/design-md) file, a plain-text design system document readable by AI agents. The export follows Google's DESIGN.md draft format: YAML design tokens in front matter plus ordered Markdown guidance sections.
178
+
179
+ ```bash
180
+ dembrandt example.com --design-md
181
+ # Saves to: output/example.com/DESIGN.md
182
+ ```
183
+
184
+ DESIGN.md reports only what Dembrandt observed on the source site. Exact values (colors, typography, spacing, radii, shadows) live in the YAML front matter when available, and the Markdown body adds human-readable context. Sections with no extracted evidence are omitted rather than filled with invented defaults. For example, the elevation section is dropped when the site uses no box-shadow tokens.
185
+
186
+ ### WCAG Contrast Analysis
187
+
188
+ Use `--wcag` to check accessibility contrast ratios across the page. Unlike palette-based checkers, dembrandt walks the actual DOM and finds what color is rendered on top of what background — per element.
189
+
190
+ ```bash
191
+ dembrandt dembrandt.com --wcag
192
+ ```
193
+
194
+ Returns every text/background pair with contrast ratio and WCAG 2.1 grade (AA, AA-Large, AAA, or fail), sorted by how often each pair appears. Results are shown in terminal and included in JSON output as `wcag`.
195
+
196
+ Also captures **interactive state contrast**: dembrandt simulates hover, focus, and disabled states on buttons, links, and inputs and checks contrast on each state. State pairs are tagged `[hover]`, `[focus]`, or `[disabled]` in output so you can catch contrast failures that only appear on interaction.
197
+
198
+ ### Motion Tokens
199
+
200
+ Motion tokens are extracted automatically on every run — no flag needed. Dembrandt analyzes CSS transitions and animations across the page and returns a structured motion profile.
201
+
202
+ ```bash
203
+ dembrandt dembrandt.com
204
+ ```
205
+
206
+ Returns:
207
+ - **Duration scale**: all unique animation durations found on the page
208
+ - **Easing curves**: named easing types (ease-out, spring, custom cubic-bezier) with usage counts
209
+ - **Per-context profiles**: motion behavior by component type (button, nav, card, modal, hero)
210
+ - **Hover interaction deltas**: which properties animate on hover (transform, opacity, background, color) and the pattern (scale-up, fade-in, color-shift, slide-y)
211
+
212
+ Motion data is included in JSON output as `motion` and printed in terminal under a dedicated Motion section.
213
+
214
+ ### Brand Guide PDF
215
+
216
+ Use `--brand-guide` to generate a printable PDF summarizing the extracted design system: colors, typography, components, and logo on a single document.
217
+
218
+ ```bash
219
+ dembrandt example.com --brand-guide
220
+ # Saves to: output/example.com/TIMESTAMP.brand-guide.pdf
221
+ ```
222
+
223
+ ## Continuous integration
224
+
225
+ Dembrandt drives a real browser, so the browser revision must match `playwright-core`.
226
+
227
+ If you are not using the Playwright container image, install the browser revision that matches `playwright-core`:
228
+
229
+ ```bash
230
+ # in dembrandt's own repo
231
+ npm run install-browser
232
+ # elsewhere — derive the version so it always matches
233
+ npx playwright@$(node -p "require('playwright-core/package.json').version") install --with-deps chromium
234
+ ```
235
+
236
+ A mismatched version fails with "Executable doesn't exist". The container image avoids this entirely — just match its tag (`v1.60.0`) to the `playwright-core` version.
237
+
238
+ ### Drift gate
239
+
240
+ Compare an extraction against a committed baseline and fail the job on drift:
241
+
242
+ ```bash
243
+ # capture a baseline once (same environment you will check against)
244
+ dembrandt https://app.example.com --json-only > baseline.json
245
+
246
+ # in CI — exits non-zero on drift; writes a report artifact
247
+ dembrandt https://app.example.com --compare baseline.json --html report.html
248
+ ```
249
+
250
+ When the change is intended, accept it as the new baseline — `--approve` overwrites the local baseline file and passes instead of failing:
251
+
252
+ ```bash
253
+ dembrandt https://app.example.com --compare baseline.json --approve
254
+ ```
255
+
256
+ Add `--json-only` to a `--compare` run to get the drift report as machine-readable JSON under a `drift` key — `score`, `status`, `summary`, and per-token `changes[]` (each with `category`, `kind`, `before`, `after`, `delta`). A CI gate can render exactly which tokens moved (e.g. in a PR comment) from this instead of parsing the HTML report:
257
+
258
+ ```bash
259
+ dembrandt https://app.example.com --compare baseline.json --json-only
260
+ ```
261
+
262
+ **Any CI.** The gate is platform-neutral — it is just the exit code plus the drift JSON, so it drops into any runner:
263
+
264
+ ```bash
265
+ dembrandt "$PREVIEW/checkout" --compare base.json --json-only > drift.json
266
+ # exit 1 = drift. Read drift.json (.drift.changes) and surface it however your
267
+ # platform does: a GitLab MR note, an Azure DevOps PR thread, a Jenkins status,
268
+ # a Slack message, or an auto-filed Jira/Linear ticket.
269
+ ```
270
+
271
+ A ready-to-use **GitHub Actions** workflow (preview vs production, per-page PR comment with the exact tokens that changed, run summary, report artifact, host-auth bypass) is in [`examples/drift-gate.yml`](examples/drift-gate.yml) as one full reference. The result-surfacing step (annotations, PR comment) is the only platform-specific part; the extract → compare → branch-on-exit-code core is identical on GitLab CI, Jenkins, and Azure DevOps.
272
+
273
+ ### Exit codes
274
+
275
+ A pipeline can branch on the exit code; "design drifted" and "extraction broke" are distinct:
276
+
277
+ | Code | Meaning |
278
+ |---|---|
279
+ | `0` | Success, or stable (no drift) under `--compare` |
280
+ | `1` | Drift detected (`--compare`) |
281
+ | `2` | Extraction failure (`EXTRACTION_FAILED`, `BROWSER_UNAVAILABLE`) |
282
+ | `67` | Navigation/connection timeout (`NAVIGATION_TIMEOUT`) — retryable, try `--slow` |
283
+
284
+ With `--json-only`, a failure also prints a machine-readable `{ "error": { "code", "message" } }` to stdout.
285
+
286
+ ## Recipes
287
+
288
+ **Quick brand scan**
289
+ ```bash
290
+ dembrandt dembrandt.com
291
+ ```
292
+
293
+ **Compare two sites**
294
+ ```bash
295
+ dembrandt dembrandt.com --save-output
296
+ dembrandt braintree.com --save-output
297
+ # Compare output/dembrandt.com and output/braintree.com side by side
298
+ ```
299
+
300
+ **Multi-page audit** — get a fuller picture across the whole site
301
+ ```bash
302
+ dembrandt dembrandt.com --crawl 10 --sitemap --save-output
303
+ ```
304
+
305
+ **Spot-check a value** — verify a specific token fast
306
+ ```bash
307
+ dembrandt dembrandt.com --json-only | grep -i "border-radius"
308
+ ```
309
+
310
+ **Export for Tailwind** — get spacing and color values into your config
311
+ ```bash
312
+ dembrandt dembrandt.com --dtcg --save-output
313
+ # Use the .tokens.json with Style Dictionary to generate tailwind.config.js
314
+ ```
315
+
316
+ **Export for Tokens Studio / Figma**
317
+ ```bash
318
+ dembrandt dembrandt.com --dtcg --save-output
319
+ # Import the .tokens.json directly into Tokens Studio
320
+ ```
321
+
322
+ **Generate DESIGN.md for your AI agent**
323
+ ```bash
324
+ dembrandt dembrandt.com --design-md
325
+ # Point your agent at the output DESIGN.md
326
+ ```
327
+
328
+ **Accessibility audit** — check contrast on any live URL
329
+ ```bash
330
+ dembrandt dembrandt.com --wcag
331
+ ```
332
+
333
+ **Regression baseline** — snapshot now, catch drift later
334
+ ```bash
335
+ dembrandt myapp.com --save-output --dtcg
336
+ # Store output as baseline, re-run after deploys and diff
337
+ ```
338
+
339
+ **CI / headless environments**
340
+ ```bash
341
+ dembrandt myapp.com --no-sandbox --save-output
342
+ ```
343
+
344
+ ## Use Cases
345
+
346
+ - Design system documentation
347
+ - Multi-site design consolidation
348
+ - Internal design audits on your own properties
349
+ - Learning how design tokens map to real CSS
350
+
351
+ ## How It Works
352
+
353
+ Uses Playwright to render the page, reads computed styles from the DOM, analyzes color usage and confidence, groups similar typography, detects spacing patterns, and returns design tokens.
354
+
355
+ ### Extraction Process
356
+
357
+ 1. Browser Launch - Launches browser (Chromium by default, Firefox optional) with stealth configuration
358
+ 2. Anti-Detection - Injects scripts to bypass bot detection
359
+ 3. Navigation - Navigates to target URL with retry logic
360
+ 4. Hydration - Waits for SPAs to fully load (8s initial + 4s stabilization)
361
+ 5. Content Validation - Verifies page content is substantial (>500 chars)
362
+ 6. Parallel Extraction - Runs all extractors concurrently for speed
363
+ 7. Analysis - Analyzes computed styles, DOM structure, and CSS variables
364
+ 8. Scoring - Assigns confidence scores based on context and usage
365
+
366
+ ### Color Confidence
367
+
368
+ - High: Logo, primary interactive elements
369
+ - Medium: Secondary interactive elements, icons, navigation
370
+ - Low: Generic UI components (filtered from display)
371
+ - Only shows high and medium confidence colors in terminal. Full palette in JSON.
372
+
373
+ ## Limitations
374
+
375
+ - Dark mode requires `--dark-mode` flag (not automatically detected)
376
+ - Hover/focus states extracted from CSS (not fully interactive)
377
+ - Canvas/WebGL-rendered sites cannot be analyzed (no DOM to read)
378
+ - JavaScript-heavy sites require hydration time (8s initial + 4s stabilization)
379
+ - Some dynamically-loaded content may be missed
380
+ - Default viewport is 1920x1080 (use `--mobile` for 390x844 mobile viewport)
381
+
382
+ ## Intended Use
383
+
384
+ Dembrandt reads publicly available CSS and computed styles from website DOMs for documentation, learning, and analysis of design systems you own or have permission to analyze.
385
+
386
+ Only run Dembrandt against sites whose Terms of Service permit automated access, or against your own properties. Do not use extracted material to reproduce third-party brand identities, logos, or trademarks. Respect robots.txt, rate limits, and copyright.
387
+
388
+ Dembrandt does not host, redistribute, or claim rights to any third-party brand assets.
389
+
390
+ ## Sponsors
391
+
392
+ The CLI is MIT-licensed and free. Sponsorship funds the enforcement layer: a committed project-level token baseline, `--compare` and the ingest API for CI/CD drift gates, and the App platform (snapshot history, team drift dashboard, alerts to Slack, Linear, and GitHub).
393
+
394
+ [![GitHub Sponsors](https://img.shields.io/badge/Sponsor-me-pink?style=flat&logo=github-sponsors)](https://github.com/sponsors/dembrandt)
395
+
396
+ <!-- sponsors -->
397
+ <!-- Backer ($25+) and Lead sponsor ($500+) logos appear here. -->
398
+ <!-- sponsors -->
399
+
400
+ ## Contributing
401
+
402
+ Bugs, weird sites, pull requests. All welcome.
403
+
404
+ Open an [Issue](https://github.com/dembrandt/dembrandt/issues) or PR.
405
+
406
+ @thevangelist
407
+
408
+ MIT. Do whatever you want with it.
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Dembrandt - Design Token Extraction CLI
4
+ *
5
+ * Extracts design tokens, brand colors, typography, spacing, and component styles
6
+ * from any website using Playwright.
7
+ */
8
+ export {};