extract-design について
Dembrandtは、ヘッドレスChromiumでWebサイトから構造化されたデザインシステム情報を抽出するCLI兼MCPサーバーです。デザイナーや開発者は複数ページのトークンを調べ、分析結果を確認し、TailwindやDTCGなどの形式で出力できます。
主な機能
- 01Webページからスタイルを抽出
- 02色、タイポグラフィ、余白を分析
- 03複数ページをクロールして統合
- 04デザインシステムの問題や差分を確認
- 05DTCG、Tailwind、shadcnテーマを出力
- 06レポートやブランドガイドを生成
活用シーン
- 01Webサイトのデザインシステムを文書化
- 02候補サイトと基準データを比較
- 03観測したトークンをテーマとして出力
- 04コントラストやトークンの一貫性を確認
MCP 対応
Dembrandtは、非同期の抽出、分析、出力、ジョブ管理ツールをMCPクライアントに提供します。クライアントはジョブ状態をポーリングするか、同期抽出を指定できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dembrandt/ dembrandt-skills --skill extract-designインストール後、Claude Code で/extract-designを入力して読み込まれたか確認します。
詳細
デザインの抽出 — Dembrandt
Dembrandt は、あらゆる URL に対してヘッドレス Chromium ブラウザーを実行し、最大数千の DOM 要素をたどって計算済み CSS を読み取り、構造化されたデザインシステムを返します。これには、信頼度スコア付きの色、タイポグラフィスタイル、スペーシングスケール、角丸、境界線、シャドウ、インタラクティブなコンポーネントスタイルが含まれます。
実行方法
# Zero-install — npx fetches the package on first run (lowest friction)
npx -y dembrandt https://dembrandt.com
# Or install once (global), then call `dembrandt` directly
npm i -g dembrandt
# Basic extraction — outputs to terminal
dembrandt https://dembrandt.com
# JSON output — pipe into files or other tools
dembrandt https://dembrandt.com --json-only > dembrandt-tokens.json
# W3C DTCG format (design-tokens.org standard)
dembrandt https://dembrandt.com --dtcg --save-output
# Generate DESIGN.md (human + AI readable brand doc)
dembrandt https://dembrandt.com --design-md
# Multi-page crawl (follows internal links)
dembrandt https://dembrandt.com --crawl 5
# Dark mode colors
dembrandt https://dembrandt.com --dark-mode
# Mobile viewport
dembrandt https://dembrandt.com --mobile
# Everything saved to output/
dembrandt https://dembrandt.com --save-output
# Tailwind v4 @theme CSS — observed values only [dembrandt 0.28+]
dembrandt https://dembrandt.com --tailwind src/app.css
# Self-contained HTML report — open offline or attach as a CI artifact [dembrandt 0.19+]
dembrandt https://dembrandt.com --html report.html
# Drift gate — compare against a saved baseline; exits 1 on drift [dembrandt 0.19+]
dembrandt https://app.example.com --compare baseline.json --html report.html
MCP の使い方(デフォルトで非同期)
Dembrandt を MCP ツールとして公開するには、このサーバーをエージェントの MCP 設定に追加します(インストール不要です。初回実行時に npx が取得します)。
{ "mcpServers": { "dembrandt": { "command": "npx", "args": ["-y", "dembrandt", "mcp"] } } }
Dembrandt MCP サーバーを使用する場合、すべての抽出ツールは処理をブロックせず、すぐに job_id を返します。status が "completed" になるまで get_job_status をポーリングしてください。
1. get_design_tokens({ url: "dembrandt.com", pages: 5 })
→ { job_id: "job_123_abc", status: "queued" }
2. get_job_status({ job_id: "job_123_abc" })
→ { status: "running" } // poll again
3. get_job_status({ job_id: "job_123_abc" })
→ { status: "completed", result: { ... } }
4. get_findings({ job_id: "job_123_abc" }) // no need to resend the extraction
→ { findings: [ ... ], contrast: { ... } }
抽出結果を渡す代わりに、job_id を分析ツールに渡してください。 すべての純粋関数型ツールが job_id を受け付け、キューは抽出結果全体を 1 時間保持するため、get_color_palette のような限定的なツールで開始したジョブでも export_dtcg に利用できます。抽出結果をインラインで渡すこともでき、その場合は両方を指定するとインラインの抽出結果が優先されます。ただし、実際の抽出結果は大きすぎるため、ツール引数としてモデルに戻すことは現実的ではありません。 [dembrandt 0.29+]
任意の抽出ツールに sync: true を渡すと、処理をブロックして結果を直接返します(ネットワークが速い場合に便利ですが、遅いサイトではタイムアウトのリスクがあり、pages が 1 を超えるとそれに応じて時間がかかります)。
抽出ツール:get_design_tokens(すべて)、get_color_palette、get_typography、get_component_styles、get_surfaces、get_spacing、get_brand_identity、get_motion(持続時間、イージング、名前付きキーフレーム、ホバーパターン、およびそれらに伴うグラデーション) [dembrandt 0.36+]。すべてのツールが slow、mobile(モバイルのビューポート)、cookie(認証が必要なページ用の Cookie 文字列)を受け付けます。get_design_tokens と get_color_palette は darkMode と wcag(コントラスト分析)も受け付けます。 [dembrandt 0.23.1+ for mobile/cookie/wcag]
すべての抽出ツールはクロールも実行します。トークンの品質を左右する最大の要因はこれです。1 ページから得られるトークンは、その 1 ページ分です。 [dembrandt 0.29+]
| オプション | 内容 |
|---|---|
pages | 最大 N ページを抽出し、1 つのトークンセットに統合します(1~20)。ページは DOM リンクから取得されるか、sitemap が true の場合は sitemap.xml から取得されます |
paths | ["/pricing", "/docs"] のように、追加するパスを明示的に指定します。自動検出より優先されます |
sitemap | sitemap.xml からページを検出します。単独で指定した場合は最大 20 ページが対象となり、pages を指定するとその数が上限になります |
header | 追加の HTTP ヘッダー。Cookie ではアクセスできないページ用に、"Authorization: Bearer ..." のような文字列またはリストを指定します |
cookieFile | 保存済みセッションへのパス。JSON Cookie 配列、Playwright の storageState ファイル(Cookie、localStorage、および --save-storage-state が追加する sessionStorage ブロック)、または Netscape の cookies.txt を指定できます。オペレーターが一度 dembrandt <url> --login --save-storage-state <path> で作成します。エージェント自身はサインインできません [dembrandt 0.39+] |
basicAuth | ブラウザーのプロンプトが表示されるステージングホスト用の HTTP Basic 認証情報。"user:password" の形式で指定します [dembrandt 0.39+] |
userAgent | カスタムユーザーエージェント文字列 |
noSandbox | ブラウザーのサンドボックスを無効にします。Docker および多くの CI コンテナーでは必須です。無効にしないと起動に失敗します |
読み込みに失敗したページは除外され、残りのページは統合されるため、URL が 1 つ失敗してもクロール全体が失敗することはありません。
純粋なツール(ブラウザー不要、同期処理。抽出結果は result に格納するか、完了済みのジョブを job_id で指定します [dembrandt 0.29+の場合]):compute_drift(2つの抽出結果間のドリフトスコアを0〜100で算出します。ジョブを使う形式では baselineJobId と candidateJobId を指定します)、get_findings(デザインシステムのリント:コントラスト、一貫性、重複)、export_dtcg(W3C Design Tokens形式)、generate_design_md(ブランドガイドのDESIGN.md)、render_report(自己完結型HTMLレポート)、export_tailwind(Tailwind v4の @theme ブロック)、export_shadcn(shadcn/uiテーマ。ページに指定がないスロットはshadcnのデフォルトのままにします)。ジョブ制御:get_job_status、list_jobs、cancel_job。 [get_findings/export_dtcg/generate_design_md/list_jobsはdembrandt 0.23.1+、2つの出力ツールは0.36+]
3つのツールは抽出結果ではなく、それぞれ独自の入力を受け取ります [dembrandt 0.36+]:validate_dtcg(このサーバーが生成したものも含め、DTCGドキュメントが2025.10仕様に準拠しているか確認します。手動編集によって問題が気付かないうちに入り込むのを防げます)、check_contrast(これから公開する色の組み合わせを指定し、テキストサイズに応じたしきい値でWCAG 2.1に照らして評価します。ページ上にすでにある色ではなく、これから公開する色が対象です)、check_robots(ブラウザーを使った処理を実行する前に、robots.txtでURLへのアクセスが許可されているか確認します)。
注意:npx は最新版を取得するよりも、PATH上にある dembrandt を優先して実行します。そのため、グローバルにインストールされたdembrandtが気付かないうちに優先されることがあります。症状:固定バージョンでサポートされているオプションが不明なオプションとして拒否される、またはクロールで1ページしか取得されない。dembrandt --version で確認し、グローバルインストールをアップグレードするか、MCP設定で明示的なパスを指定してください。
注意:dembrandt <=0.23.0では、上記のnpxワンライナーを使うと起動に失敗します(McpDepsMissingError)。MCP SDKがオプションのピア依存関係だったためです。0.23.1で修正されました。SDKが必要です。
出力構造
Dembrandtは構造化オブジェクトを返します。主なセクションは次のとおりです。
colors.palette — Deduplicated colors with confidence (high/medium/low).
Each entry carries hex (`normalized`), plus `lch` and
`oklch` of the same colour, and derived `role`,
`onColor`, `hover`. With `--wcag`, entries also carry
`contrastAgainst`, the pairs this colour was actually
observed against on the page, deduped by the other
colour and sorted by ratio (dembrandt 0.31+). `tokens`
lists the custom property names that declare that
exact colour, read from html and body, so a colour
with tokens is one the site named (dembrandt 0.37+).
colors.detected — Every colour that passed the alpha gate, with no
frequency threshold and no perceptual merge, so six
near-identical reds stay six entries. `usageFrac`
counts elements; `areaFrac` is the share of painted
background area, which ranks a hero fill above many
small glyphs the way a count alone does not (dembrandt
0.32+). Use `palette` for a design system and
`detected` when you need recall.
colors.semantic — Primary, secondary, background, text, and accent detection
colors.semanticEvidence — How `primary` was decided (dembrandt 0.39+).
`primary.decision` is `elected` or `refused`; `rule`
names the rule that chose it, `reason` says it in
words, `tokens` lists the custom properties that
declare the colour, `alternates` the chromatic
runners-up. A refused primary is written down with
the candidates that lost, so an absent `primary` is
a decision, not a failed run. Read this before
trusting a primary on a dark or monochrome brand.
colors.occurrences — The measurement the palette is read from (0.39+):
one row per colour per `paints` (`fill`, `text`,
`border`) with `count`, summed fill `area` and the
first declaring `cssVar`. `slot` and `state` are null
until classification lands.
colors.cssVariables — Named CSS custom properties. `value` is the author's
string verbatim (the only record of the authored
notation), plus computed hex + LCH + OKLCH.
typography.styles — Font family, size, weight, line-height per context.
Each entry carries `count`, the number of elements
rendering that exact style. `code`, `pre`, `kbd` and
`samp` land in a `mono` context, so a mono face used
only in code blocks is visible (dembrandt 0.32+).
`isFluid` is read from the authored declaration, so a
`clamp()` or viewport-relative ramp is detected
(dembrandt 0.32+).
typography.sources — Google Fonts, Adobe Fonts, variable font detection.
`customFonts` names the declared @font-face families;
`selfHostedFonts` keeps the file names. `fontDisplay`
is the first font-display value seen, or null
(dembrandt 0.37+).
`urls` lists the resolved font asset and webfont
stylesheet URLs, deduped, so you can re-fetch or verify
the real files. `filteredFamilies` lists families
dropped by the usage floor — check it before concluding
a face is missing.
spacing.commonValues — Margin/padding scale with rem equivalents
spacing.scaleType — 4px, 8px, or custom grid. Since 0.34.0 the verdict is
weighted: a page reads custom unless 60% of its spacing
lands on the step, so sites that used to claim a grid
now report custom truthfully
borderRadius.values — Border radius tokens with element context
borders.combinations — Width + style + color combinations
shadows — Box shadow elevation system. One string per shadow,
layers comma-separated as CSS writes them. The `--dtcg`
export splits them into structured layers (0.32+).
components.buttons — Button variants with hover/active/focus states
components.inputs — Input styles with focus states
components.links — Link colors and hover states
components.badges — Badge/tag/chip variants
breakpoints — Responsive breakpoints from CSS media queries
frameworks — What builds the UI. Before 0.38 only CSS frameworks
(Tailwind, shadcn, MUI). From 0.38 each entry carries
`category` (js-framework, meta-framework, js-library,
css-framework, ui-library, web-components, css-in-js,
site-builder), `version` when the page states one, and
`coverage`: the share of the page under that
framework's mount point, 0 to 1.
iconSystem — Detected icon library (Heroicons, FA, Material, etc.),
with `version` when the page states one (0.38+)
pages — Present only on a merged multi-page result (`--crawl`,
`--sitemap`, extra paths, or MCP `pages`). One entry per
page extracted, so you can tell which URLs the merged
tokens came from. Every merged palette, typography,
spacing, radius, border and shadow value then carries
`pageCount` and `scope`: `site` when every page has
it, `page` when one does, `section` between (0.39+).
coverage — On a merged result only (0.39+): `score` 0-100 as the
mean of family means, `byFamily` with `meanCoverage`
and `pageLocal` counts, and `outliers`, the page-local
tokens capped at five per family. A page-local token
is drift inside one snapshot. `totalPages` travels
with the score; 2 of 2 and 2 of 7 are not the same.
meta.context : the browser context the run was measured under
(0.39+): viewport, deviceScaleFactor, isMobile,
hasTouch, colorScheme, reducedMotion, forcedColors,
locale, timezoneId, userAgent. `--compare` warns when
two snapshots differ in a rendering dial.
wcag : with `--wcag`, observed contrast pairs (fg, bg, ratio,
aa/aaLarge/aaa booleans) between real rendered colours.
meta.crawl : present when `--crawl`, `--sitemap` or explicit paths
are used, with `technique`, `pagesRequested`,
`pagesFound` (dembrandt 0.31+).
meta.robotsWarnings : pages robots.txt disallowed, whether that was the
entry URL or one discovered during a crawl. The check
is advisory by default, it does not block
extraction, and this is the only record of what it
flagged (dembrandt 0.31+). Set
`DEMBRANDT_ENFORCE_ROBOTS=1` to make a disallow, or a
robots.txt we could not read, skip the target with exit
`4`. A site with no robots.txt (404/410) is not a
refusal and still runs (dembrandt 0.32+).
抽出したトークンの使用
Tailwindテーマのシード (dembrandt 0.28+)
JSONを手作業でマッピングしないでください。--tailwind はTailwind v4の @theme ブロックを直接書き出します。
dembrandt https://dembrandt.com --tailwind # → output/<domain>/theme.css
dembrandt https://dembrandt.com --tailwind src/app.css # or straight into the project
@import "tailwindcss";
@theme {
--color-primary: #ea580c;
--text-display: 96px;
--text-display--line-height: 1;
--spacing: 8px;
--radius-lg: 8px;
--breakpoint-md: 700px;
}
観測された値のみを使用します。50〜950のシェードランプ、補間されたスケールの段階、派生したホバー用やオンカラーのバリエーションはありません。いったんファイルに含めると、作り出したシェードと実測値を見分けられなくなるため、この書き出しは手動で拡張するための出発点です。色にはセマンティックな役割名(--color-primary)、またはページで独自のカスタムプロパティ名が宣言されている場合はその名前が使われ、それ以外は --color-brand-N のように番号が付けられます。ページにNを基準としたリズムがある場合、スペーシングはv4の --spacing 倍数にまとめられ、そうでない場合は名前付きの段階にフォールバックします。記載されていない項目にはTailwindのデフォルトが適用されるため、このブロックはテーマを置き換えるのではなく拡張します。
v4のみ対応しています。v3の tailwind.config.js では、出力を手動でマッピングしてください。colors.semantic → theme.colors、typography.styles → fontFamily、spacing.commonValues → spacing、borderRadius.values → borderRadius、shadows → boxShadow。
shadcn/uiテーマのシード
--shadcn(0.34.0+)でテーマを書き出すため、変数を手動でマッピングする必要はありません。
dembrandt stripe.com --shadcn # output/<domain>/shadcn.css
このファイルには、:root ブロックとTailwind v4に必要な @theme inline
マッピングが含まれており、色はoklchで表されます。ページで値が指定されているスロットのみが書き込まれ、残りはファイルヘッダーに明記されてshadcn独自のデフォルトのままになります。そのため、観測されていないスロットが、実測値のように見えるもっともらしい値として出力されることはありません。
--dark-mode を指定すると .dark ブロックが生成されます。1回の実行につき1つのカラースキームを出力します。
--radius を borderRadius.values[0] から導出しないでください。このリストは長さの順に並んでいるため、最初の項目はページ上で最も小さい半径であり、ボタンや入力欄に使われている値とは限りません。このフラグでは、最も使用頻度の高い値が使われます。
信頼度の読み方
Dembrandt は、意味的なコンテキストに基づいてすべての色をスコアリングします。
| 信頼度 | 意味 |
|---|---|
| 高 | 意味的なラベルが付いた要素(ボタン、CTA、ブランドクラスが付いたヘッダー)に表示されます。ほぼ確実にブランドカラーです。 |
| 中 | 使用頻度またはコンテキストが中程度です。ブランドカラーである可能性が高いです。 |
| 低 | 使用頻度が低く、意味的なコンテキストも乏しい色です。単発または特定のコンポーネント専用の色かもしれません。 |
0.28.0 以降では、スペーシングや角丸と同様に、信頼度にも使用回数の下限が設けられています。1 回だけ使われている色は「低」、2 回なら「中」が上限となり、意味的なコンテキストのスコアにかかわらず、「高」には3回の出現が必要です。ホバー色とフォーカス色は例外で、「中」のままです。1回だけの出現は使用回数を示すものではなく、由来を示すものだからです。
パレットを作成する際は、まず信頼度がhighの色から始めてください。網羅性を高めるにはmediumも含めます。lowは参考情報としてのみ扱ってください。
色の表記
色を手作業で変換したり、独自に計算し直したりしないでください。パレットの各エントリと各 CSS 変数には、16進数表記と併せてlchおよびoklchもすでに記載されているため、必要なフィールドを JSON から直接読み取ってください。--color-formatが変更するのはターミナルへの出力形式だけなので、JSON や MCP の出力を利用する場合には適していません。
色の識別には、16進数(normalized)を使用してください。重複排除、差分比較、すべての後続ツールがこの値をキーとして使います。同じ16進数のエントリは、出力される表記が異なっていても、同じトークンです。作成者がモダンな表記でトークンを宣言している場合、cssVariables[name].valueにはその表記がそのまま保持されます。そのコードベースに CSS を書き戻す際は、作成者自身の表記を維持し、色域内に収められるため、この値を使ってください。
フラグのリファレンス
| フラグ | 機能 |
|---|---|
--json-only | クリーンな JSON を標準出力に出力します。ファイルやツールにパイプできます |
--save-output | JSON を output/<domain>/<timestamp>.json に保存します |
--dtcg | W3C Design Tokens Community Group 形式です。シャドウトークンのレイヤーが複数ある場合、$value は配列になります。そのため、$value.offsetX を読み取るコンシューマーは Array.isArray による分岐が必要です。(0.32+) |
--design-md | DESIGN.md(文章を主体としたブランドドキュメント)を生成します |
--html [path] | 自己完結型の HTML レポートを生成します(CSS をインライン化し、JSON を埋め込みます)。オフラインで開いたり、CI アーティファクトとして添付したりできます。(0.19+) |
--compare <baseline.json> | 保存済みの抽出結果との差分を表示します。ドリフト判定を出力し、ドリフトがある場合は 1 で終了します。CI ゲートとして使用できます。(0.19+) |
--brand-guide | PDF ブランドガイドを生成します |
--dark-mode | ダークカラースキームを抽出し、パレットに統合します |
--mobile | 幅 390px のモバイルビューポートで抽出します |
--crawl <n> | 最大 N ページをクロールし、トークンを統合します |
--sitemap | sitemap.xml からページを検出します |
--slow | タイムアウトを 3 倍にします。読み込みが遅いサイトや JavaScript を多用するサイトで使用します |
--screenshot <path> | ページ全体のスクリーンショットを保存します |
--raw-colors | フィルター処理前の生の色を JSON 出力に含めます |
--color-format <fmt> | ターミナルに出力する色の表記形式です。hex(デフォルト)、rgb、oklch、lch、source(作成時の形式)を指定できます。表示形式のみの変更のため、JSON 出力は変わらず、エクスポート先では無視されます。(0.28+) |
--tailwind [path] | Tailwind v4 の @theme CSS ファイルを書き込みます。観測された値のみが対象です。デフォルトは output/<domain>/theme.css です。(0.28+) |
--shadcn [path] | shadcn/ui のテーマを書き込みます。観測されたスロットのみが対象で、@theme inline も含まれます。デフォルトは output/<domain>/shadcn.css です。(0.34+) |
--browser firefox | Chromium の代わりに Firefox を使用します |
--stealth | オプトインの検出回避機能を有効にします。navigator の偽装と人間のマウス操作のシミュレーションを行います。許可されている場合にのみ使用してください |
--user-agent <string> | カスタムユーザーエージェント文字列を指定します |
--locale <string> | ブラウザーのロケールを指定します。例:fi-FI、en-GB(デフォルト:en-US) |
--timezone <string> | ブラウザーのタイムゾーンを指定します。例:Europe/Helsinki(デフォルト:America/New_York) |
--accept-language <string> | カスタムの Accept-Language ヘッダー値を指定します |
--header <string> | 追加のリクエストヘッダーを Name: value 形式で指定します。複数指定する場合はフラグを繰り返します(0.39 以降、繰り返し指定可能) |
--screen-size <WxH> | 報告する物理画面解像度を指定します。例:1920x1080 |
ドリフト検出と CI (dembrandt 0.19+)
--compare を使うと、抽出処理をゲートとして利用できます。正常な状態のベースラインを保存し、その後の抽出結果と比較します。
# 1. capture a baseline (in the SAME environment you will check against)
dembrandt https://app.example.com --json-only > baseline.json
# 2. later — compare; exits 0 if stable, 1 if drifted
dembrandt https://app.example.com --compare baseline.json --html report.html
- 構造化トークンに対して標準のドリフトエンジンを実行します。ピクセルやレンダリングの差分ではなく、決定論的な比較です。
- 終了コード:
0は安定、1はドリフトを示します。パイプラインのゲートとして直接利用できます。 --htmlは自己完結型のレポートを書き出します。--compareと併用すると、ドリフトバナー(追加・削除・変更されたトークン)が含まれます。CI のアーティファクトとして添付してください。
0.28.0 ではベースラインが一度だけ大きく変動します。 3 つの修正によって、色とタイポグラフィの値が変わります。パレットの使用量の下限、body が 24px の読みやすい範囲で終わること(それより大きい見出し以外のテキストは text が適用されるため、ヒーローコピーが body トークンに分類されなくなります)、カウント対象のテキストの 2% 未満を占めるフォントファミリーを除外することです。dembrandt.com で 0.27.1 の抽出結果と比較したところ、ドリフトはしきい値の 10 に対して 15 となり、ゲートで失敗する値でした。アップグレード後の初回実行では、--compare <baseline> --approve で再承認するか、ベースラインを再生成してください。その後のドリフトは実際のドリフトです。
0.32.0 では再承認は不要です。 スキーマ 1.12.0 は、2 つの参照サイトでしきい値の 10 に対してそれぞれ 7 と 6 を記録しました。唯一の違いは mono コンテキストの追加です。Tailwind のシャドウ段階はぼかしだけでなく深さに基づいて並べ替えられるため、変更のないサイトでも --shadow-sm/md/lg/xl の値が変わることがあります。
0.35.0 ではゲートが失敗する条件が変わります。 以前は、ブランドカラーの変更が、同じままのパレット項目すべてによって割り引かれていました。実際の stripe.com のベースラインで semantic.primary をマゼンタに変えても、スコアは安定と判定され、終了コードは 0 でした。現在はセマンティックマップを独自の重みで評価するため、役割の変更がしきい値に達するようになりました。実行ごとのばらつきに対する許容値は変わっておらず、パレット項目が 1 つ追加または消失しただけでは、依然としてゲートに影響しません。0.34.2 と比較した 2 つの参照サイトでの測定値は、しきい値の 10 に対して 0 と 4 だったため、変更のないサイトでは再承認は不要です。ブランドカラーが実際に変わったサイトでは、以前は通過していたゲートが失敗するようになります。
また、0.35.0 では、グリッドに沿わないスペーシングの検出結果がこれまでまったく生成されていませんでした。チェックが、抽出処理で 1.14.0 以降書き込まれなくなった spacing.scaleType という表記と照合していたためです。グリッドに沿わない値を持つサイトでは、検出結果が表示され、整合性スコアが低くなります。
決定性: ベースラインは、検証時と同じ環境(どちらも本番環境、または同じプレビュー環境)で取得してください。ある環境のベースラインを別の環境と比較すると、誤ったドリフトが検出されます。
CI での使用: プレビュー URL またはデプロイ済み URL に対して --compare <baseline> --html report.html を実行し、終了コードが 1 の場合はジョブを失敗させ、HTML アーティファクトをアップロードします。プログラムからの使用: dembrandt/drift から computeDrift を、dembrandt/report から generateHtmlReport をインポートすると、CLI を使わずにサーバー側で差分を計算し、レポートを生成できます。
ボット対策と SPA への対応
Dembrandt は、一般的な抽出上の課題に自動で対応します。
- SPA のハイドレーション — React/Vue/Svelte がレンダリングされるまで 8 秒待ってから抽出します
- 遅延読み込みコンテンツ — ページ全体をスクロールして、遅延読み込みコンポーネントを起動します
- Cloudflare/ボット対策画面 — ヘッドレスブラウザーがブロックされた場合、表示ブラウザーで自動的に再試行します
- 応答の遅いサイト — 重い JavaScript バンドルがある場合は
--slowを使うと、タイムアウトが 3 倍になります - Cookie バナー — 一般的な CMP ダイアログ(OneTrust、cookielaw、GDPR のパターン)を自動的に閉じます
- ボット検出の回避 —
--stealthを使うと、navigator の偽装と人間らしいマウス操作のシミュレーションを有効にできます。ツールが正直に自身を識別するよう、デフォルトでは無効です - robots.txt — オリジンごとに一度読み込み、ブラウザーが実際に送信する User-Agent と照合します。デフォルトでは参考情報として扱います。定期実行ジョブやサーバー側での利用など、取得してよい対象を判断する人がいない場合は
DEMBRANDT_ENFORCE_ROBOTS=1を設定してください。取得禁止の指定がある場合や、ファイルを読み込めなかった場合は、対象をスキップして終了コード4を返します。robots.txt が存在しないことは拒否を意味しません (0.32+)
抽出後のチェックリスト
- 信頼度の高い色を3〜5色特定します。これらがブランドの中核となるカラーパレットです
-
colors.semantic.primaryを確認します。正しく設定されていますか? -
typography.stylesを確認します。見出しと本文にはどのフォントが使われていますか? -
spacing.scaleTypeを確認します。4px、8px、またはカスタムのどれですか?カスタムも正しい回答であり、欠落ではありません -
components.buttonsを確認します。バリエーションはいくつありますか? -
frameworksを確認します。css-frameworkとui-libraryの項目は、トークンの適用方法を左右します。coverageが0に近い場合、それはページ上のウィジェットであり、ページ全体の構成要素ではありません。versionがない場合、ページに記載がないということであり、推測してはいけません - サイトにダークテーマがある場合は、
--dark-modeを使用します - ルートにまたがる複数セクションのデザインシステムがあるサイトでは、
--crawl 3を使用します