browser-devtools-mcp 0.0.3 → 0.1.1
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 +507 -59
- package/dist/browser.js +6 -0
- package/dist/browser.js.map +1 -1
- package/dist/config.js +60 -24
- package/dist/config.js.map +1 -1
- package/dist/context.js +28 -0
- package/dist/context.js.map +1 -1
- package/dist/otel/otel-controller.js +4 -0
- package/dist/otel/otel-controller.js.map +1 -1
- package/dist/server-info.js +133 -18
- package/dist/server-info.js.map +1 -1
- package/dist/tools/content/take-screenshot.js +183 -1
- package/dist/tools/content/take-screenshot.js.map +1 -1
- package/dist/tools/figma/compare/compare-image-embedding.js +159 -0
- package/dist/tools/figma/compare/compare-image-embedding.js.map +1 -0
- package/dist/tools/figma/compare/compare-mssim.js +98 -0
- package/dist/tools/figma/compare/compare-mssim.js.map +1 -0
- package/dist/tools/figma/compare/compare-text-embedding.js +291 -0
- package/dist/tools/figma/compare/compare-text-embedding.js.map +1 -0
- package/dist/tools/figma/compare/index.js +139 -0
- package/dist/tools/figma/compare/index.js.map +1 -0
- package/dist/tools/figma/compare/types.js +3 -0
- package/dist/tools/figma/compare/types.js.map +1 -0
- package/dist/tools/figma/compare/vector.js +46 -0
- package/dist/tools/figma/compare/vector.js.map +1 -0
- package/dist/tools/figma/compare-page-with-design.js +240 -0
- package/dist/tools/figma/compare-page-with-design.js.map +1 -0
- package/dist/tools/figma/figma-service.js +134 -0
- package/dist/tools/figma/figma-service.js.map +1 -0
- package/dist/tools/figma/index.js +6 -0
- package/dist/tools/figma/index.js.map +1 -0
- package/dist/tools/index.js +12 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/interaction/index.js +6 -2
- package/dist/tools/interaction/index.js.map +1 -1
- package/dist/tools/interaction/resize-viewport.js +110 -0
- package/dist/tools/interaction/resize-viewport.js.map +1 -0
- package/dist/tools/interaction/resize-window.js +261 -0
- package/dist/tools/interaction/resize-window.js.map +1 -0
- package/dist/tools/interaction/scroll.js +304 -0
- package/dist/tools/interaction/scroll.js.map +1 -0
- package/dist/tools/{monitoring → o11y}/get-console-messages.js +1 -1
- package/dist/tools/o11y/get-console-messages.js.map +1 -0
- package/dist/tools/{monitoring → o11y}/get-http-requests.js +1 -1
- package/dist/tools/o11y/get-http-requests.js.map +1 -0
- package/dist/tools/{monitoring → o11y}/get-trace-id.js +1 -1
- package/dist/tools/o11y/get-trace-id.js.map +1 -0
- package/dist/tools/o11y/get-web-vitals.js +595 -0
- package/dist/tools/o11y/get-web-vitals.js.map +1 -0
- package/dist/tools/{monitoring → o11y}/index.js +2 -0
- package/dist/tools/o11y/index.js.map +1 -0
- package/dist/tools/{monitoring → o11y}/new-trace-id.js +1 -1
- package/dist/tools/o11y/new-trace-id.js.map +1 -0
- package/dist/tools/{monitoring → o11y}/set-trace-id.js +1 -1
- package/dist/tools/o11y/set-trace-id.js.map +1 -0
- package/dist/tools/react/get-component-for-element.js +941 -0
- package/dist/tools/react/get-component-for-element.js.map +1 -0
- package/dist/tools/react/get-element-for-component.js +1190 -0
- package/dist/tools/react/get-element-for-component.js.map +1 -0
- package/dist/tools/react/index.js +10 -0
- package/dist/tools/react/index.js.map +1 -0
- package/dist/tools/run/index.js +7 -0
- package/dist/tools/run/index.js.map +1 -0
- package/dist/tools/{interaction/evaluate.js → run/js-in-browser.js} +24 -6
- package/dist/tools/run/js-in-browser.js.map +1 -0
- package/dist/tools/run/js-in-sandbox.js +175 -0
- package/dist/tools/run/js-in-sandbox.js.map +1 -0
- package/dist/tools/stub/clear.js +41 -0
- package/dist/tools/stub/clear.js.map +1 -0
- package/dist/tools/stub/index.js +14 -0
- package/dist/tools/stub/index.js.map +1 -0
- package/dist/tools/stub/intercept-http-request.js +112 -0
- package/dist/tools/stub/intercept-http-request.js.map +1 -0
- package/dist/tools/stub/list.js +75 -0
- package/dist/tools/stub/list.js.map +1 -0
- package/dist/tools/stub/mock-http-response.js +152 -0
- package/dist/tools/stub/mock-http-response.js.map +1 -0
- package/dist/tools/stub/stub-controller.js +284 -0
- package/dist/tools/stub/stub-controller.js.map +1 -0
- package/dist/tools/sync/index.js +6 -0
- package/dist/tools/sync/index.js.map +1 -0
- package/dist/tools/sync/wait-for-network-idle.js +152 -0
- package/dist/tools/sync/wait-for-network-idle.js.map +1 -0
- package/package.json +16 -3
- package/dist/tools/interaction/evaluate.js.map +0 -1
- package/dist/tools/monitoring/get-console-messages.js.map +0 -1
- package/dist/tools/monitoring/get-http-requests.js.map +0 -1
- package/dist/tools/monitoring/get-trace-id.js.map +0 -1
- package/dist/tools/monitoring/index.js.map +0 -1
- package/dist/tools/monitoring/new-trace-id.js.map +0 -1
- package/dist/tools/monitoring/set-trace-id.js.map +0 -1
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.compare = compare;
|
|
7
|
+
const config_1 = require("../../../config");
|
|
8
|
+
const vector_1 = require("./vector");
|
|
9
|
+
const client_bedrock_runtime_1 = require("@aws-sdk/client-bedrock-runtime");
|
|
10
|
+
const credential_providers_1 = require("@aws-sdk/credential-providers");
|
|
11
|
+
const sharp_1 = __importDefault(require("sharp"));
|
|
12
|
+
const UI_DESCRIBE_PROMPT = `
|
|
13
|
+
You are analyzing a UI screenshot to compare it against another UI.
|
|
14
|
+
|
|
15
|
+
Your goal is to produce a STRUCTURAL LAYOUT FINGERPRINT that remains stable
|
|
16
|
+
even when real data, text values, or content change.
|
|
17
|
+
|
|
18
|
+
Write a concise but highly informative description using the rules below.
|
|
19
|
+
|
|
20
|
+
GENERAL RULES
|
|
21
|
+
- Describe WHAT EXISTS and WHERE IT IS, not how it looks visually.
|
|
22
|
+
- Prefer explicit structure and hierarchy over natural language.
|
|
23
|
+
- Be consistent and deterministic in wording.
|
|
24
|
+
- Do NOT describe colors, fonts, themes, or exact text.
|
|
25
|
+
- Do NOT include user data, names, numbers, timestamps, or labels.
|
|
26
|
+
|
|
27
|
+
LAYOUT STRUCTURE
|
|
28
|
+
Describe the UI from top to bottom:
|
|
29
|
+
|
|
30
|
+
1) PAGE REGIONS
|
|
31
|
+
- Identify major regions in order:
|
|
32
|
+
- top header / app bar
|
|
33
|
+
- left or right sidebar
|
|
34
|
+
- main content area
|
|
35
|
+
- footer (if present)
|
|
36
|
+
|
|
37
|
+
2) REGION DETAILS
|
|
38
|
+
For EACH region, describe:
|
|
39
|
+
- Position (top / left / right / center / full-width)
|
|
40
|
+
- Layout type (row, column, grid, split, stacked)
|
|
41
|
+
- Whether it is fixed or scrollable
|
|
42
|
+
- Primary purpose (navigation, content, controls, metadata)
|
|
43
|
+
|
|
44
|
+
3) COMPONENT INVENTORY
|
|
45
|
+
List the components that exist, grouped by region:
|
|
46
|
+
- navigation menus
|
|
47
|
+
- tabs
|
|
48
|
+
- tables (rows/columns, header present or not)
|
|
49
|
+
- lists (vertical/horizontal, item density: sparse/medium/dense)
|
|
50
|
+
- cards (count: single / few / many)
|
|
51
|
+
- forms (inline / multi-section)
|
|
52
|
+
- modals, drawers, overlays (present or not)
|
|
53
|
+
|
|
54
|
+
4) HIERARCHY & RELATIONSHIPS
|
|
55
|
+
Explicitly mention:
|
|
56
|
+
- parent → child relationships
|
|
57
|
+
- repeated patterns (e.g. "repeating card list", "uniform table rows")
|
|
58
|
+
- alignment relationships (sidebar + main content, header spanning all columns)
|
|
59
|
+
|
|
60
|
+
5) ABSENCE IS SIGNAL
|
|
61
|
+
If something is NOT present, state it explicitly when relevant:
|
|
62
|
+
- no sidebar
|
|
63
|
+
- no table
|
|
64
|
+
- no modal
|
|
65
|
+
- no pagination
|
|
66
|
+
|
|
67
|
+
FORMAT
|
|
68
|
+
- Use short bullet-style sentences.
|
|
69
|
+
- Use consistent phrasing across similar structures.
|
|
70
|
+
- Avoid synonyms (always say “sidebar”, not sometimes “side panel”).
|
|
71
|
+
- Keep the output under ~30 lines.
|
|
72
|
+
|
|
73
|
+
Return plain text only. No markdown.
|
|
74
|
+
`;
|
|
75
|
+
/**
|
|
76
|
+
* -----------------------------------------------------------------------------
|
|
77
|
+
* Helpers
|
|
78
|
+
* -----------------------------------------------------------------------------
|
|
79
|
+
*/
|
|
80
|
+
function _resolvePrompt(opt) {
|
|
81
|
+
return opt?.prompt ?? UI_DESCRIBE_PROMPT.trim();
|
|
82
|
+
}
|
|
83
|
+
function _resolveMaxDim(opt) {
|
|
84
|
+
return typeof opt?.maxDim === 'number' && opt.maxDim > 0
|
|
85
|
+
? Math.floor(opt.maxDim)
|
|
86
|
+
: 1024;
|
|
87
|
+
}
|
|
88
|
+
function _resolveImageFormat(opt) {
|
|
89
|
+
return opt?.imageFormat === 'jpeg' ? 'jpeg' : 'png';
|
|
90
|
+
}
|
|
91
|
+
function _resolveJpegQuality(opt) {
|
|
92
|
+
const q = opt?.jpegQuality;
|
|
93
|
+
return typeof q === 'number' && q >= 50 && q <= 100 ? Math.floor(q) : 90;
|
|
94
|
+
}
|
|
95
|
+
async function _preprocessImage(buf, opt) {
|
|
96
|
+
const maxDim = _resolveMaxDim(opt);
|
|
97
|
+
const format = _resolveImageFormat(opt);
|
|
98
|
+
const jpegQuality = _resolveJpegQuality(opt);
|
|
99
|
+
let img = (0, sharp_1.default)(buf).resize({
|
|
100
|
+
width: maxDim,
|
|
101
|
+
height: maxDim,
|
|
102
|
+
fit: 'inside',
|
|
103
|
+
withoutEnlargement: true,
|
|
104
|
+
});
|
|
105
|
+
let out;
|
|
106
|
+
let mimeType;
|
|
107
|
+
if (format === 'png') {
|
|
108
|
+
out = await img.png().toBuffer();
|
|
109
|
+
mimeType = 'image/png';
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
out = await img.jpeg({ quality: jpegQuality }).toBuffer();
|
|
113
|
+
mimeType = 'image/jpeg';
|
|
114
|
+
}
|
|
115
|
+
return { bytes: out, mimeType };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* -----------------------------------------------------------------------------
|
|
119
|
+
* Amazon Bedrock specific embedding implementations
|
|
120
|
+
* -----------------------------------------------------------------------------
|
|
121
|
+
*/
|
|
122
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
123
|
+
const SUPPORTED_AMAZON_BEDROCK_TEXT_EMBED_MODEL_IDS = new Set([
|
|
124
|
+
'amazon.titan-embed-text-v2:0',
|
|
125
|
+
]);
|
|
126
|
+
const DEFAULT_AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID = 'amazon.titan-embed-text-v2:0';
|
|
127
|
+
const SUPPORTED_AMAZON_BEDROCK_VISION_MODEL_IDS = new Set([
|
|
128
|
+
'anthropic.claude-3-haiku-20240307-v1',
|
|
129
|
+
'anthropic.claude-3-sonnet-20240229-v1:0',
|
|
130
|
+
'anthropic.claude-3-5-sonnet-20241022-v2:0',
|
|
131
|
+
'anthropic.claude-3-7-sonnet-20250219-v1:0',
|
|
132
|
+
'anthropic.claude-3-opus-20240229-v1:0',
|
|
133
|
+
'anthropic.claude-haiku-4-5-20251001-v1:0',
|
|
134
|
+
'anthropic.claude-opus-4-1-20250805-v1:0',
|
|
135
|
+
'anthropic.claude-opus-4-5-20251101-v1:0',
|
|
136
|
+
]);
|
|
137
|
+
const DEFAULT_AMAZON_BEDROCK_VISION_MODEL_ID = 'anthropic.claude-3-sonnet-20240229-v1:0';
|
|
138
|
+
let _bedrockClient;
|
|
139
|
+
function _isAwsBedrockActive() {
|
|
140
|
+
// Minimal "is Bedrock usable?" check:
|
|
141
|
+
// - Amazon Bedrock must be enabled
|
|
142
|
+
// - Region must exist
|
|
143
|
+
// - Credentials are resolved by AWS SDK default chain or AWS_PROFILE
|
|
144
|
+
return config_1.AMAZON_BEDROCK_ENABLE && Boolean(config_1.AWS_REGION);
|
|
145
|
+
}
|
|
146
|
+
function _getOrCreateBedrockClient() {
|
|
147
|
+
if (_bedrockClient) {
|
|
148
|
+
return _bedrockClient;
|
|
149
|
+
}
|
|
150
|
+
const region = config_1.AWS_REGION;
|
|
151
|
+
if (!region) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
const profile = config_1.AWS_PROFILE;
|
|
155
|
+
if (profile) {
|
|
156
|
+
_bedrockClient = new client_bedrock_runtime_1.BedrockRuntimeClient({
|
|
157
|
+
region,
|
|
158
|
+
credentials: (0, credential_providers_1.fromIni)({ profile }),
|
|
159
|
+
});
|
|
160
|
+
return _bedrockClient;
|
|
161
|
+
}
|
|
162
|
+
_bedrockClient = new client_bedrock_runtime_1.BedrockRuntimeClient({ region });
|
|
163
|
+
return _bedrockClient;
|
|
164
|
+
}
|
|
165
|
+
async function _invokeBedrock(client, modelId, payload) {
|
|
166
|
+
const cmd = new client_bedrock_runtime_1.InvokeModelCommand({
|
|
167
|
+
modelId,
|
|
168
|
+
contentType: 'application/json',
|
|
169
|
+
accept: 'application/json',
|
|
170
|
+
body: Buffer.from(JSON.stringify(payload)),
|
|
171
|
+
});
|
|
172
|
+
const resp = await client.send(cmd);
|
|
173
|
+
const raw = Buffer.from(resp.body).toString('utf-8');
|
|
174
|
+
return JSON.parse(raw);
|
|
175
|
+
}
|
|
176
|
+
async function _describeUIWithAmazonBedrockClaude(ss, opt, client, modelId) {
|
|
177
|
+
const { bytes, mimeType } = await _preprocessImage(ss.image, opt);
|
|
178
|
+
const prompt = _resolvePrompt(opt);
|
|
179
|
+
const payload = {
|
|
180
|
+
anthropic_version: 'bedrock-2023-05-31',
|
|
181
|
+
max_tokens: 10_000,
|
|
182
|
+
temperature: 0,
|
|
183
|
+
messages: [
|
|
184
|
+
{
|
|
185
|
+
role: 'user',
|
|
186
|
+
content: [
|
|
187
|
+
{ type: 'text', text: prompt },
|
|
188
|
+
{
|
|
189
|
+
type: 'image',
|
|
190
|
+
source: {
|
|
191
|
+
type: 'base64',
|
|
192
|
+
media_type: mimeType,
|
|
193
|
+
data: bytes.toString('base64'),
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
};
|
|
200
|
+
const parsed = await _invokeBedrock(client, modelId, payload);
|
|
201
|
+
const text = parsed?.content?.[0]?.text ?? parsed?.output_text ?? parsed?.completion;
|
|
202
|
+
if (!text || !text.trim()) {
|
|
203
|
+
throw new Error('Amazon Bedrock Claude returned empty description.');
|
|
204
|
+
}
|
|
205
|
+
return text.trim();
|
|
206
|
+
}
|
|
207
|
+
async function _embedTextWithAmazonBedrockTitan(text, client, modelId) {
|
|
208
|
+
const payload = {
|
|
209
|
+
inputText: text,
|
|
210
|
+
};
|
|
211
|
+
const parsed = await _invokeBedrock(client, modelId, payload);
|
|
212
|
+
const emb = parsed?.embedding;
|
|
213
|
+
if (!Array.isArray(emb) || typeof emb[0] !== 'number') {
|
|
214
|
+
throw new Error('Unexpected embedding response for Amazon Bedrock Titan text embedding.');
|
|
215
|
+
}
|
|
216
|
+
return emb;
|
|
217
|
+
}
|
|
218
|
+
async function _describeUIWithAmazonBedrock(ss, opt, client) {
|
|
219
|
+
const modelId = opt?.visionModelId ??
|
|
220
|
+
config_1.AMAZON_BEDROCK_VISION_MODEL_ID ??
|
|
221
|
+
DEFAULT_AMAZON_BEDROCK_VISION_MODEL_ID;
|
|
222
|
+
if (!SUPPORTED_AMAZON_BEDROCK_VISION_MODEL_IDS.has(modelId)) {
|
|
223
|
+
throw new Error(`Unsupported Amazon Bedrock vision model id: ${modelId}`);
|
|
224
|
+
}
|
|
225
|
+
return await _describeUIWithAmazonBedrockClaude(ss, opt, client, modelId);
|
|
226
|
+
}
|
|
227
|
+
async function _embedTextWithAmazonBedrock(text, opt, client) {
|
|
228
|
+
const modelId = opt?.textEmbedModelId ??
|
|
229
|
+
config_1.AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID ??
|
|
230
|
+
DEFAULT_AMAZON_BEDROCK_TEXT_EMBED_MODEL_ID;
|
|
231
|
+
if (!SUPPORTED_AMAZON_BEDROCK_TEXT_EMBED_MODEL_IDS.has(modelId)) {
|
|
232
|
+
throw new Error(`Unsupported Amazon Bedrock text embedding model id: ${modelId}`);
|
|
233
|
+
}
|
|
234
|
+
return await _embedTextWithAmazonBedrockTitan(text, client, modelId);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* -----------------------------------------------------------------------------
|
|
238
|
+
* Routing (LLM-agnostic)
|
|
239
|
+
* -----------------------------------------------------------------------------
|
|
240
|
+
*/
|
|
241
|
+
async function _describeUI(ss, opt) {
|
|
242
|
+
// Provider A: Amazon Bedrock
|
|
243
|
+
if (_isAwsBedrockActive()) {
|
|
244
|
+
const client = _getOrCreateBedrockClient();
|
|
245
|
+
if (!client) {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
return _describeUIWithAmazonBedrock(ss, opt, client);
|
|
249
|
+
}
|
|
250
|
+
// No providers active
|
|
251
|
+
return undefined;
|
|
252
|
+
}
|
|
253
|
+
async function _embedTextVector(text, opt) {
|
|
254
|
+
// Provider A: Amazon Bedrock
|
|
255
|
+
if (_isAwsBedrockActive()) {
|
|
256
|
+
const client = _getOrCreateBedrockClient();
|
|
257
|
+
if (!client) {
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
return _embedTextWithAmazonBedrock(text, opt, client);
|
|
261
|
+
}
|
|
262
|
+
// No providers active
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* -----------------------------------------------------------------------------
|
|
267
|
+
* Public API
|
|
268
|
+
* -----------------------------------------------------------------------------
|
|
269
|
+
*/
|
|
270
|
+
async function compare(page, figma, options) {
|
|
271
|
+
const normalize = typeof options?.normalize === 'boolean' ? options.normalize : true;
|
|
272
|
+
const figmaDesc = await _describeUI(figma, options);
|
|
273
|
+
if (!figmaDesc) {
|
|
274
|
+
return undefined;
|
|
275
|
+
}
|
|
276
|
+
const pageDesc = await _describeUI(page, options);
|
|
277
|
+
if (!pageDesc) {
|
|
278
|
+
return undefined;
|
|
279
|
+
}
|
|
280
|
+
const figmaVec = await _embedTextVector(figmaDesc, options);
|
|
281
|
+
if (!figmaVec) {
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
const pageVec = await _embedTextVector(pageDesc, options);
|
|
285
|
+
if (!pageVec) {
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
const score = (0, vector_1.cosineSimilarity)(figmaVec, pageVec, normalize);
|
|
289
|
+
return { score };
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=compare-text-embedding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare-text-embedding.js","sourceRoot":"","sources":["../../../../src/tools/figma/compare/compare-text-embedding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.compareWithNotes = compareWithNotes;
|
|
18
|
+
const compare_mssim_1 = require("./compare-mssim");
|
|
19
|
+
const compare_image_embedding_1 = require("./compare-image-embedding");
|
|
20
|
+
const compare_text_embedding_1 = require("./compare-text-embedding");
|
|
21
|
+
/**
|
|
22
|
+
* ------------------------------------------------------------
|
|
23
|
+
* Constants
|
|
24
|
+
* ------------------------------------------------------------
|
|
25
|
+
*/
|
|
26
|
+
const DEFAULT_MSSIM_WEIGHT = 0.25;
|
|
27
|
+
const DEFAULT_VECTOR_EMBEDDING_WEIGHT = 0.5;
|
|
28
|
+
const DEFAULT_TEXT_EMBEDDING_WEIGHT = 0.25;
|
|
29
|
+
/**
|
|
30
|
+
* ------------------------------------------------------------
|
|
31
|
+
* Helpers
|
|
32
|
+
* ------------------------------------------------------------
|
|
33
|
+
*/
|
|
34
|
+
function _clamp01(v) {
|
|
35
|
+
if (!Number.isFinite(v)) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
return Math.max(0, Math.min(1, v));
|
|
39
|
+
}
|
|
40
|
+
function _weightOrDefault(v, def) {
|
|
41
|
+
if (typeof v === 'number' && Number.isFinite(v) && v > 0) {
|
|
42
|
+
return v;
|
|
43
|
+
}
|
|
44
|
+
return def;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* ------------------------------------------------------------
|
|
48
|
+
* Main combiner
|
|
49
|
+
* ------------------------------------------------------------
|
|
50
|
+
*
|
|
51
|
+
* - MSSIM is assumed to always work
|
|
52
|
+
* - Image / text embedding may return `undefined`
|
|
53
|
+
* - Only successful signals participate in the weighted average
|
|
54
|
+
*/
|
|
55
|
+
async function compareWithNotes(page, figma, options) {
|
|
56
|
+
const notes = [];
|
|
57
|
+
const wMssim = _weightOrDefault(options?.weights?.mssim, DEFAULT_MSSIM_WEIGHT);
|
|
58
|
+
const wVector = _weightOrDefault(options?.weights?.vectorEmbedding, DEFAULT_VECTOR_EMBEDDING_WEIGHT);
|
|
59
|
+
const wText = _weightOrDefault(options?.weights?.textEmbedding, DEFAULT_TEXT_EMBEDDING_WEIGHT);
|
|
60
|
+
/**
|
|
61
|
+
* --------------------------------------------------------
|
|
62
|
+
* 1) MSSIM (always)
|
|
63
|
+
* --------------------------------------------------------
|
|
64
|
+
*/
|
|
65
|
+
const mssimRes = await (0, compare_mssim_1.compare)(page, figma, options?.mssim);
|
|
66
|
+
const mssimScore = _clamp01(mssimRes.score);
|
|
67
|
+
notes.push(`mssim=${mssimScore.toFixed(5)}`);
|
|
68
|
+
/**
|
|
69
|
+
* --------------------------------------------------------
|
|
70
|
+
* 2) Image embedding (optional)
|
|
71
|
+
* --------------------------------------------------------
|
|
72
|
+
*/
|
|
73
|
+
let imageScore;
|
|
74
|
+
try {
|
|
75
|
+
const res = await (0, compare_image_embedding_1.compare)(page, figma, options?.imageEmbedding);
|
|
76
|
+
if (res && typeof res.score === 'number') {
|
|
77
|
+
imageScore = _clamp01(res.score);
|
|
78
|
+
notes.push(`image-embedding=${imageScore.toFixed(5)}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
notes.push('image-embedding=skipped (inactive)');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
notes.push(`image-embedding=skipped (${err instanceof Error ? err.message : String(err)})`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* --------------------------------------------------------
|
|
89
|
+
* 3) Vision → text → text embedding (optional)
|
|
90
|
+
* --------------------------------------------------------
|
|
91
|
+
*/
|
|
92
|
+
let textScore;
|
|
93
|
+
try {
|
|
94
|
+
const res = await (0, compare_text_embedding_1.compare)(page, figma, options?.textEmbedding);
|
|
95
|
+
if (res && typeof res.score === 'number') {
|
|
96
|
+
textScore = _clamp01(res.score);
|
|
97
|
+
notes.push(`text-embedding=${textScore.toFixed(5)}`);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
notes.push('text-embedding=skipped (inactive)');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
notes.push(`text-embedding=skipped (${err instanceof Error ? err.message : String(err)})`);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* --------------------------------------------------------
|
|
108
|
+
* Combine scores (weight renormalization)
|
|
109
|
+
* --------------------------------------------------------
|
|
110
|
+
*/
|
|
111
|
+
const parts = [
|
|
112
|
+
{ name: 'mssim', score: mssimScore, weight: wMssim },
|
|
113
|
+
];
|
|
114
|
+
if (typeof imageScore === 'number') {
|
|
115
|
+
parts.push({
|
|
116
|
+
name: 'image-embedding',
|
|
117
|
+
score: imageScore,
|
|
118
|
+
weight: wVector,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (typeof textScore === 'number') {
|
|
122
|
+
parts.push({
|
|
123
|
+
name: 'text-embedding',
|
|
124
|
+
score: textScore,
|
|
125
|
+
weight: wText,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const totalWeight = parts.reduce((s, p) => s + p.weight, 0);
|
|
129
|
+
const combined = totalWeight > 0
|
|
130
|
+
? parts.reduce((s, p) => s + p.score * (p.weight / totalWeight), 0)
|
|
131
|
+
: 0;
|
|
132
|
+
const score = _clamp01(combined);
|
|
133
|
+
notes.push(`combined=${score.toFixed(5)} (signals=${parts
|
|
134
|
+
.map((p) => p.name)
|
|
135
|
+
.join(', ')})`);
|
|
136
|
+
return { score, notes };
|
|
137
|
+
}
|
|
138
|
+
__exportStar(require("./types"), exports);
|
|
139
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/tools/figma/compare/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/tools/figma/compare/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dot = dot;
|
|
4
|
+
exports.norm = norm;
|
|
5
|
+
exports.l2Normalize = l2Normalize;
|
|
6
|
+
exports.cosineSimilarity = cosineSimilarity;
|
|
7
|
+
function dot(a, b) {
|
|
8
|
+
const n = Math.min(a.length, b.length);
|
|
9
|
+
let s = 0;
|
|
10
|
+
for (let i = 0; i < n; i++) {
|
|
11
|
+
s += a[i] * b[i];
|
|
12
|
+
}
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
function norm(a) {
|
|
16
|
+
let s = 0;
|
|
17
|
+
for (let i = 0; i < a.length; i++) {
|
|
18
|
+
const x = a[i];
|
|
19
|
+
s += x * x;
|
|
20
|
+
}
|
|
21
|
+
return Math.sqrt(s);
|
|
22
|
+
}
|
|
23
|
+
function l2Normalize(v) {
|
|
24
|
+
const n = norm(v);
|
|
25
|
+
if (n === 0) {
|
|
26
|
+
return v.slice();
|
|
27
|
+
}
|
|
28
|
+
const out = new Array(v.length);
|
|
29
|
+
for (let i = 0; i < v.length; i++) {
|
|
30
|
+
out[i] = v[i] / n;
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
function cosineSimilarity(a, b, normalize) {
|
|
35
|
+
if (normalize) {
|
|
36
|
+
const na = l2Normalize(a);
|
|
37
|
+
const nb = l2Normalize(b);
|
|
38
|
+
return dot(na, nb);
|
|
39
|
+
}
|
|
40
|
+
const denom = norm(a) * norm(b);
|
|
41
|
+
if (denom === 0) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
return dot(a, b) / denom;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=vector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vector.js","sourceRoot":"","sources":["../../../../src/tools/figma/compare/vector.ts"],"names":[],"mappings":";;AAEA,kBAOC;AAED,oBAOC;AAED,kCAWC;AAED,4CAgBC;AA/CD,SAAgB,GAAG,CAAC,CAAS,EAAE,CAAS;IACpC,MAAM,CAAC,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAW,CAAC,CAAC;IAClB,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAgB,IAAI,CAAC,CAAS;IAC1B,IAAI,CAAC,GAAW,CAAC,CAAC;IAClB,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,GAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxB,CAAC;AAED,SAAgB,WAAW,CAAC,CAAS;IACjC,MAAM,CAAC,GAAW,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACV,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,MAAM,GAAG,GAAW,IAAI,KAAK,CAAS,CAAC,CAAC,MAAM,CAAC,CAAC;IAChD,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED,SAAgB,gBAAgB,CAC5B,CAAS,EACT,CAAS,EACT,SAAkB;IAElB,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,EAAE,GAAW,WAAW,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,EAAE,GAAW,WAAW,CAAC,CAAC,CAAC,CAAC;QAClC,OAAO,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,KAAK,GAAW,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QACd,OAAO,CAAC,CAAC;IACb,CAAC;IACD,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;AAC7B,CAAC"}
|