@texturehq/edges 1.0.2 → 1.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@texturehq/edges",
3
- "version": "1.0.2",
3
+ "version": "1.1.0",
4
4
  "author": "Nicholas Brown <nick@texturehq.com>",
5
5
  "description": "A shared component library for Texture",
6
6
  "type": "module",
@@ -117,6 +117,8 @@
117
117
  "@vitejs/plugin-react": "^4.2.1",
118
118
  "@vitest/coverage-v8": "^3.1.1",
119
119
  "@vitest/ui": "^3.1.1",
120
+ "acorn": "^8.15.0",
121
+ "acorn-jsx": "^5.3.2",
120
122
  "autoprefixer": "^10.4.19",
121
123
  "jsdom": "^24.0.0",
122
124
  "postcss": "^8.4.35",
@@ -10,7 +10,11 @@ try {
10
10
  console.log("✅ Theme CSS copied to dist");
11
11
 
12
12
  // Copy style layer files to dist
13
- const styleFiles = ["src/styles/animations.css", "src/styles/computed.css", "src/styles/utilities.css"];
13
+ const styleFiles = [
14
+ "src/styles/animations.css",
15
+ "src/styles/computed.css",
16
+ "src/styles/utilities.css",
17
+ ];
14
18
 
15
19
  // Create styles directory in dist
16
20
  if (!fs.existsSync("dist/styles")) {
@@ -26,7 +30,10 @@ try {
26
30
  });
27
31
 
28
32
  // Copy generated token CSS to dist (if they exist)
29
- const tokenFiles = ["src/generated/tailwind-tokens-light.css", "src/generated/tailwind-tokens-dark.css"];
33
+ const tokenFiles = [
34
+ "src/generated/tailwind-tokens-light.css",
35
+ "src/generated/tailwind-tokens-dark.css",
36
+ ];
30
37
 
31
38
  // Create generated directory in dist
32
39
  if (!fs.existsSync("dist/generated")) {
@@ -68,16 +68,23 @@ function getJsdocAbove(content, idx) {
68
68
 
69
69
  function extractProps(content, componentName) {
70
70
  // Try `export interface <Name>Props` first
71
- const ifaceRe = new RegExp(`export\\s+interface\\s+${componentName}Props\\s*(?:extends\\s+[^{]+)?\\{([\\s\\S]*?)\\}`, "m");
71
+ const ifaceRe = new RegExp(
72
+ `export\\s+interface\\s+${componentName}Props\\s*(?:extends\\s+[^{]+)?\\{([\\s\\S]*?)\\}`,
73
+ "m"
74
+ );
72
75
  let m = ifaceRe.exec(content);
73
76
  if (!m) {
74
77
  // Try generic name: any exported *Props
75
- const anyIfaceRe = /export\s+interface\s+([A-Za-z0-9_]+Props)\s*(?:extends\s+[^{]+)?\{([\s\S]*?)\}/m;
78
+ const anyIfaceRe =
79
+ /export\s+interface\s+([A-Za-z0-9_]+Props)\s*(?:extends\s+[^{]+)?\{([\s\S]*?)\}/m;
76
80
  m = anyIfaceRe.exec(content);
77
81
  }
78
82
  if (!m) {
79
83
  // Try type alias
80
- const typeRe = new RegExp(`export\\s+type\\s+${componentName}Props\\s*=\\s*(?:[^{&]+&\s*)?([\\s\\S]*?)\\}`, "m");
84
+ const typeRe = new RegExp(
85
+ `export\\s+type\\s+${componentName}Props\\s*=\\s*(?:[^{&]+&\s*)?([\\s\\S]*?)\\}`,
86
+ "m"
87
+ );
81
88
  m = typeRe.exec(content);
82
89
  }
83
90
  const props = [];
@@ -118,7 +125,8 @@ function run() {
118
125
  // Description: JSDoc above `export function Name` or above `export interface NameProps`
119
126
  let idx = content.indexOf(`export function ${name}`);
120
127
  if (idx === -1) idx = content.search(new RegExp(`export\\s+(const|class)\\s+${name}\b`));
121
- if (idx === -1) idx = content.search(new RegExp(`export\\s+(interface|type)\\s+${name}Props\b`));
128
+ if (idx === -1)
129
+ idx = content.search(new RegExp(`export\\s+(interface|type)\\s+${name}Props\b`));
122
130
  const description = idx !== -1 ? getJsdocAbove(content, idx) : "";
123
131
 
124
132
  const props = extractProps(content, name);
@@ -138,8 +146,13 @@ function run() {
138
146
  generatedAt: new Date().toISOString(),
139
147
  components: components.sort((a, b) => a.name.localeCompare(b.name)),
140
148
  };
141
- fs.writeFileSync(path.join(DIST_DIR, "components.manifest.json"), JSON.stringify(manifest, null, 2));
142
- console.log(`Generated ${path.join("dist", "components.manifest.json")} with ${components.length} components.`);
149
+ fs.writeFileSync(
150
+ path.join(DIST_DIR, "components.manifest.json"),
151
+ JSON.stringify(manifest, null, 2)
152
+ );
153
+ console.log(
154
+ `Generated ${path.join("dist", "components.manifest.json")} with ${components.length} components.`
155
+ );
143
156
  } catch (err) {
144
157
  console.error("Failed to generate components manifest:", err);
145
158
  process.exitCode = 1;
@@ -147,5 +160,3 @@ function run() {
147
160
  }
148
161
 
149
162
  run();
150
-
151
-
@@ -5,7 +5,7 @@ const path = require("path");
5
5
 
6
6
  const setupCursorRules = () => {
7
7
  const cwd = process.cwd();
8
-
8
+
9
9
  // Don't run inside the edges package itself
10
10
  try {
11
11
  const pkgJsonPath = path.join(cwd, "package.json");
@@ -16,20 +16,20 @@ const setupCursorRules = () => {
16
16
  } catch {
17
17
  // ignore
18
18
  }
19
-
19
+
20
20
  // Try multiple possible locations for the templates directory
21
21
  const possibleTemplatePaths = [
22
22
  // Yalc path (the actual files)
23
- path.join(cwd, 'node_modules/.yalc/@texturehq/edges/templates/cursor-rules'),
23
+ path.join(cwd, "node_modules/.yalc/@texturehq/edges/templates/cursor-rules"),
24
24
  // Regular npm install path
25
- path.join(__dirname, '../templates/cursor-rules'),
25
+ path.join(__dirname, "../templates/cursor-rules"),
26
26
  // Alternative paths
27
- path.join(__dirname, '../../templates/cursor-rules'),
28
- path.join(__dirname, '../../../templates/cursor-rules'),
27
+ path.join(__dirname, "../../templates/cursor-rules"),
28
+ path.join(__dirname, "../../../templates/cursor-rules"),
29
29
  // Direct path from node_modules
30
- path.join(cwd, 'node_modules/@texturehq/edges/templates/cursor-rules'),
30
+ path.join(cwd, "node_modules/@texturehq/edges/templates/cursor-rules"),
31
31
  ];
32
-
32
+
33
33
  let templatesDir = null;
34
34
  for (const templatePath of possibleTemplatePaths) {
35
35
  if (fs.existsSync(templatePath)) {
@@ -37,69 +37,69 @@ const setupCursorRules = () => {
37
37
  break;
38
38
  }
39
39
  }
40
-
40
+
41
41
  if (!templatesDir) {
42
- console.log('⚠️ Could not find cursor rules templates. Tried paths:');
43
- possibleTemplatePaths.forEach(path => console.log(` - ${path}`));
42
+ console.log("⚠️ Could not find cursor rules templates. Tried paths:");
43
+ possibleTemplatePaths.forEach((path) => console.log(` - ${path}`));
44
44
  return;
45
45
  }
46
-
46
+
47
47
  console.log(`✅ Found templates at: ${templatesDir}`);
48
-
48
+
49
49
  // Try to read package version from multiple locations
50
50
  const possiblePackageJsonPaths = [
51
51
  // Yalc path (the actual files)
52
- path.join(cwd, 'node_modules/.yalc/@texturehq/edges/package.json'),
52
+ path.join(cwd, "node_modules/.yalc/@texturehq/edges/package.json"),
53
53
  // Regular npm install path
54
- path.join(__dirname, '../package.json'),
55
- path.join(__dirname, '../../package.json'),
56
- path.join(__dirname, '../../../package.json'),
57
- path.join(cwd, 'node_modules/@texturehq/edges/package.json'),
54
+ path.join(__dirname, "../package.json"),
55
+ path.join(__dirname, "../../package.json"),
56
+ path.join(__dirname, "../../../package.json"),
57
+ path.join(cwd, "node_modules/@texturehq/edges/package.json"),
58
58
  ];
59
-
60
- let packageVersion = 'unknown';
59
+
60
+ let packageVersion = "unknown";
61
61
  for (const packageJsonPath of possiblePackageJsonPaths) {
62
62
  if (fs.existsSync(packageJsonPath)) {
63
63
  try {
64
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
64
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
65
65
  packageVersion = packageJson.version;
66
66
  console.log(`📦 Found package version: ${packageVersion}`);
67
67
  break;
68
- } catch (error) {
68
+ } catch (_error) {
69
69
  console.log(`⚠️ Could not read package.json at: ${packageJsonPath}`);
70
70
  }
71
71
  }
72
72
  }
73
-
74
- const templateFiles = fs.readdirSync(templatesDir).filter(file => file.endsWith('.mdc'));
75
-
73
+
74
+ const templateFiles = fs.readdirSync(templatesDir).filter((file) => file.endsWith(".mdc"));
75
+
76
76
  if (templateFiles.length === 0) {
77
- console.log('⚠️ No .mdc files found in templates directory');
77
+ console.log("⚠️ No .mdc files found in templates directory");
78
78
  return;
79
79
  }
80
-
80
+
81
81
  // Always use package-level rules for version-specific behavior
82
- const cursorDir = path.join(cwd, '.cursor');
83
- const rulesDir = path.join(cursorDir, 'rules');
84
-
82
+ const cursorDir = path.join(cwd, ".cursor");
83
+ const rulesDir = path.join(cursorDir, "rules");
84
+
85
85
  // Create directories recursively
86
86
  fs.mkdirSync(cursorDir, { recursive: true });
87
87
  fs.mkdirSync(rulesDir, { recursive: true });
88
-
88
+
89
89
  let copiedCount = 0;
90
-
91
- templateFiles.forEach(file => {
90
+
91
+ templateFiles.forEach((file) => {
92
92
  const templatePath = path.join(templatesDir, file);
93
-
93
+
94
94
  // Read template content and inject version info
95
- let templateContent = fs.readFileSync(templatePath, 'utf8');
96
-
95
+ let templateContent = fs.readFileSync(templatePath, "utf8");
96
+
97
97
  // Add version information to the rule
98
98
  const versionHeader = `\n\n<!-- @texturehq/edges version: ${packageVersion} -->\n`;
99
99
  templateContent = templateContent + versionHeader;
100
-
100
+
101
101
  const targetPath = path.join(rulesDir, file);
102
-
102
+
103
103
  // Always overwrite to ensure version-specific rules
104
104
  fs.writeFileSync(targetPath, templateContent, "utf8");
105
105
  copiedCount++;
@@ -108,44 +108,53 @@ const setupCursorRules = () => {
108
108
 
109
109
  // Additionally, try to render a components list rule from the manifest if available
110
110
  const possibleManifestPaths = [
111
- path.join(cwd, 'node_modules/.yalc/@texturehq/edges/dist/components.manifest.json'),
112
- path.join(cwd, 'node_modules/@texturehq/edges/dist/components.manifest.json')
111
+ path.join(cwd, "node_modules/.yalc/@texturehq/edges/dist/components.manifest.json"),
112
+ path.join(cwd, "node_modules/@texturehq/edges/dist/components.manifest.json"),
113
113
  ];
114
114
  let manifestPath = null;
115
115
  for (const p of possibleManifestPaths) {
116
- if (fs.existsSync(p)) { manifestPath = p; break; }
116
+ if (fs.existsSync(p)) {
117
+ manifestPath = p;
118
+ break;
119
+ }
117
120
  }
118
121
  if (manifestPath) {
119
122
  try {
120
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
123
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
121
124
  const lines = [
122
- '---',
123
- 'alwaysApply: true',
124
- '---',
125
- '',
126
- `## @texturehq/edges Components (v${manifest.version || 'unknown'})`,
127
- ''
125
+ "---",
126
+ "alwaysApply: true",
127
+ "---",
128
+ "",
129
+ `## @texturehq/edges Components (v${manifest.version || "unknown"})`,
130
+ "",
128
131
  ];
129
132
  for (const c of manifest.components || []) {
130
133
  lines.push(`- ${c.name}`);
131
134
  if (c.importRoot) lines.push(` - Import: \`import { ${c.name} } from "${c.importRoot}"\``);
132
- if (c.importPath) lines.push(` - Subpath: \`import { ${c.name} } from "${c.importPath}"\``);
135
+ if (c.importPath)
136
+ lines.push(` - Subpath: \`import { ${c.name} } from "${c.importPath}"\``);
133
137
  if (c.props && c.props.length) {
134
- const propNames = c.props.slice(0, 8).map(p => p.name).join(', ');
135
- lines.push(` - Props: ${propNames}${c.props.length > 8 ? ', …' : ''}`);
138
+ const propNames = c.props
139
+ .slice(0, 8)
140
+ .map((p) => p.name)
141
+ .join(", ");
142
+ lines.push(` - Props: ${propNames}${c.props.length > 8 ? ", …" : ""}`);
136
143
  }
137
144
  }
138
- const outPath = path.join(rulesDir, 'edges-components.mdc');
145
+ const outPath = path.join(rulesDir, "edges-components.mdc");
139
146
 
140
- fs.writeFileSync(outPath, lines.join('\n'), "utf8");
141
- console.log(`✅ Wrote .cursor/rules/edges-components.mdc from manifest (${manifest.components?.length || 0} components)`);
147
+ fs.writeFileSync(outPath, lines.join("\n"), "utf8");
148
+ console.log(
149
+ `✅ Wrote .cursor/rules/edges-components.mdc from manifest (${manifest.components?.length || 0} components)`
150
+ );
142
151
  } catch (err) {
143
- console.log('⚠️ Failed to read components.manifest.json:', err.message);
152
+ console.log("⚠️ Failed to read components.manifest.json:", err.message);
144
153
  }
145
154
  } else {
146
- console.log('ℹ️ No components.manifest.json found; skipping edges-components.mdc generation');
155
+ console.log("ℹ️ No components.manifest.json found; skipping edges-components.mdc generation");
147
156
  }
148
-
157
+
149
158
  if (copiedCount > 0) {
150
159
  console.log(`🎨 Updated ${copiedCount} cursor rule(s) for @texturehq/edges v${packageVersion}`);
151
160
  }
@@ -1,10 +1,10 @@
1
1
  // scripts/setup-cursor-rules.js
2
- import fs from 'fs';
3
- import path from 'path';
2
+ import fs from "fs";
3
+ import path from "path";
4
4
 
5
5
  const setupCursorRules = () => {
6
6
  const cwd = process.env.INIT_CWD || process.cwd();
7
-
7
+
8
8
  // Don't run inside the edges package itself
9
9
  try {
10
10
  const pkgJsonPath = path.join(cwd, "package.json");
@@ -15,175 +15,191 @@ const setupCursorRules = () => {
15
15
  } catch {
16
16
  // ignore
17
17
  }
18
-
19
- const cursorTemplatesDir = path.join(path.dirname(new URL(import.meta.url).pathname), '../templates/cursor-rules');
20
- const claudeTemplatesDir = path.join(path.dirname(new URL(import.meta.url).pathname), '../templates/claude-rules');
21
- const cursorDir = path.join(cwd, '.cursor');
22
- const rulesDir = path.join(cursorDir, 'rules');
23
-
18
+
19
+ const cursorTemplatesDir = path.join(
20
+ path.dirname(new URL(import.meta.url).pathname),
21
+ "../templates/cursor-rules"
22
+ );
23
+ const claudeTemplatesDir = path.join(
24
+ path.dirname(new URL(import.meta.url).pathname),
25
+ "../templates/claude-rules"
26
+ );
27
+ const cursorDir = path.join(cwd, ".cursor");
28
+ const rulesDir = path.join(cursorDir, "rules");
29
+
24
30
  // Create directories recursively
25
31
  fs.mkdirSync(cursorDir, { recursive: true });
26
32
  fs.mkdirSync(rulesDir, { recursive: true });
27
-
33
+
28
34
  // Setup Cursor rules
29
35
  if (fs.existsSync(cursorTemplatesDir)) {
30
- const templateFiles = fs.readdirSync(cursorTemplatesDir).filter(file => file.endsWith('.mdc'));
31
-
36
+ const templateFiles = fs
37
+ .readdirSync(cursorTemplatesDir)
38
+ .filter((file) => file.endsWith(".mdc"));
39
+
32
40
  if (templateFiles.length > 0) {
33
41
  let copiedCount = 0;
34
-
35
- templateFiles.forEach(file => {
42
+
43
+ templateFiles.forEach((file) => {
36
44
  const templatePath = path.join(cursorTemplatesDir, file);
37
45
  const targetPath = path.join(rulesDir, file);
38
-
46
+
39
47
  // Always copy to ensure latest version
40
48
  fs.copyFileSync(templatePath, targetPath);
41
49
  copiedCount++;
42
50
  console.log(`✅ Updated .cursor/rules/${file}`);
43
51
  });
44
-
52
+
45
53
  if (copiedCount > 0) {
46
54
  console.log(`🎨 Added ${copiedCount} cursor rule(s) for @texturehq/edges design system`);
47
55
  }
48
56
  }
49
57
  }
50
-
58
+
51
59
  // Setup Claude rules
52
60
  if (fs.existsSync(claudeTemplatesDir)) {
53
- const claudeTemplateFiles = fs.readdirSync(claudeTemplatesDir).filter(file => file.endsWith('.md'));
54
-
61
+ const claudeTemplateFiles = fs
62
+ .readdirSync(claudeTemplatesDir)
63
+ .filter((file) => file.endsWith(".md"));
64
+
55
65
  if (claudeTemplateFiles.length > 0) {
56
66
  let claudeCopiedCount = 0;
57
-
67
+
58
68
  // Create .claude directory for namespaced files
59
- const claudeDir = path.join(cwd, '.claude');
69
+ const claudeDir = path.join(cwd, ".claude");
60
70
  fs.mkdirSync(claudeDir, { recursive: true });
61
-
62
- claudeTemplateFiles.forEach(file => {
71
+
72
+ claudeTemplateFiles.forEach((file) => {
63
73
  const templatePath = path.join(claudeTemplatesDir, file);
64
- // Namespace the file as edges-specific
65
- const namespacedFileName = 'edges.md';
74
+ // Namespace the file as edges-specific
75
+ const namespacedFileName = "edges.md";
66
76
  const targetPath = path.join(claudeDir, namespacedFileName);
67
-
77
+
68
78
  // Always copy to ensure latest version
69
79
  fs.copyFileSync(templatePath, targetPath);
70
80
  claudeCopiedCount++;
71
81
  console.log(`✅ Updated .claude/${namespacedFileName} for Claude`);
72
82
  });
73
-
83
+
74
84
  if (claudeCopiedCount > 0) {
75
- console.log(`🤖 Added ${claudeCopiedCount} namespaced Claude rule(s) for @texturehq/edges design system`);
85
+ console.log(
86
+ `🤖 Added ${claudeCopiedCount} namespaced Claude rule(s) for @texturehq/edges design system`
87
+ );
76
88
  }
77
89
  }
78
90
  }
79
91
 
80
92
  // Also render edges-components.mdc from manifest when present
81
93
  const manifestPath = [
82
- path.join(cwd, 'node_modules/@texturehq/edges/dist/components.manifest.json')
83
- ].find(p => fs.existsSync(p));
94
+ path.join(cwd, "node_modules/@texturehq/edges/dist/components.manifest.json"),
95
+ ].find((p) => fs.existsSync(p));
84
96
 
85
97
  if (manifestPath) {
86
98
  try {
87
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
88
-
99
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
100
+
89
101
  // Generate Cursor components list
90
102
  const cursorLines = [
91
- '---',
92
- 'alwaysApply: true',
93
- '---',
94
- '',
95
- `## @texturehq/edges Components (v${manifest.version || 'unknown'})`,
96
- '',
97
- '### Quick Reference',
98
- ''
103
+ "---",
104
+ "alwaysApply: true",
105
+ "---",
106
+ "",
107
+ `## @texturehq/edges Components (v${manifest.version || "unknown"})`,
108
+ "",
109
+ "### Quick Reference",
110
+ "",
99
111
  ];
100
-
112
+
101
113
  // Add quick reference list
102
114
  for (const c of manifest.components || []) {
103
- cursorLines.push(`- **${c.name}** - ${c.description || 'Component'}`);
115
+ cursorLines.push(`- **${c.name}** - ${c.description || "Component"}`);
104
116
  }
105
-
106
- cursorLines.push('');
107
- cursorLines.push('### Detailed Component Reference');
108
- cursorLines.push('');
109
-
117
+
118
+ cursorLines.push("");
119
+ cursorLines.push("### Detailed Component Reference");
120
+ cursorLines.push("");
121
+
110
122
  for (const c of manifest.components || []) {
111
123
  cursorLines.push(`#### ${c.name}`);
112
124
  if (c.description) {
113
125
  cursorLines.push(`${c.description}`);
114
126
  }
115
- cursorLines.push('');
116
- cursorLines.push('**Imports:**');
127
+ cursorLines.push("");
128
+ cursorLines.push("**Imports:**");
117
129
  cursorLines.push(`- \`import { ${c.name} } from "@texturehq/edges"\``);
118
130
  cursorLines.push(`- \`import { ${c.name} } from "@texturehq/edges/components/${c.name}"\``);
119
- cursorLines.push('');
120
-
131
+ cursorLines.push("");
132
+
121
133
  if (c.props && c.props.length) {
122
- cursorLines.push('**Props:**');
123
- c.props.forEach(prop => {
134
+ cursorLines.push("**Props:**");
135
+ c.props.forEach((prop) => {
124
136
  cursorLines.push(`- \`${prop.name}: ${prop.type}\``);
125
137
  });
126
- cursorLines.push('');
138
+ cursorLines.push("");
127
139
  }
128
- cursorLines.push('---');
129
- cursorLines.push('');
140
+ cursorLines.push("---");
141
+ cursorLines.push("");
130
142
  }
131
- const cursorOutPath = path.join(rulesDir, 'edges-components.mdc');
143
+ const cursorOutPath = path.join(rulesDir, "edges-components.mdc");
144
+
145
+ fs.writeFileSync(cursorOutPath, cursorLines.join("\n"), "utf8");
146
+ console.log(
147
+ `✅ Wrote .cursor/rules/edges-components.mdc from manifest (${manifest.components?.length || 0} components)`
148
+ );
132
149
 
133
- fs.writeFileSync(cursorOutPath, cursorLines.join('\n'), "utf8");
134
- console.log(`✅ Wrote .cursor/rules/edges-components.mdc from manifest (${manifest.components?.length || 0} components)`);
135
-
136
150
  // Generate Claude components list
137
151
  const claudeLines = [];
138
- claudeLines.push('### Quick Reference');
139
- claudeLines.push('');
140
-
152
+ claudeLines.push("### Quick Reference");
153
+ claudeLines.push("");
154
+
141
155
  // Add quick reference list
142
156
  for (const c of manifest.components || []) {
143
- claudeLines.push(`- **${c.name}** - ${c.description || 'Component'}`);
157
+ claudeLines.push(`- **${c.name}** - ${c.description || "Component"}`);
144
158
  }
145
-
146
- claudeLines.push('');
147
- claudeLines.push('### Detailed Component Reference');
148
- claudeLines.push('');
149
-
159
+
160
+ claudeLines.push("");
161
+ claudeLines.push("### Detailed Component Reference");
162
+ claudeLines.push("");
163
+
150
164
  for (const c of manifest.components || []) {
151
165
  claudeLines.push(`#### ${c.name}`);
152
166
  if (c.description) {
153
167
  claudeLines.push(`${c.description}`);
154
168
  }
155
- claudeLines.push('');
156
- claudeLines.push('**Imports:**');
169
+ claudeLines.push("");
170
+ claudeLines.push("**Imports:**");
157
171
  claudeLines.push(`- \`import { ${c.name} } from "@texturehq/edges"\``);
158
172
  claudeLines.push(`- \`import { ${c.name} } from "@texturehq/edges/components/${c.name}"\``);
159
- claudeLines.push('');
160
-
173
+ claudeLines.push("");
174
+
161
175
  if (c.props && c.props.length) {
162
- claudeLines.push('**Props:**');
163
- c.props.forEach(prop => {
176
+ claudeLines.push("**Props:**");
177
+ c.props.forEach((prop) => {
164
178
  claudeLines.push(`- \`${prop.name}: ${prop.type}\``);
165
179
  });
166
- claudeLines.push('');
180
+ claudeLines.push("");
167
181
  }
168
- claudeLines.push('---');
169
- claudeLines.push('');
182
+ claudeLines.push("---");
183
+ claudeLines.push("");
170
184
  }
171
-
185
+
172
186
  // Update Claude template with components list
173
- const claudeTemplatePath = path.join(claudeTemplatesDir, 'claude.md');
187
+ const claudeTemplatePath = path.join(claudeTemplatesDir, "claude.md");
174
188
  if (fs.existsSync(claudeTemplatePath)) {
175
- const claudeDir = path.join(cwd, '.claude');
189
+ const claudeDir = path.join(cwd, ".claude");
176
190
  fs.mkdirSync(claudeDir, { recursive: true });
177
-
178
- let claudeContent = fs.readFileSync(claudeTemplatePath, 'utf8');
191
+
192
+ let claudeContent = fs.readFileSync(claudeTemplatePath, "utf8");
179
193
  claudeContent = claudeContent.split("{{COMPONENTS_LIST}}").join(claudeLines.join("\n"));
180
-
181
- const claudeOutPath = path.join(claudeDir, 'edges.md');
194
+
195
+ const claudeOutPath = path.join(claudeDir, "edges.md");
182
196
  fs.writeFileSync(claudeOutPath, claudeContent, "utf8");
183
- console.log(`✅ Wrote .claude/edges.md with components list (${manifest.components?.length || 0} components)`);
197
+ console.log(
198
+ `✅ Wrote .claude/edges.md with components list (${manifest.components?.length || 0} components)`
199
+ );
184
200
  }
185
201
  } catch (err) {
186
- console.log('⚠️ Failed to read components.manifest.json:', err.message);
202
+ console.log("⚠️ Failed to read components.manifest.json:", err.message);
187
203
  }
188
204
  }
189
205
  };
@@ -193,5 +209,3 @@ try {
193
209
  } catch (err) {
194
210
  console.warn("setup-cursor-rules error:", err);
195
211
  }
196
-
197
-