chrometools-mcp 2.4.2 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +540 -0
  2. package/COMPONENT_MAPPING_SPEC.md +1217 -0
  3. package/README.md +494 -38
  4. package/bridge/bridge-client.js +472 -0
  5. package/bridge/bridge-service.js +399 -0
  6. package/bridge/install.js +241 -0
  7. package/browser/browser-manager.js +107 -2
  8. package/browser/page-manager.js +226 -69
  9. package/docs/CHROME_EXTENSION.md +219 -0
  10. package/docs/PAGE_OBJECT_MODEL_CONCEPT.md +1756 -0
  11. package/element-finder-utils.js +138 -28
  12. package/extension/background.js +643 -0
  13. package/extension/content.js +715 -0
  14. package/extension/icons/create-icons.js +164 -0
  15. package/extension/icons/icon128.png +0 -0
  16. package/extension/icons/icon16.png +0 -0
  17. package/extension/icons/icon48.png +0 -0
  18. package/extension/manifest.json +58 -0
  19. package/extension/popup/popup.css +437 -0
  20. package/extension/popup/popup.html +102 -0
  21. package/extension/popup/popup.js +415 -0
  22. package/extension/recorder-overlay.css +93 -0
  23. package/figma-tools.js +120 -0
  24. package/index.js +3347 -2518
  25. package/models/BaseInputModel.js +93 -0
  26. package/models/CheckboxGroupModel.js +199 -0
  27. package/models/CheckboxModel.js +103 -0
  28. package/models/ColorInputModel.js +53 -0
  29. package/models/DateInputModel.js +67 -0
  30. package/models/RadioGroupModel.js +126 -0
  31. package/models/RangeInputModel.js +60 -0
  32. package/models/SelectModel.js +97 -0
  33. package/models/TextInputModel.js +34 -0
  34. package/models/TextareaModel.js +59 -0
  35. package/models/TimeInputModel.js +49 -0
  36. package/models/index.js +122 -0
  37. package/package.json +3 -2
  38. package/pom/apom-converter.js +267 -0
  39. package/pom/apom-tree-converter.js +515 -0
  40. package/pom/element-id-generator.js +175 -0
  41. package/recorder/page-object-generator.js +16 -0
  42. package/recorder/scenario-executor.js +80 -2
  43. package/server/tool-definitions.js +839 -656
  44. package/server/tool-groups.js +3 -2
  45. package/server/tool-schemas.js +367 -296
  46. package/server/websocket-bridge.js +447 -0
  47. package/utils/selector-resolver.js +186 -0
  48. package/utils/ui-framework-detector.js +392 -0
package/figma-tools.js CHANGED
@@ -377,3 +377,123 @@ export function collectAllText(node, texts = []) {
377
377
  }
378
378
  return texts;
379
379
  }
380
+
381
+ /**
382
+ * Simplify Figma node structure for code generation
383
+ * Extracts only essential properties: layout, styling, text, and children
384
+ */
385
+ export function simplifyNode(node) {
386
+ if (!node) return null;
387
+
388
+ const simplified = {
389
+ type: node.type,
390
+ name: node.name,
391
+ };
392
+
393
+ // Dimensions
394
+ if (node.absoluteBoundingBox) {
395
+ simplified.size = {
396
+ width: Math.round(node.absoluteBoundingBox.width),
397
+ height: Math.round(node.absoluteBoundingBox.height),
398
+ };
399
+ }
400
+
401
+ // Layout properties (Auto Layout / Flexbox)
402
+ if (node.layoutMode) {
403
+ simplified.layout = {
404
+ mode: node.layoutMode, // HORIZONTAL or VERTICAL
405
+ padding: (node.paddingLeft || node.paddingTop || node.paddingRight || node.paddingBottom) ? {
406
+ top: node.paddingTop || 0,
407
+ right: node.paddingRight || 0,
408
+ bottom: node.paddingBottom || 0,
409
+ left: node.paddingLeft || 0,
410
+ } : undefined,
411
+ gap: node.itemSpacing,
412
+ align: node.primaryAxisAlignItems,
413
+ justify: node.counterAxisAlignItems,
414
+ };
415
+ }
416
+
417
+ // Border radius
418
+ if (node.cornerRadius) {
419
+ simplified.borderRadius = node.cornerRadius;
420
+ } else if (node.rectangleCornerRadii) {
421
+ simplified.borderRadius = node.rectangleCornerRadii;
422
+ }
423
+
424
+ // Fills (backgrounds)
425
+ if (node.fills && node.fills.length > 0) {
426
+ simplified.fills = node.fills
427
+ .filter(fill => fill.visible !== false)
428
+ .map(fill => ({
429
+ type: fill.type,
430
+ color: fill.color ? {
431
+ r: Math.round(fill.color.r * 255),
432
+ g: Math.round(fill.color.g * 255),
433
+ b: Math.round(fill.color.b * 255),
434
+ a: fill.color.a !== undefined ? Math.round(fill.color.a * 100) / 100 : 1,
435
+ } : undefined,
436
+ opacity: fill.opacity,
437
+ }));
438
+ }
439
+
440
+ // Strokes (borders)
441
+ if (node.strokes && node.strokes.length > 0) {
442
+ simplified.strokes = node.strokes
443
+ .filter(stroke => stroke.visible !== false)
444
+ .map(stroke => ({
445
+ type: stroke.type,
446
+ color: stroke.color ? {
447
+ r: Math.round(stroke.color.r * 255),
448
+ g: Math.round(stroke.color.g * 255),
449
+ b: Math.round(stroke.color.b * 255),
450
+ a: stroke.color.a !== undefined ? Math.round(stroke.color.a * 100) / 100 : 1,
451
+ } : undefined,
452
+ }));
453
+
454
+ if (node.strokeWeight) {
455
+ simplified.strokeWeight = node.strokeWeight;
456
+ }
457
+ }
458
+
459
+ // Effects (shadows, blurs)
460
+ if (node.effects && node.effects.length > 0) {
461
+ simplified.effects = node.effects
462
+ .filter(effect => effect.visible !== false)
463
+ .map(effect => ({
464
+ type: effect.type,
465
+ radius: effect.radius,
466
+ offset: effect.offset,
467
+ color: effect.color ? {
468
+ r: Math.round(effect.color.r * 255),
469
+ g: Math.round(effect.color.g * 255),
470
+ b: Math.round(effect.color.b * 255),
471
+ a: Math.round(effect.color.a * 100) / 100,
472
+ } : undefined,
473
+ }));
474
+ }
475
+
476
+ // Text properties
477
+ if (node.type === 'TEXT') {
478
+ simplified.text = node.characters;
479
+ if (node.style) {
480
+ simplified.textStyle = {
481
+ fontFamily: node.style.fontFamily,
482
+ fontWeight: node.style.fontWeight,
483
+ fontSize: node.style.fontSize,
484
+ lineHeight: node.style.lineHeightPx,
485
+ letterSpacing: node.style.letterSpacing,
486
+ textAlign: node.style.textAlignHorizontal,
487
+ };
488
+ }
489
+ }
490
+
491
+ // Recursively simplify children
492
+ if (node.children && node.children.length > 0) {
493
+ simplified.children = node.children
494
+ .map(child => simplifyNode(child))
495
+ .filter(Boolean); // Remove null values
496
+ }
497
+
498
+ return simplified;
499
+ }