@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,384 @@
|
|
|
1
|
+
import * as cheerio from "cheerio";
|
|
2
|
+
import { getVersion } from "./version.js";
|
|
3
|
+
import { safeFetch } from "./url-validator.js";
|
|
4
|
+
// ── Icon filtering ──────────────────────────────────────────────
|
|
5
|
+
// SVGs that are clearly NOT logos
|
|
6
|
+
const ICON_CLASSES = /chevron|arrow|close|hamburger|caret|toggle|spinner|loader|decoration|ornament|pattern/i;
|
|
7
|
+
// Separate patterns that are too broad as substrings — require word boundary or standalone class
|
|
8
|
+
const ICON_STANDALONE = /\b(icon|menu|search|play|pause)\b/i;
|
|
9
|
+
const ICON_DATA_ATTRS = /data-prefix="fa|data-icon|svg-inline--fa/;
|
|
10
|
+
const SOCIAL_ICONS = /twitter|instagram|facebook|linkedin|youtube|dribbble|github|tiktok|pinterest|reddit|discord|slack|whatsapp/i;
|
|
11
|
+
function isIconSvg($, el) {
|
|
12
|
+
// Override: if this SVG or its parent is explicitly labeled as a logo, it's NOT an icon
|
|
13
|
+
const ariaLabel = $(el).attr("aria-label") || "";
|
|
14
|
+
const parentClass = $(el).parent()?.attr("class") || "";
|
|
15
|
+
const parentHref = $(el).parent()?.attr("href") || "";
|
|
16
|
+
if (/logo|brand|wordmark/i.test(ariaLabel))
|
|
17
|
+
return false;
|
|
18
|
+
if (/logo|brand|wordmark/i.test(parentClass) && /home|\/$/i.test(parentHref))
|
|
19
|
+
return false;
|
|
20
|
+
const html = $.html(el);
|
|
21
|
+
const outerHtml = html || "";
|
|
22
|
+
// Social media icons (Font Awesome, etc.)
|
|
23
|
+
if (ICON_DATA_ATTRS.test(outerHtml))
|
|
24
|
+
return true;
|
|
25
|
+
if (SOCIAL_ICONS.test(outerHtml))
|
|
26
|
+
return true;
|
|
27
|
+
// Tiny utility icons (< 24px)
|
|
28
|
+
const width = parseInt($(el).attr("width") || "0", 10);
|
|
29
|
+
const height = parseInt($(el).attr("height") || "0", 10);
|
|
30
|
+
if (width > 0 && width < 24 && height > 0 && height < 24)
|
|
31
|
+
return true;
|
|
32
|
+
// Icon-named classes (exact patterns that don't substring-match in logo contexts)
|
|
33
|
+
const className = $(el).attr("class") || "";
|
|
34
|
+
if (ICON_CLASSES.test(className))
|
|
35
|
+
return true;
|
|
36
|
+
// Check parent class with standalone patterns (avoid "menu" matching "navigation-menu-home-link")
|
|
37
|
+
// Split parent class into individual classes and check each
|
|
38
|
+
const parentClasses = parentClass.split(/\s+/);
|
|
39
|
+
for (const cls of parentClasses) {
|
|
40
|
+
if (ICON_CLASSES.test(cls))
|
|
41
|
+
return true;
|
|
42
|
+
// Standalone check: only match if the class IS the word (e.g., "menu" but not "menu-home-link")
|
|
43
|
+
if (ICON_STANDALONE.test(cls) && cls.length < 20)
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
// ── Client logo cloud detection ─────────────────────────────────
|
|
49
|
+
// Detect when an img is inside a logo cloud/carousel (client logos, not the company logo)
|
|
50
|
+
const LOGO_CLOUD_CLASSES = /logo-cloud|logos|clients|partners|carousel|slider|marquee|trust|social-proof|logo-wall|logo-grid|logo-bar|logo-strip|companies|brands|featured-in|as-seen/i;
|
|
51
|
+
function isInLogoCloud($, el) {
|
|
52
|
+
// Check parents up to 4 levels
|
|
53
|
+
let current = $(el).parent();
|
|
54
|
+
for (let i = 0; i < 4; i++) {
|
|
55
|
+
if (!current.length)
|
|
56
|
+
break;
|
|
57
|
+
const cls = current.attr("class") || "";
|
|
58
|
+
const id = current.attr("id") || "";
|
|
59
|
+
if (LOGO_CLOUD_CLASSES.test(cls) || LOGO_CLOUD_CLASSES.test(id))
|
|
60
|
+
return true;
|
|
61
|
+
// If this parent has 3+ img children with "logo" in src, it's a logo cloud
|
|
62
|
+
const logoImgs = current.find('img[src*="logo"], img[data-src*="logo"]');
|
|
63
|
+
if (logoImgs.length >= 3)
|
|
64
|
+
return true;
|
|
65
|
+
current = current.parent();
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
// ── Size scoring ────────────────────────────────────────────────
|
|
70
|
+
function getSvgWidthScore(el, $) {
|
|
71
|
+
const width = parseInt($(el).attr("width") || "0", 10);
|
|
72
|
+
const viewBox = $(el).attr("viewBox");
|
|
73
|
+
let vbWidth = 0;
|
|
74
|
+
if (viewBox) {
|
|
75
|
+
const parts = viewBox.split(/\s+/);
|
|
76
|
+
if (parts.length === 4)
|
|
77
|
+
vbWidth = parseFloat(parts[2]);
|
|
78
|
+
}
|
|
79
|
+
const effectiveWidth = width || vbWidth;
|
|
80
|
+
if (effectiveWidth >= 80)
|
|
81
|
+
return 3; // Likely a meaningful logo
|
|
82
|
+
if (effectiveWidth >= 50)
|
|
83
|
+
return 1; // Possible
|
|
84
|
+
return -1; // Too small, probably an icon
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Extract logo candidates from HTML.
|
|
88
|
+
* Returns candidates sorted by confidence (best first).
|
|
89
|
+
* Filters out icons, social media SVGs, and client logo clouds.
|
|
90
|
+
*/
|
|
91
|
+
export function extractLogos(html, baseUrl) {
|
|
92
|
+
const $ = cheerio.load(html);
|
|
93
|
+
const logos = [];
|
|
94
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
95
|
+
function resolveUrl(href) {
|
|
96
|
+
if (!href)
|
|
97
|
+
return null;
|
|
98
|
+
if (href.startsWith("data:"))
|
|
99
|
+
return null;
|
|
100
|
+
if (href.startsWith("http"))
|
|
101
|
+
return href;
|
|
102
|
+
if (href.startsWith("//"))
|
|
103
|
+
return `https:${href}`;
|
|
104
|
+
if (href.startsWith("/"))
|
|
105
|
+
return `${base}${href}`;
|
|
106
|
+
return `${base}/${href}`;
|
|
107
|
+
}
|
|
108
|
+
// ── 1. Inline SVGs in header/nav (HIGHEST priority) ──────────
|
|
109
|
+
// The first meaningful SVG in header or nav is almost always the company logo
|
|
110
|
+
const headerNavSvgs = $("header svg, nav svg, .header svg, .navbar svg, .site-header svg");
|
|
111
|
+
for (let i = 0; i < headerNavSvgs.length; i++) {
|
|
112
|
+
const el = headerNavSvgs[i];
|
|
113
|
+
if (isIconSvg($, el))
|
|
114
|
+
continue;
|
|
115
|
+
const sizeScore = getSvgWidthScore(el, $);
|
|
116
|
+
if (sizeScore < 0)
|
|
117
|
+
continue; // Too small
|
|
118
|
+
const svgHtml = $.html(el);
|
|
119
|
+
if (!svgHtml || svgHtml.length < 50 || svgHtml.length > 100_000)
|
|
120
|
+
continue;
|
|
121
|
+
// Check for logo-related class/id on the SVG or its parent
|
|
122
|
+
const cls = $(el).attr("class") || "";
|
|
123
|
+
const parentCls = $(el).parent()?.attr("class") || "";
|
|
124
|
+
const parentId = $(el).parent()?.attr("id") || "";
|
|
125
|
+
const isLogoClassed = /logo|brand|wordmark|site-logo/i.test(cls + parentCls + parentId);
|
|
126
|
+
logos.push({
|
|
127
|
+
url: `inline:svg:${Buffer.from(svgHtml).toString("base64").substring(0, 40)}`,
|
|
128
|
+
type: "selector-svg",
|
|
129
|
+
confidence: isLogoClassed || sizeScore >= 3 ? "high" : "medium",
|
|
130
|
+
inline_svg: svgHtml,
|
|
131
|
+
});
|
|
132
|
+
// Only take the first good header SVG — it's almost always the logo
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
// ── 2. SVG favicon (clean logomark) ───────────────────────────
|
|
136
|
+
$('link[rel="icon"][type="image/svg+xml"]').each((_, el) => {
|
|
137
|
+
const url = resolveUrl($(el).attr("href"));
|
|
138
|
+
if (url)
|
|
139
|
+
logos.push({ url, type: "svg-favicon", confidence: "high" });
|
|
140
|
+
});
|
|
141
|
+
// ── 3. IMG tags in header/nav with logo indicators ────────────
|
|
142
|
+
const headerImgSelectors = [
|
|
143
|
+
'header img[src*="logo"]',
|
|
144
|
+
'header img[data-src*="logo"]',
|
|
145
|
+
'header img[alt*="logo" i]',
|
|
146
|
+
'nav img[src*="logo"]',
|
|
147
|
+
'nav img[data-src*="logo"]',
|
|
148
|
+
'.header img[src*="logo"]',
|
|
149
|
+
'.header img[data-src*="logo"]',
|
|
150
|
+
'a[href="/"] img',
|
|
151
|
+
];
|
|
152
|
+
for (const sel of headerImgSelectors) {
|
|
153
|
+
$(sel).each((_, el) => {
|
|
154
|
+
if (isInLogoCloud($, el))
|
|
155
|
+
return;
|
|
156
|
+
// Prefer data-src (lazy-loaded) over src
|
|
157
|
+
const url = resolveUrl($(el).attr("data-src") || $(el).attr("src"));
|
|
158
|
+
if (url)
|
|
159
|
+
logos.push({ url, type: "selector-img", confidence: "high" });
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// ── 4. Logo-classed elements (outside header) ─────────────────
|
|
163
|
+
const logoClassSelectors = [
|
|
164
|
+
'.logo img',
|
|
165
|
+
'#logo img',
|
|
166
|
+
'[class*="site-logo"] img',
|
|
167
|
+
'.logo svg',
|
|
168
|
+
'#logo svg',
|
|
169
|
+
];
|
|
170
|
+
for (const sel of logoClassSelectors) {
|
|
171
|
+
$(sel).each((_, el) => {
|
|
172
|
+
if (isInLogoCloud($, el))
|
|
173
|
+
return;
|
|
174
|
+
const tagName = el.tagName?.toLowerCase();
|
|
175
|
+
if (tagName === "svg") {
|
|
176
|
+
if (isIconSvg($, el))
|
|
177
|
+
return;
|
|
178
|
+
const svgHtml = $.html(el);
|
|
179
|
+
if (svgHtml && svgHtml.length > 50 && svgHtml.length < 100_000) {
|
|
180
|
+
logos.push({
|
|
181
|
+
url: `inline:svg:${Buffer.from(svgHtml).toString("base64").substring(0, 40)}`,
|
|
182
|
+
type: "selector-svg",
|
|
183
|
+
confidence: "medium",
|
|
184
|
+
inline_svg: svgHtml,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const url = resolveUrl($(el).attr("data-src") || $(el).attr("src"));
|
|
190
|
+
if (url)
|
|
191
|
+
logos.push({ url, type: "selector-img", confidence: "medium" });
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// ── 5. OG image ───────────────────────────────────────────────
|
|
196
|
+
const ogImage = $('meta[property="og:image"]').attr("content");
|
|
197
|
+
if (ogImage) {
|
|
198
|
+
const url = resolveUrl(ogImage);
|
|
199
|
+
if (url)
|
|
200
|
+
logos.push({ url, type: "og-image", confidence: "low" });
|
|
201
|
+
}
|
|
202
|
+
// ── 6. Apple touch icon ───────────────────────────────────────
|
|
203
|
+
$('link[rel="apple-touch-icon"]').each((_, el) => {
|
|
204
|
+
const url = resolveUrl($(el).attr("href"));
|
|
205
|
+
if (url)
|
|
206
|
+
logos.push({ url, type: "apple-touch-icon", confidence: "low" });
|
|
207
|
+
});
|
|
208
|
+
// ── 7. Standard favicon ───────────────────────────────────────
|
|
209
|
+
$('link[rel="icon"], link[rel="shortcut icon"]').each((_, el) => {
|
|
210
|
+
const url = resolveUrl($(el).attr("href"));
|
|
211
|
+
if (url)
|
|
212
|
+
logos.push({ url, type: "favicon", confidence: "low" });
|
|
213
|
+
});
|
|
214
|
+
// Deduplicate by URL
|
|
215
|
+
const seen = new Set();
|
|
216
|
+
return logos.filter((l) => {
|
|
217
|
+
if (seen.has(l.url))
|
|
218
|
+
return false;
|
|
219
|
+
seen.add(l.url);
|
|
220
|
+
return true;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Try to find a logo via Clearbit's free Logo API.
|
|
225
|
+
* Returns a high-quality company logo PNG for most domains.
|
|
226
|
+
*/
|
|
227
|
+
export async function fetchClearbitLogo(domain) {
|
|
228
|
+
const cleanDomain = domain.replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "");
|
|
229
|
+
const url = `https://logo.clearbit.com/${cleanDomain}`;
|
|
230
|
+
try {
|
|
231
|
+
const response = await safeFetch(url, {
|
|
232
|
+
signal: AbortSignal.timeout(5000),
|
|
233
|
+
headers: { "User-Agent": `brandsystem-mcp/${getVersion()}` },
|
|
234
|
+
});
|
|
235
|
+
if (!response.ok)
|
|
236
|
+
return null;
|
|
237
|
+
const contentType = response.headers.get("content-type") || "";
|
|
238
|
+
if (!contentType.includes("image"))
|
|
239
|
+
return null;
|
|
240
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
241
|
+
if (buffer.length < 100)
|
|
242
|
+
return null; // Too small, probably an error
|
|
243
|
+
// Convert to data URI
|
|
244
|
+
const base64 = buffer.toString("base64");
|
|
245
|
+
const mimeType = contentType.split(";")[0].trim();
|
|
246
|
+
const data_uri = `data:${mimeType};base64,${base64}`;
|
|
247
|
+
return {
|
|
248
|
+
url,
|
|
249
|
+
type: "clearbit",
|
|
250
|
+
confidence: "medium",
|
|
251
|
+
data_uri,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Try common logo file paths on a domain.
|
|
260
|
+
* Many sites have predictable logo locations.
|
|
261
|
+
*/
|
|
262
|
+
export async function probeCommonLogoPaths(baseUrl) {
|
|
263
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
264
|
+
const paths = [
|
|
265
|
+
"/logo.svg",
|
|
266
|
+
"/logo.png",
|
|
267
|
+
"/images/logo.svg",
|
|
268
|
+
"/images/logo.png",
|
|
269
|
+
"/assets/logo.svg",
|
|
270
|
+
"/assets/images/logo.svg",
|
|
271
|
+
"/img/logo.svg",
|
|
272
|
+
"/img/logo.png",
|
|
273
|
+
"/static/logo.svg",
|
|
274
|
+
"/static/logo.png",
|
|
275
|
+
];
|
|
276
|
+
for (const path of paths) {
|
|
277
|
+
try {
|
|
278
|
+
const url = `${base}${path}`;
|
|
279
|
+
const response = await safeFetch(url, {
|
|
280
|
+
signal: AbortSignal.timeout(3000),
|
|
281
|
+
method: "HEAD",
|
|
282
|
+
headers: { "User-Agent": `brandsystem-mcp/${getVersion()}` },
|
|
283
|
+
});
|
|
284
|
+
if (response.ok) {
|
|
285
|
+
const contentType = response.headers.get("content-type") || "";
|
|
286
|
+
if (contentType.includes("svg") || contentType.includes("image")) {
|
|
287
|
+
return {
|
|
288
|
+
url,
|
|
289
|
+
type: "common-path",
|
|
290
|
+
confidence: "medium",
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Google's favicon service — GUARANTEED to return something for any domain.
|
|
303
|
+
* Returns a 256x256 favicon. This is the floor — we always get at least this.
|
|
304
|
+
*/
|
|
305
|
+
export async function fetchGoogleFavicon(domain) {
|
|
306
|
+
const cleanDomain = domain.replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/.*$/, "");
|
|
307
|
+
const url = `https://www.google.com/s2/favicons?domain=${cleanDomain}&sz=256`;
|
|
308
|
+
try {
|
|
309
|
+
const response = await safeFetch(url, {
|
|
310
|
+
signal: AbortSignal.timeout(5000),
|
|
311
|
+
headers: { "User-Agent": `brandsystem-mcp/${getVersion()}` },
|
|
312
|
+
});
|
|
313
|
+
if (!response.ok)
|
|
314
|
+
return null;
|
|
315
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
316
|
+
if (buffer.length < 100)
|
|
317
|
+
return null;
|
|
318
|
+
const contentType = response.headers.get("content-type") || "image/png";
|
|
319
|
+
const base64 = buffer.toString("base64");
|
|
320
|
+
const mimeType = contentType.split(";")[0].trim();
|
|
321
|
+
return {
|
|
322
|
+
url,
|
|
323
|
+
type: "favicon",
|
|
324
|
+
confidence: "low",
|
|
325
|
+
data_uri: `data:${mimeType};base64,${base64}`,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Fetch any logo candidate URL and convert to a data URI.
|
|
334
|
+
* Works for SVG, PNG, JPG, ICO — anything fetchable.
|
|
335
|
+
* Returns both the raw content (for file writing) and a data_uri (for embedding).
|
|
336
|
+
*/
|
|
337
|
+
export async function fetchAndEncodeLogo(url) {
|
|
338
|
+
if (url.startsWith("inline:"))
|
|
339
|
+
return null;
|
|
340
|
+
try {
|
|
341
|
+
const response = await safeFetch(url, {
|
|
342
|
+
signal: AbortSignal.timeout(10000),
|
|
343
|
+
headers: { "User-Agent": `brandsystem-mcp/${getVersion()}` },
|
|
344
|
+
});
|
|
345
|
+
if (!response.ok)
|
|
346
|
+
return null;
|
|
347
|
+
const contentType = response.headers.get("content-type") || "";
|
|
348
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
349
|
+
if (buffer.length > 500_000)
|
|
350
|
+
return null;
|
|
351
|
+
const base64 = buffer.toString("base64");
|
|
352
|
+
const mimeType = contentType.split(";")[0].trim() || "image/png";
|
|
353
|
+
const data_uri = `data:${mimeType};base64,${base64}`;
|
|
354
|
+
return { content: buffer, contentType, data_uri };
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Fetch a logo URL and return its content.
|
|
362
|
+
* Returns null if fetch fails or content is too large (>500KB).
|
|
363
|
+
*/
|
|
364
|
+
export async function fetchLogo(url) {
|
|
365
|
+
if (url.startsWith("inline:"))
|
|
366
|
+
return null;
|
|
367
|
+
try {
|
|
368
|
+
const response = await safeFetch(url, {
|
|
369
|
+
signal: AbortSignal.timeout(10000),
|
|
370
|
+
headers: { "User-Agent": `brandsystem-mcp/${getVersion()}` },
|
|
371
|
+
});
|
|
372
|
+
if (!response.ok)
|
|
373
|
+
return null;
|
|
374
|
+
const contentType = response.headers.get("content-type") || "";
|
|
375
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
376
|
+
if (buffer.length > 500_000)
|
|
377
|
+
return null; // too large
|
|
378
|
+
return { content: buffer, contentType };
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=logo-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logo-extractor.js","sourceRoot":"","sources":["../../src/lib/logo-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CoreIdentity, BrandConfig, ClarificationItem } from "../types/index.js";
|
|
2
|
+
export interface ReportData {
|
|
3
|
+
config: BrandConfig;
|
|
4
|
+
identity: CoreIdentity;
|
|
5
|
+
clarifications: ClarificationItem[];
|
|
6
|
+
tokenCount: number;
|
|
7
|
+
auditSummary: {
|
|
8
|
+
pass: number;
|
|
9
|
+
warn: number;
|
|
10
|
+
fail: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate a plain-text brand instruction block that can be pasted
|
|
15
|
+
* into any AI tool's custom instructions / project context / system prompt.
|
|
16
|
+
* Written as a directive to an AI, not a description for a human.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateBrandInstructions(config: BrandConfig, identity: CoreIdentity): string;
|
|
19
|
+
export declare function generateReportHTML(data: ReportData): string;
|
|
20
|
+
//# sourceMappingURL=report-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-html.d.ts","sourceRoot":"","sources":["../../src/lib/report-html.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtF,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,GAAG,MAAM,CAwE7F;AAwVD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAuiB3D"}
|