@brandsystem/mcp 0.3.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 +515 -0
- package/bin/brandsystem-mcp.mjs +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/brand-dir.d.ts +56 -0
- package/dist/lib/brand-dir.d.ts.map +1 -0
- package/dist/lib/brand-dir.js +270 -0
- package/dist/lib/brand-dir.js.map +1 -0
- package/dist/lib/color-namer.d.ts +28 -0
- package/dist/lib/color-namer.d.ts.map +1 -0
- package/dist/lib/color-namer.js +155 -0
- package/dist/lib/color-namer.js.map +1 -0
- package/dist/lib/confidence.d.ts +19 -0
- package/dist/lib/confidence.d.ts.map +1 -0
- package/dist/lib/confidence.js +66 -0
- package/dist/lib/confidence.js.map +1 -0
- package/dist/lib/content-scorer.d.ts +38 -0
- package/dist/lib/content-scorer.d.ts.map +1 -0
- package/dist/lib/content-scorer.js +571 -0
- package/dist/lib/content-scorer.js.map +1 -0
- package/dist/lib/css-parser.d.ts +45 -0
- package/dist/lib/css-parser.d.ts.map +1 -0
- package/dist/lib/css-parser.js +330 -0
- package/dist/lib/css-parser.js.map +1 -0
- package/dist/lib/dtcg-compiler.d.ts +7 -0
- package/dist/lib/dtcg-compiler.d.ts.map +1 -0
- package/dist/lib/dtcg-compiler.js +89 -0
- package/dist/lib/dtcg-compiler.js.map +1 -0
- package/dist/lib/interaction-policy-compiler.d.ts +40 -0
- package/dist/lib/interaction-policy-compiler.d.ts.map +1 -0
- package/dist/lib/interaction-policy-compiler.js +60 -0
- package/dist/lib/interaction-policy-compiler.js.map +1 -0
- package/dist/lib/logo-extractor.d.ts +49 -0
- package/dist/lib/logo-extractor.d.ts.map +1 -0
- package/dist/lib/logo-extractor.js +384 -0
- package/dist/lib/logo-extractor.js.map +1 -0
- package/dist/lib/report-html.d.ts +20 -0
- package/dist/lib/report-html.d.ts.map +1 -0
- package/dist/lib/report-html.js +938 -0
- package/dist/lib/report-html.js.map +1 -0
- package/dist/lib/response.d.ts +20 -0
- package/dist/lib/response.d.ts.map +1 -0
- package/dist/lib/response.js +54 -0
- package/dist/lib/response.js.map +1 -0
- package/dist/lib/runtime-compiler.d.ts +60 -0
- package/dist/lib/runtime-compiler.d.ts.map +1 -0
- package/dist/lib/runtime-compiler.js +96 -0
- package/dist/lib/runtime-compiler.js.map +1 -0
- package/dist/lib/svg-resolver.d.ts +21 -0
- package/dist/lib/svg-resolver.d.ts.map +1 -0
- package/dist/lib/svg-resolver.js +115 -0
- package/dist/lib/svg-resolver.js.map +1 -0
- package/dist/lib/url-validator.d.ts +11 -0
- package/dist/lib/url-validator.d.ts.map +1 -0
- package/dist/lib/url-validator.js +93 -0
- package/dist/lib/url-validator.js.map +1 -0
- package/dist/lib/version.d.ts +2 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +19 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/lib/vim-generator.d.ts +13 -0
- package/dist/lib/vim-generator.d.ts.map +1 -0
- package/dist/lib/vim-generator.js +718 -0
- package/dist/lib/vim-generator.js.map +1 -0
- package/dist/resources/brand-resources.d.ts +4 -0
- package/dist/resources/brand-resources.d.ts.map +1 -0
- package/dist/resources/brand-resources.js +34 -0
- package/dist/resources/brand-resources.js.map +1 -0
- package/dist/schemas/brand-config.d.ts +28 -0
- package/dist/schemas/brand-config.d.ts.map +1 -0
- package/dist/schemas/brand-config.js +11 -0
- package/dist/schemas/brand-config.js.map +1 -0
- package/dist/schemas/brand-runtime.d.ts +251 -0
- package/dist/schemas/brand-runtime.d.ts.map +1 -0
- package/dist/schemas/brand-runtime.js +54 -0
- package/dist/schemas/brand-runtime.js.map +1 -0
- package/dist/schemas/core-identity.d.ts +302 -0
- package/dist/schemas/core-identity.d.ts.map +1 -0
- package/dist/schemas/core-identity.js +51 -0
- package/dist/schemas/core-identity.js.map +1 -0
- package/dist/schemas/index.d.ts +11 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +11 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/interaction-policy.d.ts +150 -0
- package/dist/schemas/interaction-policy.d.ts.map +1 -0
- package/dist/schemas/interaction-policy.js +34 -0
- package/dist/schemas/interaction-policy.js.map +1 -0
- package/dist/schemas/messaging.d.ts +776 -0
- package/dist/schemas/messaging.d.ts.map +1 -0
- package/dist/schemas/messaging.js +68 -0
- package/dist/schemas/messaging.js.map +1 -0
- package/dist/schemas/needs-clarification.d.ts +62 -0
- package/dist/schemas/needs-clarification.d.ts.map +1 -0
- package/dist/schemas/needs-clarification.js +13 -0
- package/dist/schemas/needs-clarification.js.map +1 -0
- package/dist/schemas/strategy.d.ts +537 -0
- package/dist/schemas/strategy.d.ts.map +1 -0
- package/dist/schemas/strategy.js +71 -0
- package/dist/schemas/strategy.js.map +1 -0
- package/dist/schemas/tokens.d.ts +35 -0
- package/dist/schemas/tokens.d.ts.map +1 -0
- package/dist/schemas/tokens.js +15 -0
- package/dist/schemas/tokens.js.map +1 -0
- package/dist/schemas/visual-identity.d.ts +224 -0
- package/dist/schemas/visual-identity.d.ts.map +1 -0
- package/dist/schemas/visual-identity.js +42 -0
- package/dist/schemas/visual-identity.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +75 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/brand-audit-content.d.ts +3 -0
- package/dist/tools/brand-audit-content.d.ts.map +1 -0
- package/dist/tools/brand-audit-content.js +116 -0
- package/dist/tools/brand-audit-content.js.map +1 -0
- package/dist/tools/brand-audit-drift.d.ts +3 -0
- package/dist/tools/brand-audit-drift.d.ts.map +1 -0
- package/dist/tools/brand-audit-drift.js +301 -0
- package/dist/tools/brand-audit-drift.js.map +1 -0
- package/dist/tools/brand-audit.d.ts +3 -0
- package/dist/tools/brand-audit.d.ts.map +1 -0
- package/dist/tools/brand-audit.js +129 -0
- package/dist/tools/brand-audit.js.map +1 -0
- package/dist/tools/brand-build-journey.d.ts +3 -0
- package/dist/tools/brand-build-journey.d.ts.map +1 -0
- package/dist/tools/brand-build-journey.js +312 -0
- package/dist/tools/brand-build-journey.js.map +1 -0
- package/dist/tools/brand-build-matrix.d.ts +3 -0
- package/dist/tools/brand-build-matrix.d.ts.map +1 -0
- package/dist/tools/brand-build-matrix.js +525 -0
- package/dist/tools/brand-build-matrix.js.map +1 -0
- package/dist/tools/brand-build-personas.d.ts +3 -0
- package/dist/tools/brand-build-personas.d.ts.map +1 -0
- package/dist/tools/brand-build-personas.js +436 -0
- package/dist/tools/brand-build-personas.js.map +1 -0
- package/dist/tools/brand-build-themes.d.ts +3 -0
- package/dist/tools/brand-build-themes.d.ts.map +1 -0
- package/dist/tools/brand-build-themes.js +476 -0
- package/dist/tools/brand-build-themes.js.map +1 -0
- package/dist/tools/brand-check-compliance.d.ts +3 -0
- package/dist/tools/brand-check-compliance.d.ts.map +1 -0
- package/dist/tools/brand-check-compliance.js +243 -0
- package/dist/tools/brand-check-compliance.js.map +1 -0
- package/dist/tools/brand-clarify.d.ts +21 -0
- package/dist/tools/brand-clarify.d.ts.map +1 -0
- package/dist/tools/brand-clarify.js +497 -0
- package/dist/tools/brand-clarify.js.map +1 -0
- package/dist/tools/brand-compile-messaging.d.ts +3 -0
- package/dist/tools/brand-compile-messaging.d.ts.map +1 -0
- package/dist/tools/brand-compile-messaging.js +759 -0
- package/dist/tools/brand-compile-messaging.js.map +1 -0
- package/dist/tools/brand-compile.d.ts +3 -0
- package/dist/tools/brand-compile.d.ts.map +1 -0
- package/dist/tools/brand-compile.js +182 -0
- package/dist/tools/brand-compile.js.map +1 -0
- package/dist/tools/brand-deepen-identity.d.ts +3 -0
- package/dist/tools/brand-deepen-identity.d.ts.map +1 -0
- package/dist/tools/brand-deepen-identity.js +483 -0
- package/dist/tools/brand-deepen-identity.js.map +1 -0
- package/dist/tools/brand-export.d.ts +17 -0
- package/dist/tools/brand-export.d.ts.map +1 -0
- package/dist/tools/brand-export.js +730 -0
- package/dist/tools/brand-export.js.map +1 -0
- package/dist/tools/brand-extract-figma.d.ts +3 -0
- package/dist/tools/brand-extract-figma.d.ts.map +1 -0
- package/dist/tools/brand-extract-figma.js +174 -0
- package/dist/tools/brand-extract-figma.js.map +1 -0
- package/dist/tools/brand-extract-messaging.d.ts +3 -0
- package/dist/tools/brand-extract-messaging.d.ts.map +1 -0
- package/dist/tools/brand-extract-messaging.js +620 -0
- package/dist/tools/brand-extract-messaging.js.map +1 -0
- package/dist/tools/brand-extract-web.d.ts +3 -0
- package/dist/tools/brand-extract-web.d.ts.map +1 -0
- package/dist/tools/brand-extract-web.js +477 -0
- package/dist/tools/brand-extract-web.js.map +1 -0
- package/dist/tools/brand-feedback.d.ts +3 -0
- package/dist/tools/brand-feedback.d.ts.map +1 -0
- package/dist/tools/brand-feedback.js +366 -0
- package/dist/tools/brand-feedback.js.map +1 -0
- package/dist/tools/brand-ingest-assets.d.ts +3 -0
- package/dist/tools/brand-ingest-assets.d.ts.map +1 -0
- package/dist/tools/brand-ingest-assets.js +233 -0
- package/dist/tools/brand-ingest-assets.js.map +1 -0
- package/dist/tools/brand-init.d.ts +3 -0
- package/dist/tools/brand-init.d.ts.map +1 -0
- package/dist/tools/brand-init.js +66 -0
- package/dist/tools/brand-init.js.map +1 -0
- package/dist/tools/brand-preflight.d.ts +3 -0
- package/dist/tools/brand-preflight.d.ts.map +1 -0
- package/dist/tools/brand-preflight.js +608 -0
- package/dist/tools/brand-preflight.js.map +1 -0
- package/dist/tools/brand-report.d.ts +3 -0
- package/dist/tools/brand-report.d.ts.map +1 -0
- package/dist/tools/brand-report.js +154 -0
- package/dist/tools/brand-report.js.map +1 -0
- package/dist/tools/brand-runtime.d.ts +3 -0
- package/dist/tools/brand-runtime.d.ts.map +1 -0
- package/dist/tools/brand-runtime.js +37 -0
- package/dist/tools/brand-runtime.js.map +1 -0
- package/dist/tools/brand-set-logo.d.ts +3 -0
- package/dist/tools/brand-set-logo.d.ts.map +1 -0
- package/dist/tools/brand-set-logo.js +170 -0
- package/dist/tools/brand-set-logo.js.map +1 -0
- package/dist/tools/brand-start.d.ts +3 -0
- package/dist/tools/brand-start.d.ts.map +1 -0
- package/dist/tools/brand-start.js +686 -0
- package/dist/tools/brand-start.js.map +1 -0
- package/dist/tools/brand-status.d.ts +3 -0
- package/dist/tools/brand-status.d.ts.map +1 -0
- package/dist/tools/brand-status.js +175 -0
- package/dist/tools/brand-status.js.map +1 -0
- package/dist/tools/brand-write.d.ts +3 -0
- package/dist/tools/brand-write.d.ts.map +1 -0
- package/dist/tools/brand-write.js +442 -0
- package/dist/tools/brand-write.js.map +1 -0
- package/dist/types/index.d.ts +331 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +52 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import * as csstree from "css-tree";
|
|
2
|
+
const COLOR_PROPERTIES = new Set([
|
|
3
|
+
"color",
|
|
4
|
+
"background-color",
|
|
5
|
+
"border-color",
|
|
6
|
+
"fill",
|
|
7
|
+
"stroke",
|
|
8
|
+
"outline-color",
|
|
9
|
+
"text-decoration-color",
|
|
10
|
+
]);
|
|
11
|
+
/** Convert rgb/rgba/hsl/named colors to hex */
|
|
12
|
+
function normalizeToHex(value) {
|
|
13
|
+
const trimmed = value.trim().toLowerCase();
|
|
14
|
+
// Already hex
|
|
15
|
+
if (/^#[0-9a-f]{3,8}$/.test(trimmed)) {
|
|
16
|
+
// Expand 3-char to 6-char
|
|
17
|
+
if (trimmed.length === 4) {
|
|
18
|
+
return `#${trimmed[1]}${trimmed[1]}${trimmed[2]}${trimmed[2]}${trimmed[3]}${trimmed[3]}`;
|
|
19
|
+
}
|
|
20
|
+
return trimmed;
|
|
21
|
+
}
|
|
22
|
+
// rgb(r, g, b) or rgba(r, g, b, a)
|
|
23
|
+
const rgbMatch = trimmed.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})/);
|
|
24
|
+
if (rgbMatch) {
|
|
25
|
+
const r = parseInt(rgbMatch[1], 10);
|
|
26
|
+
const g = parseInt(rgbMatch[2], 10);
|
|
27
|
+
const b = parseInt(rgbMatch[3], 10);
|
|
28
|
+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
29
|
+
}
|
|
30
|
+
// Named colors (commonly used CSS named colors)
|
|
31
|
+
const NAMED = {
|
|
32
|
+
white: "#ffffff",
|
|
33
|
+
black: "#000000",
|
|
34
|
+
red: "#ff0000",
|
|
35
|
+
blue: "#0000ff",
|
|
36
|
+
green: "#008000",
|
|
37
|
+
transparent: "#00000000",
|
|
38
|
+
navy: "#000080",
|
|
39
|
+
teal: "#008080",
|
|
40
|
+
orange: "#ffa500",
|
|
41
|
+
purple: "#800080",
|
|
42
|
+
gray: "#808080",
|
|
43
|
+
grey: "#808080",
|
|
44
|
+
silver: "#c0c0c0",
|
|
45
|
+
maroon: "#800000",
|
|
46
|
+
olive: "#808000",
|
|
47
|
+
lime: "#00ff00",
|
|
48
|
+
aqua: "#00ffff",
|
|
49
|
+
fuchsia: "#ff00ff",
|
|
50
|
+
yellow: "#ffff00",
|
|
51
|
+
coral: "#ff7f50",
|
|
52
|
+
tomato: "#ff6347",
|
|
53
|
+
salmon: "#fa8072",
|
|
54
|
+
gold: "#ffd700",
|
|
55
|
+
indigo: "#4b0082",
|
|
56
|
+
violet: "#ee82ee",
|
|
57
|
+
pink: "#ffc0cb",
|
|
58
|
+
cyan: "#00ffff",
|
|
59
|
+
magenta: "#ff00ff",
|
|
60
|
+
crimson: "#dc143c",
|
|
61
|
+
turquoise: "#40e0d0",
|
|
62
|
+
wheat: "#f5deb3",
|
|
63
|
+
ivory: "#fffff0",
|
|
64
|
+
linen: "#faf0e6",
|
|
65
|
+
beige: "#f5f5dc",
|
|
66
|
+
khaki: "#f0e68c",
|
|
67
|
+
plum: "#dda0dd",
|
|
68
|
+
orchid: "#da70d6",
|
|
69
|
+
rebeccapurple: "#663399",
|
|
70
|
+
darkblue: "#00008b",
|
|
71
|
+
darkgreen: "#006400",
|
|
72
|
+
darkred: "#8b0000",
|
|
73
|
+
darkgray: "#a9a9a9",
|
|
74
|
+
darkgrey: "#a9a9a9",
|
|
75
|
+
lightblue: "#add8e6",
|
|
76
|
+
lightgreen: "#90ee90",
|
|
77
|
+
lightgray: "#d3d3d3",
|
|
78
|
+
lightgrey: "#d3d3d3",
|
|
79
|
+
midnightblue: "#191970",
|
|
80
|
+
steelblue: "#4682b4",
|
|
81
|
+
slategray: "#708090",
|
|
82
|
+
slategrey: "#708090",
|
|
83
|
+
};
|
|
84
|
+
if (NAMED[trimmed])
|
|
85
|
+
return NAMED[trimmed];
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
// ── Structural selector detection ────────────────────────────────
|
|
89
|
+
// Colors found in these selectors are the brand's structural colors (chrome).
|
|
90
|
+
// Colors only in content selectors are likely from showcased content.
|
|
91
|
+
const STRUCTURAL_SELECTORS = /^(html|body|:root|\*|header|nav|footer|\.header|\.nav|\.footer|\.navbar|\.site-header|\.site-footer|\.topbar|\.sidebar|\.menu|\.brand|a|a:hover|a:visited|button|\.btn|\.button|input|select|textarea|h[1-6]|p|\.text|\.heading|\.title)/i;
|
|
92
|
+
const CONTENT_SELECTORS = /\.(case-study|portfolio|project|article|post|blog|story|card|hero-image|featured|showcase|editorial|gallery|client|work-item|testimonial)/i;
|
|
93
|
+
function isStructuralSelector(selector) {
|
|
94
|
+
return STRUCTURAL_SELECTORS.test(selector.trim());
|
|
95
|
+
}
|
|
96
|
+
function isContentSelector(selector) {
|
|
97
|
+
return CONTENT_SELECTORS.test(selector.trim());
|
|
98
|
+
}
|
|
99
|
+
/** Parse CSS text and extract colors + fonts */
|
|
100
|
+
export function extractFromCSS(cssText) {
|
|
101
|
+
const colorMap = new Map();
|
|
102
|
+
const fontMap = new Map();
|
|
103
|
+
let ast;
|
|
104
|
+
try {
|
|
105
|
+
ast = csstree.parse(cssText, { parseCustomProperty: true });
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return { colors: [], fonts: [] };
|
|
109
|
+
}
|
|
110
|
+
// Track current rule's selector for context
|
|
111
|
+
let currentSelector = "";
|
|
112
|
+
csstree.walk(ast, {
|
|
113
|
+
enter(node) {
|
|
114
|
+
// Track the selector of the current rule
|
|
115
|
+
if (node.type === "Rule" && node.prelude) {
|
|
116
|
+
currentSelector = csstree.generate(node.prelude);
|
|
117
|
+
}
|
|
118
|
+
if (node.type !== "Declaration")
|
|
119
|
+
return;
|
|
120
|
+
const property = node.property;
|
|
121
|
+
// CSS custom properties that look like colors (HIGHEST priority — always brand)
|
|
122
|
+
if (property.startsWith("--")) {
|
|
123
|
+
const raw = csstree.generate(node.value);
|
|
124
|
+
const hex = normalizeToHex(raw);
|
|
125
|
+
if (hex && hex !== "#00000000") {
|
|
126
|
+
const existing = colorMap.get(hex);
|
|
127
|
+
if (existing) {
|
|
128
|
+
existing.frequency++;
|
|
129
|
+
// CSS variables are always brand colors — upgrade to css-variable
|
|
130
|
+
if (existing.source_type !== "css-variable") {
|
|
131
|
+
existing.source_type = "css-variable";
|
|
132
|
+
existing.property = property;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
colorMap.set(hex, {
|
|
137
|
+
value: hex,
|
|
138
|
+
property,
|
|
139
|
+
frequency: 1,
|
|
140
|
+
source_type: "css-variable",
|
|
141
|
+
selector_context: currentSelector,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Color properties
|
|
147
|
+
if (COLOR_PROPERTIES.has(property)) {
|
|
148
|
+
const raw = csstree.generate(node.value);
|
|
149
|
+
const hex = normalizeToHex(raw);
|
|
150
|
+
if (hex && hex !== "#00000000") {
|
|
151
|
+
// Determine if this is a structural or content color
|
|
152
|
+
const isStructural = isStructuralSelector(currentSelector);
|
|
153
|
+
const isContent = isContentSelector(currentSelector);
|
|
154
|
+
const existing = colorMap.get(hex);
|
|
155
|
+
if (existing) {
|
|
156
|
+
existing.frequency++;
|
|
157
|
+
// Upgrade to structural if found in structural selector
|
|
158
|
+
if (isStructural && existing.source_type === "computed") {
|
|
159
|
+
existing.source_type = "structural";
|
|
160
|
+
existing.property = property;
|
|
161
|
+
existing.selector_context = currentSelector;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
colorMap.set(hex, {
|
|
166
|
+
value: hex,
|
|
167
|
+
property,
|
|
168
|
+
frequency: isContent ? 0 : 1, // Content colors start at 0 frequency (deprioritized)
|
|
169
|
+
source_type: isStructural ? "structural" : "computed",
|
|
170
|
+
selector_context: currentSelector,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Font families
|
|
176
|
+
if (property === "font-family") {
|
|
177
|
+
const raw = csstree.generate(node.value);
|
|
178
|
+
const families = raw
|
|
179
|
+
.split(",")
|
|
180
|
+
.map((f) => f.trim().replace(/^["']|["']$/g, ""))
|
|
181
|
+
.filter((f) => !isSystemFont(f));
|
|
182
|
+
for (const family of families) {
|
|
183
|
+
fontMap.set(family, (fontMap.get(family) || 0) + 1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
// Sort with priority: css-variable > structural > computed, then by frequency
|
|
189
|
+
const sourceWeight = (t) => t === "css-variable" ? 100 : t === "structural" ? 50 : 0;
|
|
190
|
+
const colors = Array.from(colorMap.values()).sort((a, b) => (sourceWeight(b.source_type) + b.frequency) - (sourceWeight(a.source_type) + a.frequency));
|
|
191
|
+
const fonts = Array.from(fontMap.entries())
|
|
192
|
+
.map(([family, frequency]) => ({ family, frequency }))
|
|
193
|
+
.sort((a, b) => b.frequency - a.frequency);
|
|
194
|
+
return { colors, fonts };
|
|
195
|
+
}
|
|
196
|
+
/** CSS generic families + platform system fonts that are never brand fonts */
|
|
197
|
+
const SYSTEM_FONTS = new Set([
|
|
198
|
+
// CSS generic families
|
|
199
|
+
"serif", "sans-serif", "monospace", "cursive", "fantasy",
|
|
200
|
+
"system-ui", "ui-serif", "ui-sans-serif", "ui-monospace",
|
|
201
|
+
"ui-rounded", "emoji", "math", "fangsong",
|
|
202
|
+
// CSS keywords
|
|
203
|
+
"inherit", "initial", "unset", "revert",
|
|
204
|
+
// Apple system fonts
|
|
205
|
+
"-apple-system", "blinkmacsystemfont",
|
|
206
|
+
"sf pro", "sf pro display", "sf pro text", "sf pro rounded",
|
|
207
|
+
// Apple monospace fallbacks
|
|
208
|
+
"sfmono-regular", "sf mono", "menlo", "monaco",
|
|
209
|
+
// Windows system fonts
|
|
210
|
+
"segoe ui", "segoe ui emoji", "segoe ui symbol",
|
|
211
|
+
// Cross-platform monospace fallbacks
|
|
212
|
+
"consolas", "liberation mono", "courier new", "courier",
|
|
213
|
+
// Android
|
|
214
|
+
"roboto mono", "droid sans mono",
|
|
215
|
+
]);
|
|
216
|
+
function isSystemFont(name) {
|
|
217
|
+
return SYSTEM_FONTS.has(name.toLowerCase());
|
|
218
|
+
}
|
|
219
|
+
// --- Color analysis utilities ---
|
|
220
|
+
function hexToRGB(hex) {
|
|
221
|
+
const h = hex.replace("#", "");
|
|
222
|
+
return {
|
|
223
|
+
r: parseInt(h.substring(0, 2), 16),
|
|
224
|
+
g: parseInt(h.substring(2, 4), 16),
|
|
225
|
+
b: parseInt(h.substring(4, 6), 16),
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
function relativeLuminance(hex) {
|
|
229
|
+
const { r, g, b } = hexToRGB(hex);
|
|
230
|
+
const [rl, gl, bl] = [r, g, b].map((c) => {
|
|
231
|
+
const s = c / 255;
|
|
232
|
+
return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
|
|
233
|
+
});
|
|
234
|
+
return 0.2126 * rl + 0.7152 * gl + 0.0722 * bl;
|
|
235
|
+
}
|
|
236
|
+
export function isNearWhite(hex) {
|
|
237
|
+
return relativeLuminance(hex) > 0.85;
|
|
238
|
+
}
|
|
239
|
+
export function isNearBlack(hex) {
|
|
240
|
+
return relativeLuminance(hex) < 0.05;
|
|
241
|
+
}
|
|
242
|
+
/** Low saturation = gray/neutral */
|
|
243
|
+
export function isNeutral(hex) {
|
|
244
|
+
const { r, g, b } = hexToRGB(hex);
|
|
245
|
+
return (Math.max(r, g, b) - Math.min(r, g, b)) < 30;
|
|
246
|
+
}
|
|
247
|
+
/** Has noticeable hue — not white, black, or gray */
|
|
248
|
+
export function isChromatic(hex) {
|
|
249
|
+
return !isNeutral(hex) && !isNearWhite(hex) && !isNearBlack(hex);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* After extraction, if no primary color was identified, promote the
|
|
253
|
+
* most frequent chromatic color. Returns a new array.
|
|
254
|
+
*
|
|
255
|
+
* The promoted color gets `_promoted_role: "primary"` and
|
|
256
|
+
* `_promoted_confidence: "low"` so downstream can surface it
|
|
257
|
+
* as a confirmation item rather than treating it as certain.
|
|
258
|
+
*/
|
|
259
|
+
export function promotePrimaryColor(colors) {
|
|
260
|
+
const hasExplicitPrimary = colors.some((c) => inferColorRole(c) === "primary");
|
|
261
|
+
if (hasExplicitPrimary)
|
|
262
|
+
return colors;
|
|
263
|
+
// Find chromatic colors sorted by frequency
|
|
264
|
+
const chromatic = colors
|
|
265
|
+
.filter((c) => isChromatic(c.value))
|
|
266
|
+
.sort((a, b) => b.frequency - a.frequency);
|
|
267
|
+
if (chromatic.length === 0)
|
|
268
|
+
return colors;
|
|
269
|
+
// Tag the winner so the caller can detect it — low confidence since auto-promoted
|
|
270
|
+
const winner = chromatic[0];
|
|
271
|
+
return colors.map((c) => c === winner
|
|
272
|
+
? { ...c, _promoted_role: "primary", _promoted_confidence: "low" }
|
|
273
|
+
: c);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Get the top chromatic color candidates from extraction results.
|
|
277
|
+
* Used by the confirmation flow to show the user color options.
|
|
278
|
+
*/
|
|
279
|
+
export function getTopChromaticCandidates(colors, max = 4) {
|
|
280
|
+
return colors
|
|
281
|
+
.filter((c) => isChromatic(c.value))
|
|
282
|
+
.sort((a, b) => b.frequency - a.frequency)
|
|
283
|
+
.slice(0, max)
|
|
284
|
+
.map((c) => c.value);
|
|
285
|
+
}
|
|
286
|
+
/** Infer confidence from extraction quality */
|
|
287
|
+
export function inferColorConfidence(color) {
|
|
288
|
+
if (color.source_type === "css-variable" && color.frequency >= 3)
|
|
289
|
+
return "high";
|
|
290
|
+
if (color.source_type === "css-variable")
|
|
291
|
+
return "medium";
|
|
292
|
+
if (color.source_type === "structural" && color.frequency >= 3)
|
|
293
|
+
return "high";
|
|
294
|
+
if (color.source_type === "structural")
|
|
295
|
+
return "medium";
|
|
296
|
+
if (color.frequency >= 5)
|
|
297
|
+
return "medium";
|
|
298
|
+
return "low";
|
|
299
|
+
}
|
|
300
|
+
/** Infer role from CSS property/variable name, then fall back to value heuristics */
|
|
301
|
+
export function inferColorRole(color) {
|
|
302
|
+
// Promotion override from promotePrimaryColor()
|
|
303
|
+
if (color._promoted_role === "primary")
|
|
304
|
+
return "primary";
|
|
305
|
+
const prop = color.property.toLowerCase();
|
|
306
|
+
// CSS variable name heuristics
|
|
307
|
+
if (prop.includes("primary") || prop.includes("brand"))
|
|
308
|
+
return "primary";
|
|
309
|
+
if (prop.includes("secondary"))
|
|
310
|
+
return "secondary";
|
|
311
|
+
if (prop.includes("accent"))
|
|
312
|
+
return "accent";
|
|
313
|
+
if (prop.includes("neutral") || prop.includes("gray") || prop.includes("grey"))
|
|
314
|
+
return "neutral";
|
|
315
|
+
if (prop.includes("surface") || prop.includes("bg") || prop.includes("background"))
|
|
316
|
+
return "surface";
|
|
317
|
+
if (prop.includes("text") || prop.includes("foreground"))
|
|
318
|
+
return "text";
|
|
319
|
+
if (prop.includes("action") || prop.includes("cta") || prop.includes("button"))
|
|
320
|
+
return "action";
|
|
321
|
+
// Value-based heuristics (when CSS names give no signal)
|
|
322
|
+
if (isNearWhite(color.value))
|
|
323
|
+
return "surface";
|
|
324
|
+
if (isNearBlack(color.value))
|
|
325
|
+
return "text";
|
|
326
|
+
if (isNeutral(color.value))
|
|
327
|
+
return "neutral";
|
|
328
|
+
return "unknown";
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=css-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-parser.js","sourceRoot":"","sources":["../../src/lib/css-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CoreIdentityData } from "../schemas/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compile core-identity.yaml into DTCG tokens.json format.
|
|
4
|
+
* Only includes values with medium+ confidence.
|
|
5
|
+
*/
|
|
6
|
+
export declare function compileDTCG(identity: CoreIdentityData, clientName: string): Record<string, unknown>;
|
|
7
|
+
//# sourceMappingURL=dtcg-compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dtcg-compiler.d.ts","sourceRoot":"","sources":["../../src/lib/dtcg-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D;;;GAGG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { isTokenWorthy } from "./confidence.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compile core-identity.yaml into DTCG tokens.json format.
|
|
4
|
+
* Only includes values with medium+ confidence.
|
|
5
|
+
*/
|
|
6
|
+
export function compileDTCG(identity, clientName) {
|
|
7
|
+
const tokens = {
|
|
8
|
+
$name: `${clientName} Design Tokens`,
|
|
9
|
+
$description: `Generated by brandsystem.app — schema 0.1.0`,
|
|
10
|
+
brand: {
|
|
11
|
+
color: compileColors(identity.colors),
|
|
12
|
+
typography: compileTypography(identity.typography),
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
if (identity.spacing) {
|
|
16
|
+
tokens.brand.spacing = compileSpacing(identity.spacing);
|
|
17
|
+
}
|
|
18
|
+
return tokens;
|
|
19
|
+
}
|
|
20
|
+
function compileColors(colors) {
|
|
21
|
+
const group = {};
|
|
22
|
+
for (const color of colors) {
|
|
23
|
+
if (!isTokenWorthy(color.confidence))
|
|
24
|
+
continue;
|
|
25
|
+
const key = color.role === "unknown" ? slugify(color.name) : color.role;
|
|
26
|
+
group[key] = {
|
|
27
|
+
$value: color.value,
|
|
28
|
+
$type: "color",
|
|
29
|
+
$description: color.name,
|
|
30
|
+
$extensions: {
|
|
31
|
+
"com.brandsystem": {
|
|
32
|
+
source: color.source,
|
|
33
|
+
confidence: color.confidence,
|
|
34
|
+
...(color.figma_variable_id && { figmaVariableId: color.figma_variable_id }),
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return group;
|
|
40
|
+
}
|
|
41
|
+
function compileTypography(typography) {
|
|
42
|
+
const group = {};
|
|
43
|
+
for (const entry of typography) {
|
|
44
|
+
if (!isTokenWorthy(entry.confidence))
|
|
45
|
+
continue;
|
|
46
|
+
const key = slugify(entry.name);
|
|
47
|
+
const typeGroup = {
|
|
48
|
+
family: {
|
|
49
|
+
$value: entry.family,
|
|
50
|
+
$type: "fontFamily",
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
if (entry.size) {
|
|
54
|
+
typeGroup.size = { $value: entry.size, $type: "dimension" };
|
|
55
|
+
}
|
|
56
|
+
if (entry.weight) {
|
|
57
|
+
typeGroup.weight = { $value: entry.weight, $type: "fontWeight" };
|
|
58
|
+
}
|
|
59
|
+
if (entry.line_height) {
|
|
60
|
+
typeGroup.lineHeight = { $value: entry.line_height, $type: "dimension" };
|
|
61
|
+
}
|
|
62
|
+
group[key] = typeGroup;
|
|
63
|
+
}
|
|
64
|
+
return group;
|
|
65
|
+
}
|
|
66
|
+
function compileSpacing(spacing) {
|
|
67
|
+
if (!isTokenWorthy(spacing.confidence))
|
|
68
|
+
return {};
|
|
69
|
+
const group = {};
|
|
70
|
+
if (spacing.base_unit) {
|
|
71
|
+
group.base = { $value: spacing.base_unit, $type: "dimension" };
|
|
72
|
+
}
|
|
73
|
+
if (spacing.scale) {
|
|
74
|
+
for (let i = 0; i < spacing.scale.length; i++) {
|
|
75
|
+
group[`scale-${i + 1}`] = {
|
|
76
|
+
$value: `${spacing.scale[i]}px`,
|
|
77
|
+
$type: "dimension",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return group;
|
|
82
|
+
}
|
|
83
|
+
function slugify(name) {
|
|
84
|
+
return name
|
|
85
|
+
.toLowerCase()
|
|
86
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
87
|
+
.replace(/^-|-$/g, "");
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=dtcg-compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dtcg-compiler.js","sourceRoot":"","sources":["../../src/lib/dtcg-compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { VisualIdentityData, MessagingData, ContentStrategyData } from "../schemas/index.js";
|
|
2
|
+
export interface InteractionPolicy {
|
|
3
|
+
version: string;
|
|
4
|
+
compiled_at: string;
|
|
5
|
+
visual_rules: PolicyRule[];
|
|
6
|
+
voice_rules: VoicePolicyRules;
|
|
7
|
+
content_rules: ContentPolicyRules;
|
|
8
|
+
}
|
|
9
|
+
export interface PolicyRule {
|
|
10
|
+
id: string;
|
|
11
|
+
rule: string;
|
|
12
|
+
severity: "hard" | "soft";
|
|
13
|
+
category: "visual" | "voice" | "content";
|
|
14
|
+
}
|
|
15
|
+
export interface VoicePolicyRules {
|
|
16
|
+
never_say: string[];
|
|
17
|
+
ai_ism_patterns: string[];
|
|
18
|
+
tone_constraints: {
|
|
19
|
+
never_sounds_like: string;
|
|
20
|
+
avoid_patterns: string[];
|
|
21
|
+
} | null;
|
|
22
|
+
sentence_patterns: {
|
|
23
|
+
prefer: string[];
|
|
24
|
+
avoid: string[];
|
|
25
|
+
} | null;
|
|
26
|
+
}
|
|
27
|
+
export interface ContentPolicyRules {
|
|
28
|
+
claims_policies: Array<{
|
|
29
|
+
stage: string;
|
|
30
|
+
max_per_piece: number | null;
|
|
31
|
+
}>;
|
|
32
|
+
persona_count: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Compile interaction-policy.json from brand data.
|
|
36
|
+
* This is the automated rules engine — the enforceable subset of the brand system.
|
|
37
|
+
* Visual anti-patterns become hard/soft rules. Voice constraints become guardrails.
|
|
38
|
+
*/
|
|
39
|
+
export declare function compileInteractionPolicy(schemaVersion: string, visual: VisualIdentityData | null, messaging: MessagingData | null, strategy: ContentStrategyData | null): InteractionPolicy;
|
|
40
|
+
//# sourceMappingURL=interaction-policy-compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction-policy-compiler.d.ts","sourceRoot":"","sources":["../../src/lib/interaction-policy-compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAElG,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,UAAU,EAAE,CAAC;IAC3B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,EAAE,kBAAkB,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,EAAE;QAChB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;KAC1B,GAAG,IAAI,CAAC;IACT,iBAAiB,EAAE;QACjB,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,KAAK,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;KAC9B,CAAC,CAAC;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,kBAAkB,GAAG,IAAI,EACjC,SAAS,EAAE,aAAa,GAAG,IAAI,EAC/B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GACnC,iBAAiB,CAQnB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile interaction-policy.json from brand data.
|
|
3
|
+
* This is the automated rules engine — the enforceable subset of the brand system.
|
|
4
|
+
* Visual anti-patterns become hard/soft rules. Voice constraints become guardrails.
|
|
5
|
+
*/
|
|
6
|
+
export function compileInteractionPolicy(schemaVersion, visual, messaging, strategy) {
|
|
7
|
+
return {
|
|
8
|
+
version: schemaVersion,
|
|
9
|
+
compiled_at: new Date().toISOString(),
|
|
10
|
+
visual_rules: compileVisualRules(visual),
|
|
11
|
+
voice_rules: compileVoiceRules(messaging),
|
|
12
|
+
content_rules: compileContentRules(strategy),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function compileVisualRules(visual) {
|
|
16
|
+
if (!visual)
|
|
17
|
+
return [];
|
|
18
|
+
return visual.anti_patterns.map((ap, i) => ({
|
|
19
|
+
id: ap.preflight_id ?? `visual-${i + 1}`,
|
|
20
|
+
rule: ap.rule,
|
|
21
|
+
severity: ap.severity,
|
|
22
|
+
category: "visual",
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
function compileVoiceRules(messaging) {
|
|
26
|
+
if (!messaging?.voice) {
|
|
27
|
+
return {
|
|
28
|
+
never_say: [],
|
|
29
|
+
ai_ism_patterns: [],
|
|
30
|
+
tone_constraints: null,
|
|
31
|
+
sentence_patterns: null,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const voice = messaging.voice;
|
|
35
|
+
return {
|
|
36
|
+
never_say: voice.vocabulary.never_say.map(ns => ns.word),
|
|
37
|
+
ai_ism_patterns: voice.ai_ism_detection.patterns,
|
|
38
|
+
tone_constraints: {
|
|
39
|
+
never_sounds_like: voice.tone.never_sounds_like,
|
|
40
|
+
avoid_patterns: voice.tone.sentence_patterns.avoid,
|
|
41
|
+
},
|
|
42
|
+
sentence_patterns: {
|
|
43
|
+
prefer: voice.tone.sentence_patterns.prefer,
|
|
44
|
+
avoid: voice.tone.sentence_patterns.avoid,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function compileContentRules(strategy) {
|
|
49
|
+
if (!strategy) {
|
|
50
|
+
return { claims_policies: [], persona_count: 0 };
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
claims_policies: strategy.journey_stages.map(js => ({
|
|
54
|
+
stage: js.name,
|
|
55
|
+
max_per_piece: js.claims_policy.max_per_piece,
|
|
56
|
+
})),
|
|
57
|
+
persona_count: strategy.personas.filter(p => p.status === "Active").length,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=interaction-policy-compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction-policy-compiler.js","sourceRoot":"","sources":["../../src/lib/interaction-policy-compiler.ts"],"names":[],"mappings":"AAsCA;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CACtC,aAAqB,EACrB,MAAiC,EACjC,SAA+B,EAC/B,QAAoC;IAEpC,OAAO;QACL,OAAO,EAAE,aAAa;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,YAAY,EAAE,kBAAkB,CAAC,MAAM,CAAC;QACxC,WAAW,EAAE,iBAAiB,CAAC,SAAS,CAAC;QACzC,aAAa,EAAE,mBAAmB,CAAC,QAAQ,CAAC;KAC7C,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAiC;IAC3D,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAEvB,OAAO,MAAM,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,EAAE,EAAE,EAAE,CAAC,YAAY,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE;QACxC,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,QAAQ,EAAE,EAAE,CAAC,QAAQ;QACrB,QAAQ,EAAE,QAAiB;KAC5B,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,iBAAiB,CAAC,SAA+B;IACxD,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;QACtB,OAAO;YACL,SAAS,EAAE,EAAE;YACb,eAAe,EAAE,EAAE;YACnB,gBAAgB,EAAE,IAAI;YACtB,iBAAiB,EAAE,IAAI;SACxB,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;IAC9B,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACxD,eAAe,EAAE,KAAK,CAAC,gBAAgB,CAAC,QAAQ;QAChD,gBAAgB,EAAE;YAChB,iBAAiB,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB;YAC/C,cAAc,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK;SACnD;QACD,iBAAiB,EAAE;YACjB,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM;YAC3C,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK;SAC1C;KACF,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,QAAoC;IAC/D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;IACnD,CAAC;IAED,OAAO;QACL,eAAe,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAClD,KAAK,EAAE,EAAE,CAAC,IAAI;YACd,aAAa,EAAE,EAAE,CAAC,aAAa,CAAC,aAAa;SAC9C,CAAC,CAAC;QACH,aAAa,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM;KAC3E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface ExtractedLogo {
|
|
2
|
+
url: string;
|
|
3
|
+
type: "og-image" | "svg-favicon" | "selector-img" | "selector-svg" | "apple-touch-icon" | "favicon" | "clearbit" | "common-path";
|
|
4
|
+
confidence: "high" | "medium" | "low";
|
|
5
|
+
/** Full SVG markup for inline SVGs (selector-svg type) */
|
|
6
|
+
inline_svg?: string;
|
|
7
|
+
/** Data URI for raster images (PNG/JPG) */
|
|
8
|
+
data_uri?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Extract logo candidates from HTML.
|
|
12
|
+
* Returns candidates sorted by confidence (best first).
|
|
13
|
+
* Filters out icons, social media SVGs, and client logo clouds.
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractLogos(html: string, baseUrl: string): ExtractedLogo[];
|
|
16
|
+
/**
|
|
17
|
+
* Try to find a logo via Clearbit's free Logo API.
|
|
18
|
+
* Returns a high-quality company logo PNG for most domains.
|
|
19
|
+
*/
|
|
20
|
+
export declare function fetchClearbitLogo(domain: string): Promise<ExtractedLogo | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Try common logo file paths on a domain.
|
|
23
|
+
* Many sites have predictable logo locations.
|
|
24
|
+
*/
|
|
25
|
+
export declare function probeCommonLogoPaths(baseUrl: string): Promise<ExtractedLogo | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Google's favicon service — GUARANTEED to return something for any domain.
|
|
28
|
+
* Returns a 256x256 favicon. This is the floor — we always get at least this.
|
|
29
|
+
*/
|
|
30
|
+
export declare function fetchGoogleFavicon(domain: string): Promise<ExtractedLogo | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Fetch any logo candidate URL and convert to a data URI.
|
|
33
|
+
* Works for SVG, PNG, JPG, ICO — anything fetchable.
|
|
34
|
+
* Returns both the raw content (for file writing) and a data_uri (for embedding).
|
|
35
|
+
*/
|
|
36
|
+
export declare function fetchAndEncodeLogo(url: string): Promise<{
|
|
37
|
+
content: Buffer;
|
|
38
|
+
contentType: string;
|
|
39
|
+
data_uri: string;
|
|
40
|
+
} | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Fetch a logo URL and return its content.
|
|
43
|
+
* Returns null if fetch fails or content is too large (>500KB).
|
|
44
|
+
*/
|
|
45
|
+
export declare function fetchLogo(url: string): Promise<{
|
|
46
|
+
content: Buffer;
|
|
47
|
+
contentType: string;
|
|
48
|
+
} | null>;
|
|
49
|
+
//# sourceMappingURL=logo-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logo-extractor.d.ts","sourceRoot":"","sources":["../../src/lib/logo-extractor.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,GAAG,kBAAkB,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;IACjI,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAsFD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CA+H3E;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAgCrF;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAwCzF;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA4BtF;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAwB5E;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAoB1D"}
|