vibe-design-system 2.0.0 → 2.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/bin/init.js CHANGED
@@ -54,16 +54,41 @@ Geliştirme kuralları:
54
54
  `;
55
55
 
56
56
  const WATCH_MJS = `#!/usr/bin/env node
57
- import { spawnSync } from "child_process";
58
- import path from "path";
59
- import { fileURLToPath } from "url";
60
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
61
- const projectRoot = path.join(__dirname, "..");
62
- const r = spawnSync("node", [path.join(__dirname, "scan.mjs"), "--watch"], {
63
- cwd: projectRoot,
64
- stdio: "inherit",
65
- });
66
- process.exit(r.status ?? 0);
57
+ import { watch } from 'fs';
58
+ import { execSync } from 'child_process';
59
+ import { resolve } from 'path';
60
+
61
+ const ROOT = resolve(process.cwd());
62
+ const SRC = resolve(ROOT, 'src');
63
+ let timeout = null;
64
+
65
+ function run() {
66
+ const ts = new Date().toLocaleTimeString();
67
+ console.log(\`\\n[VDS \${ts}] Değişiklik algılandı, taranıyor...\`);
68
+ try {
69
+ execSync('node vds-core/scan.mjs', { stdio: 'inherit', cwd: ROOT });
70
+ execSync('node vds-core/story-generator.mjs', { stdio: 'inherit', cwd: ROOT });
71
+ console.log(\`[VDS \${ts}] ✅ Design system güncellendi.\`);
72
+ } catch (e) {
73
+ console.error(\`[VDS \${ts}] ❌ Hata:\`, e.message);
74
+ }
75
+ }
76
+
77
+ function onFileChange(eventType, filename) {
78
+ if (!filename) return;
79
+ if (filename.includes('stories/')) return;
80
+ if (filename.includes('vds-output')) return;
81
+ if (!filename.endsWith('.tsx') && !filename.endsWith('.ts') &&
82
+ !filename.endsWith('.css') && !filename.endsWith('.js')) return;
83
+ console.log(\`[VDS] Değişiklik: \${filename}\`);
84
+ clearTimeout(timeout);
85
+ timeout = setTimeout(run, 2000);
86
+ }
87
+
88
+ run();
89
+ console.log('[VDS] 👀 src/ klasörü izleniyor...');
90
+ console.log('[VDS] Durdurmak için Ctrl+C\\n');
91
+ watch(SRC, { recursive: true }, onFileChange);
67
92
  `;
68
93
 
69
94
  const STORYBOOK_EXAMPLE_FILES = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-design-system",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -92,6 +92,106 @@ function readPreviousOutput() {
92
92
  return null;
93
93
  }
94
94
 
95
+ function readPreviousOutputFull() {
96
+ try {
97
+ if (fs.existsSync(OUTPUT_FILE)) {
98
+ const raw = fs.readFileSync(OUTPUT_FILE, "utf-8");
99
+ return JSON.parse(raw);
100
+ }
101
+ } catch (_) {}
102
+ return null;
103
+ }
104
+
105
+ const CHANGELOG_MAX_ENTRIES = 20;
106
+
107
+ function getColorHex(val) {
108
+ if (val == null) return null;
109
+ if (typeof val === "string") return val;
110
+ if (typeof val === "object" && (val.hex || val.value)) return val.hex || val.value;
111
+ return null;
112
+ }
113
+
114
+ function compareColors(prevColors, newColors) {
115
+ const changes = [];
116
+ if (!prevColors && !newColors) return changes;
117
+ const prev = prevColors || {};
118
+ const next = newColors || {};
119
+ const allKeys = new Set([...Object.keys(prev), ...Object.keys(next)]);
120
+ for (const key of allKeys) {
121
+ if (key === "_dark") continue;
122
+ const fromHex = getColorHex(prev[key]);
123
+ const toHex = getColorHex(next[key]);
124
+ if (toHex == null) {
125
+ if (fromHex != null) changes.push({ type: "color_removed", name: key });
126
+ continue;
127
+ }
128
+ if (fromHex == null) {
129
+ changes.push({ type: "color_added", name: key, to: toHex });
130
+ continue;
131
+ }
132
+ if (fromHex !== toHex) {
133
+ changes.push({ type: "color_changed", name: key, from: fromHex, to: toHex });
134
+ }
135
+ }
136
+ if (next._dark && typeof next._dark === "object") {
137
+ const prevDark = prev._dark || {};
138
+ for (const key of Object.keys(next._dark)) {
139
+ const fromHex = getColorHex(prevDark[key]);
140
+ const toHex = getColorHex(next._dark[key]);
141
+ if (fromHex != null && toHex != null && fromHex !== toHex) {
142
+ changes.push({ type: "color_changed", name: `_dark.${key}`, from: fromHex, to: toHex });
143
+ } else if (fromHex == null && toHex != null) {
144
+ changes.push({ type: "color_added", name: `_dark.${key}`, to: toHex });
145
+ } else if (fromHex != null && toHex == null) {
146
+ changes.push({ type: "color_removed", name: `_dark.${key}` });
147
+ }
148
+ }
149
+ }
150
+ return changes;
151
+ }
152
+
153
+ function compareTypography(prevTypo, newTypo) {
154
+ const changes = [];
155
+ if (!prevTypo && !newTypo) return changes;
156
+ const prev = prevTypo || {};
157
+ const next = newTypo || {};
158
+ const allKeys = new Set([...Object.keys(prev), ...Object.keys(next)]);
159
+ for (const key of allKeys) {
160
+ const fromVal = prev[key] != null ? String(prev[key]) : null;
161
+ const toVal = next[key] != null ? String(next[key]) : null;
162
+ if (fromVal === toVal) continue;
163
+ if (toVal == null) continue;
164
+ changes.push({
165
+ type: "typography_changed",
166
+ key,
167
+ from: fromVal || "(none)",
168
+ to: toVal,
169
+ });
170
+ }
171
+ return changes;
172
+ }
173
+
174
+ function buildChangelogChanges(prevOutput, newOutput, added, removed) {
175
+ const changes = [];
176
+ const prevFoundations = prevOutput?.foundations;
177
+ const newFoundations = newOutput?.foundations;
178
+
179
+ const colorChanges = compareColors(prevFoundations?.colors, newFoundations?.colors);
180
+ changes.push(...colorChanges);
181
+
182
+ const typoChanges = compareTypography(prevFoundations?.typography, newFoundations?.typography);
183
+ changes.push(...typoChanges);
184
+
185
+ for (const a of added) {
186
+ changes.push({ type: "component_added", name: a.name });
187
+ }
188
+ for (const r of removed) {
189
+ changes.push({ type: "component_removed", name: r.name });
190
+ }
191
+
192
+ return changes;
193
+ }
194
+
95
195
  function readLastVersion() {
96
196
  try {
97
197
  if (fs.existsSync(HISTORY_FILE)) {
@@ -760,21 +860,37 @@ function scan() {
760
860
  componentSuggestions,
761
861
  };
762
862
 
763
- const prevComponents = readPreviousOutput();
863
+ const prevOutput = readPreviousOutputFull();
864
+ const prevComponents = prevOutput?.components ?? readPreviousOutput();
764
865
  const { added, removed, modified } = compareComponents(prevComponents, results);
765
866
  const hasChanges = added.length > 0 || removed.length > 0 || modified.length > 0;
766
867
 
868
+ const prevVersion = prevOutput?.version || readLastVersion() || "1.0.0";
869
+ const changelogChanges = buildChangelogChanges(prevOutput, output, added, removed);
870
+ const prevChangelog = Array.isArray(prevOutput?.changelog) ? prevOutput.changelog : [];
871
+ if (changelogChanges.length > 0) {
872
+ const nextVersion = incPatch(prevVersion);
873
+ const changelogEntry = {
874
+ version: nextVersion,
875
+ date: new Date().toISOString(),
876
+ changes: changelogChanges,
877
+ };
878
+ output.changelog = prevChangelog.concat(changelogEntry).slice(-CHANGELOG_MAX_ENTRIES);
879
+ output.version = nextVersion;
880
+ } else {
881
+ output.changelog = prevChangelog;
882
+ output.version = prevVersion;
883
+ }
884
+
767
885
  fs.writeFileSync(OUTPUT_FILE, JSON.stringify(output, null, 2), "utf-8");
768
886
  const publicDir = path.join(PROJECT_ROOT, "public");
769
887
  if (!fs.existsSync(publicDir)) fs.mkdirSync(publicDir, { recursive: true });
770
888
  fs.writeFileSync(PUBLIC_MANIFEST, JSON.stringify(output, null, 2), "utf-8");
771
889
 
772
890
  if (hasChanges) {
773
- const lastVersion = readLastVersion();
774
- const nextVersion = incPatch(lastVersion);
775
891
  const changes = [...added, ...removed, ...modified];
776
892
  const historyEntry = {
777
- version: nextVersion,
893
+ version: output.version,
778
894
  timestamp: new Date().toISOString(),
779
895
  branch: getGitBranch(),
780
896
  engineer: getGitEngineer(),
@@ -784,7 +900,7 @@ function scan() {
784
900
  entries.push(historyEntry);
785
901
  fs.writeFileSync(HISTORY_FILE, JSON.stringify(entries, null, 2), "utf-8");
786
902
  console.log(
787
- `[VDS] v${nextVersion}: ${added.length} added, ${removed.length} removed, ${modified.length} modified`
903
+ `[VDS] v${output.version}: ${added.length} added, ${removed.length} removed, ${modified.length} modified`
788
904
  );
789
905
  console.log(cliT("scanComplete", results.length));
790
906
  }
@@ -813,6 +813,65 @@ function writeComponentSuggestionsStory(componentSuggestions) {
813
813
  console.log("[VDS] Wrote " + path.relative(PROJECT_ROOT, path.join(foundationsDir, "ComponentSuggestions.stories.tsx")));
814
814
  }
815
815
 
816
+ function writeChangelogStory(changelog) {
817
+ if (!Array.isArray(changelog) || changelog.length === 0) return;
818
+ const foundationsDir = path.join(STORIES_DIR, "foundations");
819
+ ensureDir(foundationsDir);
820
+ const entries = changelog.map((e) => ({
821
+ version: e.version,
822
+ date: e.date,
823
+ changes: e.changes || [],
824
+ }));
825
+ const content =
826
+ [
827
+ "import type { Meta, StoryObj } from \"@storybook/react\";",
828
+ "",
829
+ "const meta = { title: \"Foundations/Changelog\" } satisfies Meta;",
830
+ "export default meta;",
831
+ "type Story = StoryObj;",
832
+ "",
833
+ `const changelog = ${JSON.stringify(entries)};`,
834
+ "",
835
+ "function ChangeItem({ c }) {",
836
+ " if (c.type === \"color_changed\")",
837
+ " return (",
838
+ " <div style={{ marginBottom: 8 }}>",
839
+ " <strong>{c.name}</strong>: <span style={{ color: \"#888\" }}>{c.from}</span> → <span style={{ color: \"#0f0\" }}>{c.to}</span>",
840
+ " <span style={{ display: \"inline-block\", width: 16, height: 16, backgroundColor: c.from, marginLeft: 8, border: \"1px solid #333\" }} />",
841
+ " <span style={{ display: \"inline-block\", width: 16, height: 16, backgroundColor: c.to, marginLeft: 4, border: \"1px solid #333\" }} />",
842
+ " </div>",
843
+ " );",
844
+ " if (c.type === \"color_added\") return <div style={{ marginBottom: 8 }}><strong>{c.name}</strong> added: <code>{c.to}</code> <span style={{ display: \"inline-block\", width: 16, height: 16, backgroundColor: c.to, marginLeft: 4, border: \"1px solid #333\" }} /></div>;",
845
+ " if (c.type === \"color_removed\") return <div style={{ marginBottom: 8, color: \"#888\" }}><strong>{c.name}</strong> removed</div>;",
846
+ " if (c.type === \"typography_changed\") return <div style={{ marginBottom: 8 }}><strong>{c.key}</strong>: {c.from} → {c.to}</div>;",
847
+ " if (c.type === \"component_added\") return <div style={{ marginBottom: 8, color: \"#0f0\" }}>+ {c.name}</div>;",
848
+ " if (c.type === \"component_removed\") return <div style={{ marginBottom: 8, color: \"#f88\" }}>− {c.name}</div>;",
849
+ " return <div style={{ marginBottom: 8 }}>{c.type}: {JSON.stringify(c)}</div>;",
850
+ "}",
851
+ "",
852
+ "export const Default: Story = {",
853
+ " render: () => (",
854
+ " <div style={{ padding: 24, fontFamily: \"system-ui, sans-serif\" }}>",
855
+ " <h2 style={{ marginBottom: 16 }}>VDS Changelog</h2>",
856
+ " <div style={{ display: \"flex\", flexDirection: \"column\", gap: 24 }}>",
857
+ " {changelog.map((e, i) => (",
858
+ " <div key={i} style={{ border: \"1px solid #333\", borderRadius: 8, padding: 16, background: \"#111\" }}>",
859
+ " <div style={{ fontWeight: 600, marginBottom: 4 }}>v{e.version}</div>",
860
+ " <div style={{ fontSize: 12, color: \"#888\", marginBottom: 12 }}>{e.date}</div>",
861
+ " {e.changes.length === 0 ? <div style={{ color: \"#666\" }}>No changes</div> : (",
862
+ " <div>{e.changes.map((c, j) => <ChangeItem key={j} c={c} />)}</div>",
863
+ " )}",
864
+ " </div>",
865
+ " ))}",
866
+ " </div>",
867
+ " </div>",
868
+ " ),",
869
+ "};",
870
+ ].join("\n");
871
+ fs.writeFileSync(path.join(foundationsDir, "Changelog.stories.tsx"), content, "utf-8");
872
+ console.log("[VDS] Wrote " + path.relative(PROJECT_ROOT, path.join(foundationsDir, "Changelog.stories.tsx")));
873
+ }
874
+
816
875
  function main() {
817
876
  if (!fs.existsSync(VDS_OUTPUT)) {
818
877
  console.error("[VDS] vds-output.json not found. Run `npm run vds` first.");
@@ -832,6 +891,10 @@ function main() {
832
891
  if (componentSuggestions?.length) {
833
892
  writeComponentSuggestionsStory(componentSuggestions);
834
893
  }
894
+ const changelog = data.changelog;
895
+ if (changelog?.length) {
896
+ writeChangelogStory(changelog);
897
+ }
835
898
  try {
836
899
  const fd = path.join(STORIES_DIR, "foundations");
837
900
  if (fs.existsSync(fd)) {
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ import { watch } from 'fs';
3
+ import { execSync } from 'child_process';
4
+ import { resolve } from 'path';
5
+
6
+ const ROOT = resolve(process.cwd());
7
+ const SRC = resolve(ROOT, 'src');
8
+ let timeout = null;
9
+
10
+ function run() {
11
+ const ts = new Date().toLocaleTimeString();
12
+ console.log(`\n[VDS ${ts}] Değişiklik algılandı, taranıyor...`);
13
+ try {
14
+ execSync('node vds-core/scan.mjs', { stdio: 'inherit', cwd: ROOT });
15
+ execSync('node vds-core/story-generator.mjs', { stdio: 'inherit', cwd: ROOT });
16
+ console.log(`[VDS ${ts}] ✅ Design system güncellendi.`);
17
+ } catch (e) {
18
+ console.error(`[VDS ${ts}] ❌ Hata:`, e.message);
19
+ }
20
+ }
21
+
22
+ function onFileChange(eventType, filename) {
23
+ if (!filename) return;
24
+ if (filename.includes('stories/')) return;
25
+ if (filename.includes('vds-output')) return;
26
+ if (!filename.endsWith('.tsx') && !filename.endsWith('.ts') &&
27
+ !filename.endsWith('.css') && !filename.endsWith('.js')) return;
28
+ console.log(`[VDS] Değişiklik: ${filename}`);
29
+ clearTimeout(timeout);
30
+ timeout = setTimeout(run, 2000);
31
+ }
32
+
33
+ run();
34
+ console.log('[VDS] 👀 src/ klasörü izleniyor...');
35
+ console.log('[VDS] Durdurmak için Ctrl+C\n');
36
+ watch(SRC, { recursive: true }, onFileChange);