@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
@@ -0,0 +1,59 @@
1
+ const TRANSIENT_KEYS = ['_discoveredLinks', '_extractedUrls', '_pageResults'];
2
+ /**
3
+ * Remove internal crawl/merge fields that must never be persisted, even if a raw
4
+ * crawl object is fed in. Returns a shallow copy; the input is untouched.
5
+ */
6
+ export function stripTransient(result) {
7
+ const clean = { ...result };
8
+ for (const key of TRANSIENT_KEYS)
9
+ delete clean[key];
10
+ return clean;
11
+ }
12
+ const toNumber = (v) => {
13
+ if (typeof v === 'number')
14
+ return Number.isFinite(v) ? v : undefined;
15
+ if (typeof v === 'string') {
16
+ const n = parseFloat(v);
17
+ return Number.isFinite(n) ? n : undefined;
18
+ }
19
+ return undefined;
20
+ };
21
+ /**
22
+ * Canonicalize the loose unions to a single shape so the engine and UI never see
23
+ * variants. Conservative: only touches the documented offenders, leaves the rest
24
+ * untouched, and never throws. Run after stripTransient() at ingest.
25
+ *
26
+ * - typography weight : string | number -> number
27
+ * - spacing px : number | string -> number
28
+ * - spacing display : guaranteed "Npx" string (backfilled if absent)
29
+ * - typography adobeFonts : string[] | bool -> string[]
30
+ * - components inputs/badges : array | object -> array
31
+ */
32
+ export function normalizeExtraction(result) {
33
+ const out = stripTransient(result);
34
+ for (const s of out.typography?.styles ?? []) {
35
+ const w = toNumber(s.weight);
36
+ if (w !== undefined)
37
+ s.weight = w;
38
+ }
39
+ for (const v of out.spacing?.commonValues ?? []) {
40
+ const px = toNumber(v.px);
41
+ if (px !== undefined)
42
+ v.px = px;
43
+ if (v.display === undefined) {
44
+ v.display = px !== undefined ? `${px}px` : String(v.px);
45
+ }
46
+ }
47
+ if (out.typography?.sources && typeof out.typography.sources.adobeFonts === 'boolean') {
48
+ out.typography.sources.adobeFonts = [];
49
+ }
50
+ if (out.components) {
51
+ const c = out.components;
52
+ if (c.inputs && !Array.isArray(c.inputs))
53
+ c.inputs = c.inputs.text ?? [];
54
+ if (c.badges && !Array.isArray(c.badges))
55
+ c.badges = c.badges.all ?? [];
56
+ }
57
+ return out;
58
+ }
59
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../lib/normalize.ts"],"names":[],"mappings":"AAaA,MAAM,cAAc,GAAG,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,CAAU,CAAC;AAEvF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAA2B,MAAS;IAChE,MAAM,KAAK,GAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IACjC,KAAK,MAAM,GAAG,IAAI,cAAc;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAsB,EAAE;IAClD,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QACxB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAA2B,MAAS;IACrE,MAAM,GAAG,GAAQ,cAAc,CAAC,MAAM,CAAC,CAAC;IAExC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,UAAU,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;QAC7C,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,SAAS;YAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,YAAY,IAAI,EAAE,EAAE,CAAC;QAChD,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,EAAE,KAAK,SAAS;YAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;QAChC,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC5B,CAAC,CAAC,OAAO,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,IAAI,OAAO,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACtF,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,GAAG,EAAE,CAAC;IACzC,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACnB,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC;QACzB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACzE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,12 @@
1
+ export type RobotsResult = {
2
+ status: "unavailable";
3
+ robotsUrl: string;
4
+ } | {
5
+ status: "ok";
6
+ robotsUrl: string;
7
+ allowed: boolean;
8
+ rule: string | null;
9
+ };
10
+ export declare function checkRobotsTxt(targetUrl: string, { timeoutMs }?: {
11
+ timeoutMs?: number;
12
+ }): Promise<RobotsResult>;
@@ -0,0 +1,110 @@
1
+ const UA = "Dembrandt";
2
+ export async function checkRobotsTxt(targetUrl, { timeoutMs = 5000 } = {}) {
3
+ const u = new URL(targetUrl);
4
+ const robotsUrl = `${u.protocol}//${u.host}/robots.txt`;
5
+ const path = u.pathname || "/";
6
+ const controller = new AbortController();
7
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
8
+ let body;
9
+ try {
10
+ const res = await fetch(robotsUrl, {
11
+ signal: controller.signal,
12
+ headers: { "User-Agent": UA },
13
+ });
14
+ if (!res.ok)
15
+ return { status: "unavailable", robotsUrl };
16
+ body = await res.text();
17
+ }
18
+ catch {
19
+ return { status: "unavailable", robotsUrl };
20
+ }
21
+ finally {
22
+ clearTimeout(timer);
23
+ }
24
+ const groups = parseRobots(body);
25
+ const rules = matchGroup(groups, UA) || matchGroup(groups, "*") || [];
26
+ const decision = evaluate(rules, path);
27
+ return { status: "ok", robotsUrl, ...decision };
28
+ }
29
+ function parseRobots(text) {
30
+ const groups = [];
31
+ let current = null;
32
+ let lastWasAgent = false;
33
+ for (const raw of text.split(/\r?\n/)) {
34
+ const line = raw.replace(/#.*$/, "").trim();
35
+ if (!line)
36
+ continue;
37
+ const idx = line.indexOf(":");
38
+ if (idx === -1)
39
+ continue;
40
+ const field = line.slice(0, idx).trim().toLowerCase();
41
+ const value = line.slice(idx + 1).trim();
42
+ if (field === "user-agent") {
43
+ if (!current || !lastWasAgent) {
44
+ current = { agents: [], rules: [] };
45
+ groups.push(current);
46
+ }
47
+ current.agents.push(value.toLowerCase());
48
+ lastWasAgent = true;
49
+ }
50
+ else if (field === "allow" || field === "disallow") {
51
+ if (!current) {
52
+ current = { agents: ["*"], rules: [] };
53
+ groups.push(current);
54
+ }
55
+ current.rules.push({ type: field, value });
56
+ lastWasAgent = false;
57
+ }
58
+ }
59
+ return groups;
60
+ }
61
+ function matchGroup(groups, agent) {
62
+ const wanted = agent.toLowerCase();
63
+ for (const g of groups) {
64
+ if (g.agents.includes(wanted))
65
+ return g.rules;
66
+ }
67
+ return null;
68
+ }
69
+ function evaluate(rules, path) {
70
+ let best = {
71
+ type: null,
72
+ length: -1,
73
+ value: "",
74
+ };
75
+ for (const r of rules) {
76
+ if (!r.value)
77
+ continue;
78
+ if (!pathMatches(path, r.value))
79
+ continue;
80
+ if (r.value.length > best.length)
81
+ best = { ...r, length: r.value.length };
82
+ }
83
+ if (best.type === "disallow")
84
+ return { allowed: false, rule: best.value };
85
+ return { allowed: true, rule: best.value || null };
86
+ }
87
+ function pathMatches(path, pattern) {
88
+ const anchored = pattern.endsWith("$");
89
+ const p = anchored ? pattern.slice(0, -1) : pattern;
90
+ const parts = p.split("*");
91
+ let i = 0;
92
+ for (let k = 0; k < parts.length; k++) {
93
+ const seg = parts[k];
94
+ if (k === 0) {
95
+ if (!path.startsWith(seg))
96
+ return false;
97
+ i = seg.length;
98
+ }
99
+ else {
100
+ const found = path.indexOf(seg, i);
101
+ if (found === -1)
102
+ return false;
103
+ i = found + seg.length;
104
+ }
105
+ }
106
+ if (anchored && i !== path.length)
107
+ return false;
108
+ return true;
109
+ }
110
+ //# sourceMappingURL=robots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"robots.js","sourceRoot":"","sources":["../../lib/robots.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Builds the "what shaped this run" lines for the closing CLI summary (DEM-99):
3
+ * which flags were active and which paths were merged. Pure and importable so it
4
+ * is unit-tested without spawning the CLI; index.ts wraps the returned strings
5
+ * with chalk and prints them under the analysis summary.
6
+ */
7
+ export interface RunOpts {
8
+ darkMode?: boolean;
9
+ mobile?: boolean;
10
+ slow?: boolean;
11
+ stealth?: boolean;
12
+ wcag?: boolean;
13
+ /** number of pages, or true for the bare flag, or null/undefined when unused */
14
+ crawl?: number | boolean | null;
15
+ sitemap?: boolean;
16
+ browser?: string;
17
+ /** commander sets false for --no-sandbox; true/undefined otherwise */
18
+ sandbox?: boolean;
19
+ rawColors?: boolean;
20
+ dtcg?: boolean;
21
+ saveOutput?: boolean;
22
+ /** --html [path]: undefined when absent, string or true when present */
23
+ html?: unknown;
24
+ compare?: unknown;
25
+ brandGuide?: boolean;
26
+ designMd?: boolean;
27
+ screenshot?: unknown;
28
+ }
29
+ /**
30
+ * The flags that changed the run, in a stable display order. Behaviour-only
31
+ * flags (--wcag, --dark-mode, ...) included so they leave a trace even though
32
+ * they write no file; artifact flags included too (their paths print separately).
33
+ */
34
+ export declare function activeFlags(opts?: RunOpts): string[];
35
+ /**
36
+ * Explicit paths and/or the merged-page count. Explicit paths are positional
37
+ * (not flags) so they would otherwise be invisible; --crawl/--sitemap have no
38
+ * explicit paths but still merge pages, reported by the count alone.
39
+ */
40
+ export declare function pathSummary(paths: string[] | undefined, mergedPages?: number): string[];
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Builds the "what shaped this run" lines for the closing CLI summary (DEM-99):
3
+ * which flags were active and which paths were merged. Pure and importable so it
4
+ * is unit-tested without spawning the CLI; index.ts wraps the returned strings
5
+ * with chalk and prints them under the analysis summary.
6
+ */
7
+ /**
8
+ * The flags that changed the run, in a stable display order. Behaviour-only
9
+ * flags (--wcag, --dark-mode, ...) included so they leave a trace even though
10
+ * they write no file; artifact flags included too (their paths print separately).
11
+ */
12
+ export function activeFlags(opts = {}) {
13
+ const bits = [];
14
+ if (opts.darkMode)
15
+ bits.push('--dark-mode');
16
+ if (opts.mobile)
17
+ bits.push('--mobile');
18
+ if (opts.slow)
19
+ bits.push('--slow');
20
+ if (opts.stealth)
21
+ bits.push('--stealth');
22
+ if (opts.wcag)
23
+ bits.push('--wcag');
24
+ if (opts.crawl != null && opts.crawl !== false) {
25
+ bits.push(opts.crawl === true ? '--crawl' : `--crawl ${opts.crawl}`);
26
+ }
27
+ if (opts.sitemap)
28
+ bits.push('--sitemap');
29
+ if (opts.browser && opts.browser !== 'chromium')
30
+ bits.push(`--browser ${opts.browser}`);
31
+ if (opts.sandbox === false)
32
+ bits.push('--no-sandbox');
33
+ if (opts.rawColors)
34
+ bits.push('--raw-colors');
35
+ if (opts.dtcg)
36
+ bits.push('--dtcg');
37
+ if (opts.saveOutput)
38
+ bits.push('--save-output');
39
+ if (opts.html !== undefined)
40
+ bits.push('--html');
41
+ if (opts.compare)
42
+ bits.push('--compare');
43
+ if (opts.brandGuide)
44
+ bits.push('--brand-guide');
45
+ if (opts.designMd)
46
+ bits.push('--design-md');
47
+ if (opts.screenshot)
48
+ bits.push('--screenshot');
49
+ return bits;
50
+ }
51
+ /**
52
+ * Explicit paths and/or the merged-page count. Explicit paths are positional
53
+ * (not flags) so they would otherwise be invisible; --crawl/--sitemap have no
54
+ * explicit paths but still merge pages, reported by the count alone.
55
+ */
56
+ export function pathSummary(paths, mergedPages = 0) {
57
+ const bits = [];
58
+ if (paths && paths.length)
59
+ bits.push(...paths);
60
+ if (mergedPages > 1)
61
+ bits.push(`(${mergedPages} pages merged)`);
62
+ return bits;
63
+ }
64
+ //# sourceMappingURL=run-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-summary.js","sourceRoot":"","sources":["../../lib/run-summary.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAgB,EAAE;IAC5C,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,IAAI,CAAC,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5C,IAAI,IAAI,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,IAAI,IAAI,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACxF,IAAI,IAAI,CAAC,OAAO,KAAK,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACtD,IAAI,IAAI,CAAC,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC9C,IAAI,IAAI,CAAC,IAAI;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,IAAI,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACzC,IAAI,IAAI,CAAC,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,QAAQ;QAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5C,IAAI,IAAI,CAAC,UAAU;QAAE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,KAA2B,EAAE,WAAW,GAAG,CAAC;IACtE,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAC/C,IAAI,WAAW,GAAG,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,IAAI,WAAW,gBAAgB,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Shared types for dembrandt extraction output and CLI options.
3
+ * These were JSDoc @typedefs; promoted to real exported interfaces so the rest
4
+ * of the (now TypeScript) codebase can import and use them.
5
+ */
6
+ export type Confidence = 'high' | 'medium' | 'low';
7
+ export interface PaletteColor {
8
+ /** Original color string */
9
+ color: string;
10
+ /** Hex color (#rrggbb) */
11
+ normalized: string;
12
+ /** Number of occurrences */
13
+ count: number;
14
+ /** Semantic relevance score */
15
+ score?: number;
16
+ /** CSS class/id sources */
17
+ sources?: string[];
18
+ confidence: Confidence;
19
+ }
20
+ export interface Colors {
21
+ palette: PaletteColor[];
22
+ /** e.g. { primary: '#hex' } */
23
+ semantic: Record<string, string>;
24
+ /** CSS custom properties */
25
+ cssVariables: Record<string, string>;
26
+ rawColors?: PaletteColor[];
27
+ }
28
+ export interface TypographyStyle {
29
+ /** 'heading-1' | 'body' | 'button' | 'caption' | 'display' | 'link' */
30
+ context: string;
31
+ family: string;
32
+ fallbacks?: string[];
33
+ size: string;
34
+ weight: string | number;
35
+ lineHeight?: string;
36
+ letterSpacing?: string;
37
+ textTransform?: string;
38
+ isVariable?: boolean;
39
+ isFluid?: boolean;
40
+ }
41
+ export interface Typography {
42
+ styles: TypographyStyle[];
43
+ sources: {
44
+ googleFonts?: string[];
45
+ adobeFonts?: string[] | boolean;
46
+ variableFonts?: string[];
47
+ customFonts?: string[];
48
+ selfHostedFonts?: string[];
49
+ fontDisplay?: string;
50
+ };
51
+ }
52
+ export interface SpacingValue {
53
+ /**
54
+ * Numeric pixels for math and diffing. Raw extraction emits the "16px" string;
55
+ * normalizeExtraction() coerces it to a number. Read `display` for rendering.
56
+ */
57
+ px: number | string;
58
+ /** Guaranteed formatted value for display, e.g. "16px". Survives normalize. */
59
+ display: string;
60
+ rem?: string;
61
+ count?: number;
62
+ /** Numeric pixels as emitted by the extractor; mirror of px once normalized. */
63
+ numericValue?: number;
64
+ }
65
+ export interface Spacing {
66
+ /** 'base-4' | 'base-8' | 'fibonacci' | 'custom' */
67
+ scaleType: string;
68
+ commonValues: SpacingValue[];
69
+ }
70
+ export interface TokenValue {
71
+ value: string;
72
+ count: number;
73
+ confidence: Confidence;
74
+ }
75
+ export interface BorderRadius {
76
+ values: TokenValue[];
77
+ }
78
+ export interface BorderCombination {
79
+ width: string;
80
+ style: string;
81
+ color: string;
82
+ count?: number;
83
+ confidence?: Confidence;
84
+ }
85
+ export interface Borders {
86
+ widths?: TokenValue[];
87
+ styles?: TokenValue[];
88
+ colors?: TokenValue[];
89
+ combinations?: BorderCombination[];
90
+ }
91
+ export interface Shadow {
92
+ shadow: string;
93
+ count: number;
94
+ confidence: Confidence;
95
+ }
96
+ export interface Gradient {
97
+ gradient: string;
98
+ type: 'linear' | 'radial' | 'conic' | 'linear-repeating' | 'radial-repeating' | 'conic-repeating';
99
+ stopColors: string[];
100
+ count: number;
101
+ }
102
+ /** Computed CSS for one interaction state (rest/hover/active/focus). */
103
+ export interface CssState {
104
+ backgroundColor?: string;
105
+ color?: string;
106
+ borderRadius?: string;
107
+ padding?: string;
108
+ border?: string;
109
+ boxShadow?: string;
110
+ textDecoration?: string;
111
+ [key: string]: string | undefined;
112
+ }
113
+ export interface ButtonStyle {
114
+ states: {
115
+ default: CssState;
116
+ hover?: CssState;
117
+ active?: CssState;
118
+ focus?: CssState;
119
+ [key: string]: CssState | undefined;
120
+ };
121
+ text?: string;
122
+ fontWeight?: string;
123
+ fontSize?: string;
124
+ classes?: string;
125
+ }
126
+ export interface LinkStyle {
127
+ states: {
128
+ default: CssState;
129
+ hover?: CssState;
130
+ };
131
+ fontWeight?: string;
132
+ }
133
+ export interface InputStyle {
134
+ type?: string;
135
+ border?: string;
136
+ borderRadius?: string;
137
+ padding?: string;
138
+ states?: {
139
+ default?: CssState;
140
+ focus?: CssState;
141
+ };
142
+ }
143
+ export interface BadgeStyle {
144
+ backgroundColor?: string;
145
+ color?: string;
146
+ borderRadius?: string;
147
+ padding?: string;
148
+ fontSize?: string;
149
+ isRounded?: boolean;
150
+ styleType?: string;
151
+ }
152
+ export interface Components {
153
+ buttons: ButtonStyle[];
154
+ inputs: {
155
+ text?: InputStyle[];
156
+ } | InputStyle[];
157
+ links: LinkStyle[];
158
+ badges: {
159
+ all?: BadgeStyle[];
160
+ byVariant?: Record<string, BadgeStyle[]>;
161
+ } | BadgeStyle[];
162
+ }
163
+ export interface Breakpoint {
164
+ px: number | string;
165
+ }
166
+ export interface IconSystem {
167
+ name: string;
168
+ type: string;
169
+ sizes?: string[];
170
+ }
171
+ export interface Framework {
172
+ name: string;
173
+ confidence: Confidence;
174
+ evidence?: string;
175
+ }
176
+ export interface Logo {
177
+ source: 'img' | 'svg';
178
+ url: string;
179
+ width?: number;
180
+ height?: number;
181
+ alt?: string;
182
+ inline?: boolean;
183
+ color?: string | null;
184
+ ariaLabel?: string | null;
185
+ markup?: string | null;
186
+ dataUri?: string | null;
187
+ safeZone?: {
188
+ top: number;
189
+ right: number;
190
+ bottom: number;
191
+ left: number;
192
+ };
193
+ background?: string | null;
194
+ }
195
+ export interface Favicon {
196
+ type: string;
197
+ url: string;
198
+ sizes: string | null;
199
+ }
200
+ export interface WcagPair {
201
+ fg: string;
202
+ bg: string;
203
+ ratio: number;
204
+ aa: boolean;
205
+ aaLarge: boolean;
206
+ aaa: boolean;
207
+ count?: number;
208
+ state?: string;
209
+ tag?: string;
210
+ source?: string;
211
+ }
212
+ /** Metadata block on the native extraction output. */
213
+ export interface ExtractionMeta {
214
+ /** Provenance: the CLI release that produced this. Doubles as source.cliVersion. */
215
+ dembrandtVersion?: string | null;
216
+ /**
217
+ * Output contract version. Required: the current producer always stamps it.
218
+ * Consumers key migrations off this (absent in a persisted blob = pre-1.0) and
219
+ * must NOT shape-sniff. Bumps on breaking shape changes.
220
+ */
221
+ schemaVersion: string;
222
+ flags?: Record<string, unknown>;
223
+ /**
224
+ * Categories that extracted incompletely. Engine rule: do NOT flag drift from a
225
+ * degraded category (it failed extraction, the brand did not change) — surface
226
+ * it in the UI instead.
227
+ */
228
+ degraded?: string[];
229
+ }
230
+ export interface BrandingResult {
231
+ url: string;
232
+ /** ISO 8601 timestamp */
233
+ extractedAt: string;
234
+ meta?: ExtractionMeta;
235
+ siteName?: string | null;
236
+ logo?: Logo | null;
237
+ logoInstances?: any[];
238
+ favicons?: Favicon[];
239
+ manifest?: any;
240
+ colors: Colors;
241
+ typography: Typography;
242
+ spacing: Spacing;
243
+ borderRadius: BorderRadius;
244
+ borders: Borders;
245
+ shadows: Shadow[];
246
+ gradients?: Gradient[];
247
+ motion?: any;
248
+ components: Components;
249
+ breakpoints: Breakpoint[];
250
+ iconSystem: IconSystem[];
251
+ frameworks: Framework[];
252
+ wcag?: WcagPair[];
253
+ pages?: {
254
+ url: string;
255
+ }[];
256
+ /**
257
+ * CLI-emitted note about the extraction itself (e.g. canvas-only sites). This is
258
+ * NOT a user annotation — a user note belongs in the storage envelope around the
259
+ * payload, never on the pristine BrandingResult, or it mutates the payload.
260
+ */
261
+ note?: string;
262
+ isCanvasOnly?: boolean;
263
+ /** Internal/transient fields used during crawl + merge. Never persist; see stripTransient(). */
264
+ _discoveredLinks?: any[];
265
+ _extractedUrls?: any[];
266
+ _pageResults?: any[];
267
+ }
268
+ /**
269
+ * Storage envelope around a pristine BrandingResult payload. Identity, time, and
270
+ * user-facing annotations live HERE, never on the payload — putting them on the
271
+ * payload would mutate the immutable extraction and break drift comparison.
272
+ *
273
+ * This type is reserved for the storage/UI layer (dembrandt-next, drift). The CLI
274
+ * does not produce it; it is defined in core so every consumer agrees on one
275
+ * envelope shape instead of forking it. Build the notes/labels feature against
276
+ * `note`/`label` here — not against BrandingResult.note (which is CLI metadata).
277
+ */
278
+ export interface Snapshot {
279
+ id: string;
280
+ /** Which tracked surface (page/route/brand) this capture belongs to. */
281
+ surfaceId: string;
282
+ /** Owns identity + time, separate from payload.extractedAt. */
283
+ capturedAt: string;
284
+ /** The untouched extraction. */
285
+ payload: BrandingResult;
286
+ /** Optional human label for the capture. */
287
+ label?: string;
288
+ /** The customer's own note about this capture. NOT payload.note. */
289
+ note?: string;
290
+ }
291
+ /**
292
+ * Minimal spinner contract extractBranding() needs. A real ora `Ora` satisfies
293
+ * it structurally, as does the MCP null-spinner stub — so we don't pull ora's
294
+ * full type just to accept a progress reporter.
295
+ */
296
+ export interface Spinner {
297
+ text?: string;
298
+ start(text?: string): Spinner;
299
+ stop(): Spinner;
300
+ succeed(text?: string): Spinner;
301
+ fail(text?: string): Spinner;
302
+ warn(text?: string): Spinner;
303
+ info(text?: string): Spinner;
304
+ }
305
+ /** CLI / programmatic options accepted by extractBranding(). */
306
+ export interface ExtractOptions {
307
+ slow?: boolean;
308
+ darkMode?: boolean;
309
+ mobile?: boolean;
310
+ stealth?: boolean;
311
+ wcag?: boolean;
312
+ keepAnimations?: boolean;
313
+ verbose?: boolean;
314
+ navigationTimeout?: number;
315
+ screenshotPath?: string;
316
+ discoverLinks?: number | null;
317
+ includeRawColors?: boolean;
318
+ userAgent?: string;
319
+ locale?: string;
320
+ timezoneId?: string;
321
+ acceptLanguage?: string;
322
+ screenSize?: string;
323
+ cookie?: string;
324
+ header?: string;
325
+ /** Internal: collect raw :root tokens + interactive-state styles to a sidecar. */
326
+ teach?: boolean;
327
+ /** Injected CLI version, surfaced as meta.dembrandtVersion. */
328
+ _version?: string;
329
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Shared types for dembrandt extraction output and CLI options.
3
+ * These were JSDoc @typedefs; promoted to real exported interfaces so the rest
4
+ * of the (now TypeScript) codebase can import and use them.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}