@wz927/codedesign 0.2.16 → 0.2.18

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.
@@ -144,7 +144,7 @@ async function loadFontFor(props) {
144
144
  }
145
145
  // ─── Ops ─────────────────────────────────────────────────────────────────
146
146
  async function handle(req) {
147
- var _a, _b, _c, _d, _e, _f, _g, _h;
147
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
148
148
  const p = (_a = req.params) !== null && _a !== void 0 ? _a : {};
149
149
  switch (req.op) {
150
150
  case 'getCurrentPage':
@@ -248,12 +248,34 @@ async function handle(req) {
248
248
  if ('resize' in n && (typeof patch.width === 'number' || typeof patch.height === 'number')) {
249
249
  n.resize((_d = patch.width) !== null && _d !== void 0 ? _d : n.width, (_e = patch.height) !== null && _e !== void 0 ? _e : n.height);
250
250
  }
251
- for (const k of ['x', 'y', 'cornerRadius', 'opacity', 'rotation', 'visible', 'name', 'itemSpacing',
251
+ for (const k of ['x', 'y', 'opacity', 'rotation', 'visible', 'name', 'itemSpacing',
252
252
  'paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom', 'strokeWeight', 'layoutMode',
253
253
  'primaryAxisAlignItems', 'counterAxisAlignItems', 'clipsContent', 'textAlignHorizontal', 'fontSize']) {
254
254
  if (patch[k] !== undefined)
255
255
  n[k] = patch[k];
256
256
  }
257
+ // cornerRadius: number → uniform; [tl,tr,br,bl] → per-corner
258
+ if (patch.cornerRadius !== undefined) {
259
+ const cr = patch.cornerRadius;
260
+ if (typeof cr === 'number') {
261
+ n.cornerRadius = cr;
262
+ }
263
+ else if (Array.isArray(cr) && cr.length === 4) {
264
+ n.topLeftRadius = cr[0];
265
+ n.topRightRadius = cr[1];
266
+ n.bottomRightRadius = cr[2];
267
+ n.bottomLeftRadius = cr[3];
268
+ }
269
+ }
270
+ // Also support explicit per-corner keys
271
+ if (patch.topLeftRadius !== undefined)
272
+ n.topLeftRadius = patch.topLeftRadius;
273
+ if (patch.topRightRadius !== undefined)
274
+ n.topRightRadius = patch.topRightRadius;
275
+ if (patch.bottomRightRadius !== undefined)
276
+ n.bottomRightRadius = patch.bottomRightRadius;
277
+ if (patch.bottomLeftRadius !== undefined)
278
+ n.bottomLeftRadius = patch.bottomLeftRadius;
257
279
  if (patch.fills)
258
280
  n.fills = patch.fills.map(toPaint);
259
281
  if (patch.strokes)
@@ -321,7 +343,14 @@ async function handle(req) {
321
343
  }));
322
344
  case 'createInstance': {
323
345
  const all = figma.root.findAllWithCriteria({ types: ['COMPONENT'] });
324
- const comp = all.find((c) => c.key === p.componentKey || c.id === p.componentKey);
346
+ let comp = all.find((c) => c.key === p.componentKey || c.id === p.componentKey);
347
+ // If not found locally, try to import from a team library by component key.
348
+ if (!comp && p.componentKey) {
349
+ try {
350
+ comp = await figma.importComponentByKeyAsync(p.componentKey);
351
+ }
352
+ catch { /* not in library either; throw below */ }
353
+ }
325
354
  if (!comp)
326
355
  throw new Error('Component not found: ' + p.componentKey);
327
356
  const inst = comp.createInstance();
@@ -330,8 +359,68 @@ async function handle(req) {
330
359
  inst.x = p.x;
331
360
  if (typeof p.y === 'number')
332
361
  inst.y = p.y;
362
+ if (typeof p.width === 'number' && typeof p.height === 'number')
363
+ inst.resize(p.width, p.height);
333
364
  return nodeSummary(inst);
334
365
  }
366
+ case 'createVector': {
367
+ // Draw an icon/shape using SVG path data.
368
+ // params: { parentId?, vectorPaths: [{windingRule, data}], fills, strokes, strokeWeight, x, y, width, height, name }
369
+ const vec = figma.createVector();
370
+ getParent(p.parentId).appendChild(vec);
371
+ if (p.vectorPaths)
372
+ vec.vectorPaths = p.vectorPaths;
373
+ if (p.fills)
374
+ vec.fills = p.fills.map(toPaint);
375
+ if (p.strokes)
376
+ vec.strokes = p.strokes.map(toPaint);
377
+ if (typeof p.strokeWeight === 'number')
378
+ vec.strokeWeight = p.strokeWeight;
379
+ if (typeof p.x === 'number')
380
+ vec.x = p.x;
381
+ if (typeof p.y === 'number')
382
+ vec.y = p.y;
383
+ if (typeof p.width === 'number' && typeof p.height === 'number')
384
+ vec.resize(p.width, p.height);
385
+ if (typeof p.name === 'string')
386
+ vec.name = p.name;
387
+ return nodeSummary(vec);
388
+ }
389
+ case 'createLine': {
390
+ // A simple line / divider.
391
+ // params: { parentId?, x, y, length, vertical?, strokeWeight, color:{r,g,b}, name }
392
+ const line = figma.createLine();
393
+ getParent(p.parentId).appendChild(line);
394
+ if (typeof p.x === 'number')
395
+ line.x = p.x;
396
+ if (typeof p.y === 'number')
397
+ line.y = p.y;
398
+ const len = (_g = p.length) !== null && _g !== void 0 ? _g : 100;
399
+ line.resize(p.vertical ? 0 : len, p.vertical ? len : 0);
400
+ if (p.color)
401
+ line.strokes = [{ type: 'SOLID', color: p.color, opacity: (_h = p.color.a) !== null && _h !== void 0 ? _h : 1 }];
402
+ if (typeof p.strokeWeight === 'number')
403
+ line.strokeWeight = p.strokeWeight;
404
+ if (typeof p.name === 'string')
405
+ line.name = p.name;
406
+ return nodeSummary(line);
407
+ }
408
+ case 'applyStyle': {
409
+ // Apply a local Figma style (paint/text/effect) to a node by style id.
410
+ // params: { id, fillStyleId?, strokeStyleId?, textStyleId?, effectStyleId? }
411
+ const n = figma.getNodeById(p.id);
412
+ if (!n)
413
+ throw new Error('Not found: ' + p.id);
414
+ if (p.fillStyleId !== undefined)
415
+ n.fillStyleId = p.fillStyleId;
416
+ if (p.strokeStyleId !== undefined)
417
+ n.strokeStyleId = p.strokeStyleId;
418
+ if (p.textStyleId !== undefined)
419
+ n.textStyleId = p.textStyleId;
420
+ if (p.effectStyleId !== undefined)
421
+ n.effectStyleId = p.effectStyleId;
422
+ return nodeSummary(n);
423
+ }
335
424
  case 'viewport': {
336
425
  const n = figma.getNodeById(p.id);
337
426
  if (!n)
@@ -345,10 +434,10 @@ async function handle(req) {
345
434
  const n = figma.getNodeById(p.id);
346
435
  if (!n || !('exportAsync' in n))
347
436
  throw new Error('Node not exportable');
348
- const format = ((_g = p.format) !== null && _g !== void 0 ? _g : 'PNG').toUpperCase();
437
+ const format = ((_j = p.format) !== null && _j !== void 0 ? _j : 'PNG').toUpperCase();
349
438
  const settings = { format };
350
439
  if (format === 'PNG' || format === 'JPG')
351
- settings.constraint = { type: 'SCALE', value: (_h = p.scale) !== null && _h !== void 0 ? _h : 2 };
440
+ settings.constraint = { type: 'SCALE', value: (_k = p.scale) !== null && _k !== void 0 ? _k : 2 };
352
441
  const bytes = await n.exportAsync(settings);
353
442
  const b64 = figma.base64Encode(bytes);
354
443
  return { bytesBase64: b64, format };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wz927/codedesign",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "description": "Terminal AI agent for designers — drive Figma through natural-language conversation.",
5
5
  "type": "module",
6
6
  "bin": {