mta-mcp 3.14.1 → 3.14.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mta-mcp",
3
- "version": "3.14.1",
3
+ "version": "3.14.2",
4
4
  "description": "MTA - 智能编码助手 MCP 服务器(规范 + 技能 + 诊断 + 模板 + 记忆 + 思考)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -670,7 +670,7 @@ function detectIfIcon(layer) {
670
670
 
671
671
  var name = (layer.name || '').toLowerCase();
672
672
  var size = Math.max(layer.frame.width, layer.frame.height);
673
- var iconKeywords = ['icon', 'ico', 'logo', 'symbol', 'arrow', 'close', 'menu',
673
+ var iconKeywords = ['icon', 'ico', 'ic_', '_ic', 'logo', 'symbol', 'arrow', 'close', 'menu',
674
674
  'search', 'star', 'check', 'back', 'more', 'nav', 'btn', 'button'];
675
675
  var hasKeyword = false;
676
676
  for (var k = 0; k < iconKeywords.length; k++) {
@@ -1297,7 +1297,11 @@ function extractCompleteStyle(layer) {
1297
1297
  var ish = innerShadows[isi];
1298
1298
  var innerObj = { color: ish.color, blur: ish.blur, x: ish.x, y: ish.y, spread: ish.spread || 0 };
1299
1299
  var fc3 = sketchColorToFlutter(ish.color);
1300
- if (fc3) innerObj.flutterBoxShadow = 'BoxShadow(color: ' + fc3 + ', offset: Offset(' + ish.x + ', ' + ish.y + '), blurRadius: ' + ish.blur + ', spreadRadius: ' + (ish.spread || 0) + ')';
1300
+ if (fc3) {
1301
+ innerObj.flutterBoxShadow = 'BoxShadow(color: ' + fc3 + ', offset: Offset(' + ish.x + ', ' + ish.y + '), blurRadius: ' + ish.blur + ', spreadRadius: ' + (ish.spread || 0) + ')';
1302
+ // Flutter 不原生支持 innerShadow,以下给出实现方案
1303
+ innerObj.flutterNote = '⚠️ Flutter 不原生支持 innerShadow。实现方案: 在 Stack 中于内容层上方叠加一个同形状的 DecoratedBox,decoration 中 boxShadow 使用较大的 spreadRadius 使阴影向内延伸,再用 ClipRRect/ClipPath 裁剪为相同圆角,使阴影只在容器内部可见。或使用 CustomPainter 直接绘制。';
1304
+ }
1301
1305
  style.innerShadows.push(innerObj);
1302
1306
  }
1303
1307
  }
@@ -2433,8 +2437,28 @@ function measureRecursively(layer, depth, parentFrame, siblings) {
2433
2437
  if (iconFill.flutterColor) {
2434
2438
  var iw = Math.round(layer.frame.width);
2435
2439
  var ih = Math.round(layer.frame.height);
2440
+ // 将图层级别 opacity 合并进 colorFilter 颜色的 alpha 通道
2441
+ // 原因: Sketch 支持"填充色 alpha"和"图层整体 opacity"两个独立维度,
2442
+ // 若只用填充色 alpha 而忽略 layer opacity, colorFilter 渲染比设计稿更深
2443
+ var layerOpacity = 1.0;
2444
+ try {
2445
+ if (layer.style && layer.style.opacity !== undefined && layer.style.opacity !== 1) {
2446
+ layerOpacity = layer.style.opacity;
2447
+ }
2448
+ } catch (e2) { /* ignore */ }
2449
+ var fillAlpha = (iconFill.alpha !== undefined) ? iconFill.alpha : 1.0;
2450
+ var effectiveAlpha = fillAlpha * layerOpacity;
2451
+ var effectiveColor;
2452
+ if (Math.abs(effectiveAlpha - fillAlpha) > 0.01) {
2453
+ // layer opacity 有效,合并后重新生成 Flutter 颜色
2454
+ effectiveColor = toFlutterColor(iconFill.hex || iconFill.color, effectiveAlpha);
2455
+ element.iconOpacityMerged = true;
2456
+ element.iconOpacityNote = 'fill-alpha(' + Math.round(fillAlpha * 100) + '%) × layer-opacity(' + Math.round(layerOpacity * 100) + '%) = ' + Math.round(effectiveAlpha * 100) + '% → 已合并入 colorFilter alpha';
2457
+ } else {
2458
+ effectiveColor = iconFill.flutterColor;
2459
+ }
2436
2460
  // 路径后附带 TODO 注释,提示核对实际文件名
2437
- element.flutterSvgCode = 'SvgPicture.asset(\'assets/' + element.iconExportPath + '\' /* TODO: 核对 assets/icons/ 中实际文件名,禁止用 Icons.xxx 替代 */, width: ' + iw + ', height: ' + ih + ', colorFilter: ColorFilter.mode(' + iconFill.flutterColor + ', BlendMode.srcIn),)';
2461
+ element.flutterSvgCode = 'SvgPicture.asset(\'assets/' + element.iconExportPath + '\' /* TODO: 核对 assets/icons/ 中实际文件名,禁止用 Icons.xxx 替代 */, width: ' + iw + ', height: ' + ih + ', colorFilter: ColorFilter.mode(' + effectiveColor + ', BlendMode.srcIn),)';
2438
2462
  }
2439
2463
  }
2440
2464
  }
@@ -2526,7 +2550,13 @@ function measureRecursively(layer, depth, parentFrame, siblings) {
2526
2550
  if (nativeImgFills && nativeImgFills[0] && nativeImgFills[0].hex) {
2527
2551
  element.imageInfo.nativeTint = formatNativeColor(nativeImgFills[0]);
2528
2552
  }
2529
- element.imageInfo.note = '此图层为嵌入式位图(Bitmap), 需要导出为 SVG PNG 后使用';
2553
+ element.imageInfo.note = '此图层为嵌入式位图(Bitmap), 必须导出为 PNG (非SVG——Bitmap导出SVG只含base64嵌套图片, 无矢量路径), 放入 assets/icons/, 用 Image.asset 渲染';
2554
+ // 生成 Image.asset 代码片段,开发者直接复制使用
2555
+ var bitmapW = Math.round(layer.frame.width);
2556
+ var bitmapH = Math.round(layer.frame.height);
2557
+ var bitmapName = sanitizeFileName(layer.name);
2558
+ element.flutterImageCode = 'Image.asset(\'assets/icons/' + bitmapName + '.png\', width: ' + bitmapW + ', height: ' + bitmapH + ', color: YOUR_COLOR, colorBlendMode: BlendMode.srcIn,)';
2559
+ element.imageInfo.exportHint = 'Sketch 导出命令: File > Export Layers > 选择此图层 > 格式 PNG @3x, 放入 assets/icons/';
2530
2560
  }
2531
2561
 
2532
2562
  // Symbol Instance — override 真实值