vibe-design-system 2.8.56 → 2.8.58

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/bin/init.js CHANGED
@@ -15,7 +15,7 @@
15
15
  import fs from "fs";
16
16
  import path from "path";
17
17
  import { fileURLToPath } from "url";
18
- import { spawnSync } from "child_process";
18
+ import { spawnSync, spawn } from "child_process";
19
19
 
20
20
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
21
  const INSTALLER_ROOT = path.join(__dirname, "..");
@@ -610,12 +610,11 @@ function ensureVdsConfig(projectRoot, srcPrefix) {
610
610
  const configPath = path.join(projectRoot, "vds.config.js");
611
611
  if (fs.existsSync(configPath)) return;
612
612
 
613
- // Detect shadcn/ui: if components/ui/ directory exists, add includeGroups by default
614
- const uiDir = path.join(projectRoot, srcPrefix || "src", "components", "ui");
615
- const hasShadcn = fs.existsSync(uiDir);
616
- const includeGroupsLine = hasShadcn
617
- ? ` includeGroups: ["shadcn", "UI", "ui"], // Auto-detected shadcn/ui: generate stories for UI components\n`
618
- : ` // includeGroups: ["shadcn", "UI"], // Uncomment to generate stories for shadcn/ui primitives\n`;
613
+ // includeGroups is intentionally OFF by default.
614
+ // shadcn/ui base components (Button, Avatar, Badge…) are generic library primitives —
615
+ // most projects only want their custom sections and page components in Storybook.
616
+ // To include shadcn/ui components: add includeGroups: ["shadcn", "UI", "ui"] to vds.config.js.
617
+ const includeGroupsLine = ` // includeGroups: ["shadcn", "UI"], // Uncomment to add shadcn/ui primitive stories\n`;
619
618
 
620
619
  const content = `/**
621
620
  * VDS Configuration — auto-created by VDS installer
@@ -715,8 +714,18 @@ runStorybookAdapt(projectRoot);
715
714
 
716
715
  // ADIM 8
717
716
  console.log("\n✅ VDS kuruldu!");
718
- console.log("→ npm run storybook — design system'ı aç (localhost:6006)");
719
- console.log("→ npm run storybook:bg — Storybook'u arka planda başlat (Cursor kapansa bile çalışır)");
720
717
  console.log("→ npm run vds:stories — tarama + story + provider (tek komut)");
721
718
  console.log("→ npm run vds:watch — otomatik güncelleme (watch modu)");
722
719
  console.log("\nNot: Storybook başlarken (Node 24+) DEP0190 uyarısı çıkarsa Storybook kaynaklıdır, güvenle yok sayabilirsiniz.\n");
720
+
721
+ // ADIM 10 — Storybook'u otomatik başlat
722
+ console.log("🚀 Storybook başlatılıyor → http://localhost:6006\n");
723
+ const sbProc = spawn("npm", ["run", "storybook"], {
724
+ stdio: "inherit",
725
+ cwd: projectRoot,
726
+ shell: process.platform === "win32",
727
+ });
728
+ sbProc.on("error", (err) => {
729
+ console.error("[VDS] Storybook başlatılamadı:", err.message);
730
+ console.log("→ Manuel başlatmak için: npm run storybook");
731
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-design-system",
3
- "version": "2.8.56",
3
+ "version": "2.8.58",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "homepage": "https://vibedesign.tech",
6
6
  "repository": {
@@ -246,10 +246,9 @@ const RECIPES = {
246
246
  )`,
247
247
  },
248
248
  Avatar: {
249
- imports: ["AvatarImage", "AvatarFallback"],
249
+ imports: ["AvatarFallback"],
250
250
  render: `(args) => (
251
251
  <ComponentRef {...args}>
252
- <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
253
252
  <AvatarFallback>JD</AvatarFallback>
254
253
  </ComponentRef>
255
254
  )`,
@@ -881,6 +880,58 @@ const COMPONENT_EXTRA_ARGS = {
881
880
  ...(VDS_CONFIG.componentExtraArgs ?? {}),
882
881
  };
883
882
 
883
+ // ---------------------------------------------------------------------------
884
+ // USAGE SCANNER — reads project sources to find actual component usage patterns
885
+ // e.g. <Button className="bg-[#5409da] text-white rounded-[10px]"> → generates
886
+ // a "ProjectPrimary" story with the real project styling instead of generic CVA variants.
887
+ // ---------------------------------------------------------------------------
888
+ const _SCAN_IGNORE_DIRS = new Set(["node_modules", ".next", "dist", "build", ".git", ".storybook"]);
889
+
890
+ function scanComponentUsages(componentName, projectRoot) {
891
+ const uiPathFrag = path.join("components", "ui") + path.sep;
892
+ const classNameCounts = new Map(); // className → count
893
+
894
+ function walk(dir) {
895
+ let entries;
896
+ try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }
897
+ for (const e of entries) {
898
+ if (_SCAN_IGNORE_DIRS.has(e.name)) continue;
899
+ const full = path.join(dir, e.name);
900
+ if (e.isDirectory()) { walk(full); continue; }
901
+ if (!/\.(tsx|jsx|ts|js)$/.test(e.name)) continue;
902
+ if (full.includes(uiPathFrag)) continue; // Skip ui/ directory itself
903
+ if (e.name.includes(".stories.")) continue; // Skip story files
904
+ let src;
905
+ try { src = fs.readFileSync(full, "utf-8"); } catch { continue; }
906
+ if (!src.includes(`<${componentName}`)) continue;
907
+
908
+ // Match <ComponentName ... > or <ComponentName ... />
909
+ const re = new RegExp(`<${componentName}(?:\\s+([^>]*?))?(?:\\s*/>|\\s*>)`, "g");
910
+ let m;
911
+ while ((m = re.exec(src)) !== null) {
912
+ const propsStr = m[1] || "";
913
+ // Extract className="..." — single or double quotes
914
+ const classM = propsStr.match(/className=["']([^"']+)["']/);
915
+ if (!classM) continue;
916
+ const cn = classM[1].trim();
917
+ if (!cn) continue;
918
+ // Only include usages that have project-specific (non-CVA) styling
919
+ // i.e. hex colors, arbitrary Tailwind values, custom font families
920
+ const hasCustomStyling = /bg-\[|text-\[|rounded-\[|#[0-9a-fA-F]{3,8}|\[font-family:/.test(cn);
921
+ if (!hasCustomStyling) continue;
922
+ classNameCounts.set(cn, (classNameCounts.get(cn) || 0) + 1);
923
+ }
924
+ }
925
+ }
926
+
927
+ walk(projectRoot);
928
+
929
+ return [...classNameCounts.entries()]
930
+ .sort((a, b) => b[1] - a[1])
931
+ .slice(0, 4)
932
+ .map(([className, count]) => ({ className, count }));
933
+ }
934
+
884
935
  /** Render'da args'a uygulanacak fallback (useState(estimate.toString()) gibi kullanımlar için; args/Controls undefined yapsa bile). */
885
936
  const RENDER_ARGS_FALLBACKS = {
886
937
  TaskEstimateInput: ", estimate: (args && args.estimate) ?? 0, value: (args && args.value) ?? 0, task: (args && args.task) ?? { id: \"1\", title: \"Example\", estimate: 0 }",
@@ -1867,6 +1918,28 @@ function buildStoryFileContent(comp) {
1867
1918
  lines.push(`};`);
1868
1919
  }
1869
1920
 
1921
+ // --- Project-specific usage stories ---
1922
+ // Scan actual component usages in project source. If custom className overrides found
1923
+ // (hex colors, arbitrary Tailwind values), append stories that show the REAL project styling.
1924
+ const usagePatterns = scanComponentUsages(componentName, PROJECT_ROOT);
1925
+ if (usagePatterns.length > 0) {
1926
+ const usageStoryNames = ["ProjectPrimary", "ProjectSecondary", "ProjectTertiary", "ProjectQuaternary"];
1927
+ lines.push("");
1928
+ lines.push(`// — Project-specific stories auto-detected from actual ${componentName} usage in this codebase.`);
1929
+ lines.push(`// These reflect how ${componentName} is styled in the project, not generic variants.`);
1930
+ for (let i = 0; i < usagePatterns.length; i++) {
1931
+ const { className } = usagePatterns[i];
1932
+ const sName = usageStoryNames[i];
1933
+ lines.push(`export const ${sName}: Story = {`);
1934
+ lines.push(` render: () => (`);
1935
+ lines.push(` <ComponentRef className="${className}">`);
1936
+ lines.push(` ${componentName}`);
1937
+ lines.push(` </ComponentRef>`);
1938
+ lines.push(` ),`);
1939
+ lines.push(`};`);
1940
+ }
1941
+ }
1942
+
1870
1943
  return lines.join("\n");
1871
1944
  }
1872
1945
 
@@ -3496,6 +3569,12 @@ function main() {
3496
3569
  if (!onlyName) {
3497
3570
  try {
3498
3571
  const existing = fs.readdirSync(STORIES_DIR);
3572
+ // Remove macOS copy artifacts: "Button.stories 2.tsx", "Badge.stories 3.tsx", etc.
3573
+ for (const name of existing) {
3574
+ if (/\.stories \d+\.(tsx|ts|jsx|js)$/.test(name)) {
3575
+ try { fs.unlinkSync(path.join(STORIES_DIR, name)); } catch { /* ignore */ }
3576
+ }
3577
+ }
3499
3578
  for (const name of existing) {
3500
3579
  if (name === "foundations") continue;
3501
3580
  if (