@sangheepark/figma-ds-mcp 0.2.7 → 0.2.8

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.
@@ -239,13 +239,18 @@ function enrichSpec(traversal, mapping) {
239
239
  delete node['_ds_type'];
240
240
  }
241
241
  // Step 6: CSS → Figma 정규화
242
- // 6-pre: overflow → layout.clip-content 변환 (6-A 필터링 전에 처리)
243
- const overflow = node.style && node.style['overflow'];
244
- if (overflow === 'hidden' || overflow === 'scroll' || overflow === 'auto') {
242
+ // 6-pre: overflow → clip-content 변환 (style 또는 layout 어디에 있든 처리)
243
+ const styleOverflow = node.style && node.style['overflow'];
244
+ if (styleOverflow === 'hidden' || styleOverflow === 'scroll' || styleOverflow === 'auto') {
245
245
  node.layout = node.layout || {};
246
246
  node.layout['clip-content'] = true;
247
247
  delete node.style['overflow'];
248
248
  }
249
+ const layoutOverflow = node.layout && node.layout['overflow'];
250
+ if (layoutOverflow === 'hidden' || layoutOverflow === 'scroll' || layoutOverflow === 'auto') {
251
+ node.layout['clip-content'] = true;
252
+ delete node.layout['overflow'];
253
+ }
249
254
  // 6-A: CSS-only 속성 필터링 (Figma가 지원하지 않는 CSS 속성 제거)
250
255
  if (node.style) {
251
256
  for (const key of Object.keys(node.style)) {
@@ -254,6 +259,25 @@ function enrichSpec(traversal, mapping) {
254
259
  }
255
260
  }
256
261
  }
262
+ // 6-A2: layout에서 CSS position 키 → Figma x/y 변환 후 non-layout 키 제거
263
+ if (node.layout) {
264
+ const lay = node.layout;
265
+ // CSS top/left → Figma y/x (absolute positioning만)
266
+ if (lay['positioning'] === 'absolute') {
267
+ if (lay['top'] !== undefined && lay['y'] === undefined) {
268
+ lay['y'] = String(lay['top']);
269
+ }
270
+ if (lay['left'] !== undefined && lay['x'] === undefined) {
271
+ lay['x'] = String(lay['left']);
272
+ }
273
+ }
274
+ // non-layout 키 제거 (top, bottom, left, right, aspect-ratio, overflow 잔존 등)
275
+ for (const key of Object.keys(lay)) {
276
+ if (!LAYOUT_KEYS.has(key)) {
277
+ delete lay[key];
278
+ }
279
+ }
280
+ }
257
281
  // 6-B: direction 기본값 column (children 있는 frame/component에 direction 없으면)
258
282
  if ((node.type === 'frame' || node.type === 'component') && node.children && node.children.length > 0) {
259
283
  if (!node.layout?.direction) {
@@ -1156,10 +1180,20 @@ If no reviewNeeded, completes in 1 pass.`, {
1156
1180
  // Also produce manifest + section files for incremental build
1157
1181
  const outputDir = dirname(outputPath);
1158
1182
  const manifests = [];
1159
- for (const page of allPages) {
1160
- const manifest = splitSections(page, allComponents, outputDir);
1183
+ if (allPages.length === 1) {
1184
+ const manifest = splitSections(allPages[0], allComponents, outputDir);
1161
1185
  manifests.push(manifest);
1162
1186
  }
1187
+ else {
1188
+ for (let i = 0; i < allPages.length; i++) {
1189
+ const pageDir = join(outputDir, `page_${i}`);
1190
+ mkdirSync(pageDir, { recursive: true });
1191
+ const manifest = splitSections(allPages[i], allComponents, pageDir);
1192
+ manifests.push(manifest);
1193
+ }
1194
+ // Save combined manifest at root level
1195
+ writeFileSync(join(outputDir, 'manifest.json'), JSON.stringify(manifests, null, 2));
1196
+ }
1163
1197
  // Save full specs (legacy format) alongside manifest
1164
1198
  if (finalSpecs.length === 1) {
1165
1199
  writeFileSync(outputPath, JSON.stringify(finalSpecs[0], null, 2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sangheepark/figma-ds-mcp",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "MCP server for Code to Figma Bridge — bridges Claude Code to Figma plugin via WebSocket",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",