vibe-design-system 2.6.2 → 2.7.1

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": "vibe-design-system",
3
- "version": "2.6.2",
3
+ "version": "2.7.1",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -943,19 +943,58 @@ function parseCssVarBlock(block) {
943
943
  return out;
944
944
  }
945
945
 
946
- /** Return only theme.extend.colors from tailwind config (user-defined colors), not the default Tailwind palette. */
946
+ /** Return only theme.extend.colors from tailwind config (user-defined colors), not the default Tailwind palette. Also supports tailwind.config.ts (hex colors only). */
947
947
  function getTailwindExtendColors() {
948
948
  try {
949
- const twPath = path.join(PROJECT_ROOT, "tailwind.config.js");
949
+ const twPathJs = path.join(PROJECT_ROOT, "tailwind.config.js");
950
950
  const twPathMjs = path.join(PROJECT_ROOT, "tailwind.config.mjs");
951
+ const twPathTs = path.join(PROJECT_ROOT, "tailwind.config.ts");
951
952
  let config = null;
952
- if (fs.existsSync(twPath)) {
953
- config = projectRequire(twPath);
954
- } else if (fs.existsSync(twPathMjs)) {
955
- config = projectRequire(twPathMjs);
953
+
954
+ // Prefer executable JS/MJS config when available
955
+ if (fs.existsSync(twPathJs) || fs.existsSync(twPathMjs)) {
956
+ const pathToUse = fs.existsSync(twPathJs) ? twPathJs : twPathMjs;
957
+ config = projectRequire(pathToUse);
958
+ if (config && typeof config === "object" && config.default) config = config.default;
959
+ return config?.theme?.extend?.colors ?? null;
960
+ }
961
+
962
+ // Fallback: parse tailwind.config.ts for hex colors under theme.extend.colors
963
+ if (fs.existsSync(twPathTs)) {
964
+ const raw = fs.readFileSync(twPathTs, "utf-8");
965
+ const m = raw.match(/colors\s*:\s*\{([\s\S]*?)\}\s*[,}]/);
966
+ if (!m) return null;
967
+ const body = m[1];
968
+ const out = {};
969
+
970
+ // Nested objects: primary: { DEFAULT: "#...", foreground: "#..." }
971
+ const nestedRe = /([\w-]+)\s*:\s*\{([^}]+)\}/g;
972
+ let match;
973
+ while ((match = nestedRe.exec(body)) !== null) {
974
+ const parent = match[1];
975
+ const inner = match[2];
976
+ const innerMap = {};
977
+ const hexRe = /["']?([\w-]+)["']?\s*:\s*["'](#[0-9a-fA-F]{3,8})["']/g;
978
+ let m2;
979
+ while ((m2 = hexRe.exec(inner)) !== null) {
980
+ innerMap[m2[1]] = m2[2];
981
+ }
982
+ if (Object.keys(innerMap).length > 0) out[parent] = innerMap;
983
+ }
984
+
985
+ // Top-level simple entries: brand: "#AEF33F"
986
+ const simpleHexRe = /["']?([\w-]+)["']?\s*:\s*["'](#[0-9a-fA-F]{3,8})["']/g;
987
+ let m3;
988
+ while ((m3 = simpleHexRe.exec(body)) !== null) {
989
+ const key = m3[1];
990
+ const hex = m3[2];
991
+ if (!out[key]) out[key] = hex;
992
+ }
993
+
994
+ return Object.keys(out).length ? out : null;
956
995
  }
957
- if (config && typeof config === "object" && config.default) config = config.default;
958
- return config?.theme?.extend?.colors ?? null;
996
+
997
+ return null;
959
998
  } catch (_) {
960
999
  return null;
961
1000
  }
@@ -138,9 +138,29 @@ function collectProvidersAndWarnings(projectRoot) {
138
138
  const providersToAdd = [];
139
139
  const hooksWithoutProvider = new Set();
140
140
  for (const hook of allHooksUsed) {
141
- const providerName = HOOK_TO_PROVIDER[hook];
142
- const importPath = findProviderExportPath(projectRoot, providerName, hook);
143
- if (importPath) {
141
+ let providerName = HOOK_TO_PROVIDER[hook] || null;
142
+ let importPath = null;
143
+
144
+ const candidateNames = [];
145
+ if (providerName) {
146
+ candidateNames.push(providerName);
147
+ } else if (/^use[A-Z]/.test(hook)) {
148
+ const base = hook.slice(3);
149
+ candidateNames.push(base + "Provider");
150
+ candidateNames.push(base + "ContextProvider");
151
+ candidateNames.push(base + "Context");
152
+ }
153
+
154
+ for (const name of candidateNames) {
155
+ const foundPath = findProviderExportPath(projectRoot, name, hook);
156
+ if (foundPath) {
157
+ providerName = name;
158
+ importPath = foundPath;
159
+ break;
160
+ }
161
+ }
162
+
163
+ if (providerName && importPath) {
144
164
  if (!providersToAdd.some((p) => p.name === providerName)) {
145
165
  providersToAdd.push({ name: providerName, importPath });
146
166
  }