@pedroab0/skills 1.0.1 → 1.2.0

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 (29) hide show
  1. package/README.md +19 -3
  2. package/bin/cli.js +175 -35
  3. package/figma-extractor/README.md +14 -6
  4. package/figma-extractor/SKILL.md +18 -16
  5. package/figma-extractor/figma-plugin/README.md +10 -5
  6. package/figma-extractor/figma-plugin/code.js +461 -87
  7. package/figma-extractor/figma-plugin/ui.html +76 -23
  8. package/figma-extractor/scripts/fetch_figma.js +465 -61
  9. package/figma-node-builder/README.md +1 -1
  10. package/figma-node-builder/SKILL.md +7 -8
  11. package/figma-node-builder/scripts/inspect_spec.js +15 -2
  12. package/figma-to-code/README.md +10 -4
  13. package/figma-to-code/SKILL.md +18 -16
  14. package/figma-to-code/scripts/fetch_figma.js +448 -53
  15. package/package.json +12 -3
  16. package/figma-extractor/demo/desktop_home.json +0 -2434
  17. package/figma-extractor/demo/dt_money_desktop_home.png +0 -0
  18. package/figma-extractor/demo/dt_money_preview.png +0 -0
  19. package/figma-extractor/demo/dt_money_selection.json +0 -472
  20. package/figma-extractor/demo/index.html +0 -188
  21. package/figma-extractor/demo/style.css +0 -360
  22. package/figma-extractor/figma-plugin/assets/cover-1920.png +0 -0
  23. package/figma-extractor/figma-plugin/assets/cover.jpg +0 -0
  24. package/figma-extractor/figma-plugin/assets/cover.png +0 -0
  25. package/figma-extractor/figma-plugin/assets/icon-128.png +0 -0
  26. package/figma-extractor/figma-plugin/assets/icon.png +0 -0
  27. package/figma-extractor/scripts/test_fetch_figma.js +0 -601
  28. package/figma-node-builder/scripts/test_inspect_spec.js +0 -148
  29. package/figma-to-code/scripts/test_fetch_figma.js +0 -581
@@ -1,148 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const assert = require('assert');
4
- const fs = require('fs');
5
- const path = require('path');
6
- const os = require('os');
7
- const {
8
- resolveSpecPath,
9
- inspectSpec,
10
- formatTerminalReport,
11
- formatMarkdownReport,
12
- } = require('./inspect_spec.js');
13
-
14
- console.log('--- Running Spec Inspector Unit Tests ---');
15
-
16
- // Mock Node AST tree
17
- const mockSpec = {
18
- name: 'Product Card',
19
- type: 'FRAME',
20
- bounds: { width: 360, height: 480 },
21
- layoutMode: 'VERTICAL',
22
- itemSpacing: 16,
23
- itemSpacingToken: 'spacing/md',
24
- padding: { top: 24, right: 24, bottom: 24, left: 24 },
25
- paddingToken: 'spacing/lg',
26
- cornerRadius: 12,
27
- cornerRadiusToken: 'radii/lg',
28
- fills: [{ type: 'SOLID', color: '#FFFFFF', token: 'color/surface' }],
29
- children: [
30
- {
31
- name: 'Badge Instance',
32
- type: 'INSTANCE',
33
- component: { name: 'Badge' },
34
- props: { variant: 'success', label: 'In Stock' },
35
- },
36
- {
37
- name: 'Title',
38
- type: 'TEXT',
39
- characters: 'Wireless Noise-Canceling Headphones',
40
- style: {
41
- fontFamily: 'Inter',
42
- fontSize: 20,
43
- fontWeight: 700,
44
- },
45
- fills: [{ type: 'SOLID', color: '#111827', token: 'color/text-primary' }],
46
- },
47
- {
48
- name: 'Description',
49
- type: 'TEXT',
50
- characters: 'Premium audio experience with active noise cancellation.',
51
- style: {
52
- fontFamily: 'Inter',
53
- fontSize: 14,
54
- fontWeight: 400,
55
- },
56
- },
57
- {
58
- name: 'Action Button',
59
- type: 'INSTANCE',
60
- component: { name: 'Button' },
61
- props: { variant: 'primary', size: 'md', hasIcon: true },
62
- },
63
- {
64
- name: 'Secondary Button',
65
- type: 'INSTANCE',
66
- component: { name: 'Button' },
67
- props: { variant: 'outline', size: 'md' },
68
- },
69
- ],
70
- };
71
-
72
- // 1. inspectSpec: dimensions and layout
73
- const report = inspectSpec(mockSpec, '/mock/.specs/card.json');
74
- assert.strictEqual(report.rootLayout.name, 'Product Card');
75
- assert.strictEqual(report.rootLayout.width, 360);
76
- assert.strictEqual(report.rootLayout.height, 480);
77
- assert.strictEqual(report.rootLayout.layoutMode, 'VERTICAL');
78
- assert.strictEqual(report.rootLayout.itemSpacing, 16);
79
- assert.strictEqual(report.rootLayout.itemSpacingToken, 'spacing/md');
80
- assert.strictEqual(report.rootLayout.paddingToken, 'spacing/lg');
81
- console.log(' ✓ inspectSpec: correctly extracts root dimensions and auto-layout metrics');
82
-
83
- // 2. inspectSpec: tokens
84
- assert.ok(report.tokens.colors.has('color/surface'), 'Includes surface color token');
85
- assert.ok(report.tokens.colors.has('color/text-primary'), 'Includes text color token');
86
- assert.ok(report.tokens.spacing.has('spacing/md'), 'Includes spacing/md token');
87
- assert.ok(report.tokens.radii.has('radii/lg'), 'Includes radii/lg token');
88
- console.log(' ✓ inspectSpec: aggregates design tokens across colors, spacing, and radii');
89
-
90
- // 3. inspectSpec: component instances & gaps
91
- assert.strictEqual(report.instances.size, 2, 'Detects 2 distinct components');
92
- assert.strictEqual(report.instances.get('Button').length, 2, 'Detects 2 Button instances');
93
- assert.strictEqual(report.instances.get('Badge').length, 1, 'Detects 1 Badge instance');
94
- assert.strictEqual(report.instances.get('Button')[0].variant, 'primary');
95
- assert.strictEqual(report.instances.get('Button')[1].variant, 'outline');
96
- console.log(' ✓ inspectSpec: aggregates component instances and variant prop shapes');
97
-
98
- // 4. inspectSpec: typography
99
- assert.strictEqual(report.typography.totalTextLayers, 2);
100
- assert.ok(report.typography.fontFamilies.has('Inter'));
101
- assert.ok(report.typography.fontSizes.has(20));
102
- assert.ok(report.typography.fontSizes.has(14));
103
- assert.ok(report.typography.fontWeights.has(700));
104
- console.log(' ✓ inspectSpec: extracts font families, sizes, weights, and text samples');
105
-
106
- // 5. formatTerminalReport & formatMarkdownReport
107
- const terminalText = formatTerminalReport(report);
108
- assert.ok(terminalText.includes('Product Card'));
109
- assert.ok(terminalText.includes('Vertical Flex (Column)'));
110
- assert.ok(terminalText.includes('<Button />'));
111
- assert.ok(terminalText.includes('<Badge />'));
112
- assert.ok(terminalText.includes('Component Gaps & Codebase Checklist'));
113
- console.log(' ✓ formatTerminalReport: formats clean box-drawing terminal report');
114
-
115
- const markdownText = formatMarkdownReport(report);
116
- assert.ok(markdownText.includes('### 📐 Figma Spec Summary: `card.json`'));
117
- assert.ok(markdownText.includes('`<Button />`'));
118
- assert.ok(markdownText.includes('`spacing/md`'));
119
- console.log(' ✓ formatMarkdownReport: formats Markdown table and component checklist');
120
-
121
- // 6. resolveSpecPath: resolution from disk
122
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'spec-test-'));
123
- try {
124
- const specsSubdir = path.join(tmpDir, '.specs');
125
- fs.mkdirSync(specsSubdir, { recursive: true });
126
- const testFile = path.join(specsSubdir, 'product.json');
127
- fs.writeFileSync(testFile, JSON.stringify(mockSpec), 'utf8');
128
-
129
- // Direct path
130
- assert.strictEqual(resolveSpecPath(testFile), testFile);
131
-
132
- // Shorthand in cwd
133
- const origCwd = process.cwd();
134
- try {
135
- process.chdir(tmpDir);
136
- const expected = fs.realpathSync(path.resolve(specsSubdir, 'product.json'));
137
- assert.strictEqual(fs.realpathSync(resolveSpecPath('product')), expected);
138
- assert.strictEqual(fs.realpathSync(resolveSpecPath('.specs/product')), expected);
139
- assert.strictEqual(fs.realpathSync(resolveSpecPath('.specs/product.json')), expected);
140
- console.log(' ✓ resolveSpecPath: resolves direct files, shorthand names, and .specs/ subdirectories');
141
- } finally {
142
- process.chdir(origCwd);
143
- }
144
- } finally {
145
- fs.rmSync(tmpDir, { recursive: true, force: true });
146
- }
147
-
148
- console.log('\nResults: 6/6 Spec Inspector tests passed.\n');