@devfellowship/components 2.0.0 → 3.0.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 (2) hide show
  1. package/dist/cli.js +54 -367
  2. package/package.json +4 -8
package/dist/cli.js CHANGED
@@ -3,321 +3,10 @@
3
3
  // src/cli/index.ts
4
4
  import { Command } from "commander";
5
5
 
6
- // src/cli/commands/init.ts
7
- import fs from "fs-extra";
8
- import path from "path";
9
- import chalk2 from "chalk";
10
- import ora from "ora";
11
- import prompts from "prompts";
12
-
13
- // src/cli/types/config.ts
14
- import { z } from "zod";
15
- var configSchema = z.object({
16
- typescript: z.boolean().default(true),
17
- aliases: z.object({
18
- components: z.string().default("@/components/dfl"),
19
- hooks: z.string().default("@/hooks"),
20
- providers: z.string().default("@/providers"),
21
- pages: z.string().default("@/pages")
22
- }),
23
- registry: z.string().default("https://raw.githubusercontent.com/taigfs/dfl-components-cli/main/registry")
24
- });
25
-
26
- // src/cli/utils/logger.ts
27
- import chalk from "chalk";
28
- var logger = {
29
- info: (message) => console.log(chalk.blue("info"), message),
30
- success: (message) => console.log(chalk.green("\u2713"), message),
31
- warn: (message) => console.log(chalk.yellow("warn"), message),
32
- error: (message) => console.log(chalk.red("error"), message),
33
- break: () => console.log("")
34
- };
35
-
36
- // src/cli/commands/init.ts
37
- async function init(options) {
38
- const cwd = path.resolve(options.cwd);
39
- logger.info("Initializing dfl-components configuration...");
40
- logger.break();
41
- const configPath = path.join(cwd, "dfl-components.json");
42
- if (await fs.pathExists(configPath)) {
43
- const { overwrite } = await prompts({
44
- type: "confirm",
45
- name: "overwrite",
46
- message: "dfl-components.json already exists. Overwrite?",
47
- initial: false
48
- });
49
- if (!overwrite) {
50
- logger.warn("Aborted.");
51
- return;
52
- }
53
- }
54
- let config;
55
- if (options.yes) {
56
- config = configSchema.parse({
57
- aliases: {}
58
- });
59
- } else {
60
- const answers = await prompts([
61
- {
62
- type: "confirm",
63
- name: "typescript",
64
- message: "Would you like to use TypeScript?",
65
- initial: true
66
- },
67
- {
68
- type: "text",
69
- name: "componentsPath",
70
- message: "Where would you like to install components?",
71
- initial: "@/components/dfl"
72
- },
73
- {
74
- type: "text",
75
- name: "hooksPath",
76
- message: "Where would you like to install hooks?",
77
- initial: "@/hooks"
78
- },
79
- {
80
- type: "text",
81
- name: "providersPath",
82
- message: "Where would you like to install providers?",
83
- initial: "@/providers"
84
- },
85
- {
86
- type: "text",
87
- name: "pagesPath",
88
- message: "Where would you like to install pages?",
89
- initial: "@/pages"
90
- }
91
- ]);
92
- if (!answers.typescript) {
93
- logger.warn("Aborted.");
94
- return;
95
- }
96
- config = configSchema.parse({
97
- typescript: answers.typescript,
98
- aliases: {
99
- components: answers.componentsPath,
100
- hooks: answers.hooksPath,
101
- providers: answers.providersPath,
102
- pages: answers.pagesPath
103
- }
104
- });
105
- }
106
- const spinner = ora("Writing configuration...").start();
107
- try {
108
- await fs.writeJson(configPath, config, { spaces: 2 });
109
- spinner.succeed("Configuration saved to dfl-components.json");
110
- logger.break();
111
- logger.success("Project initialized successfully!");
112
- logger.break();
113
- console.log("You can now add components:");
114
- console.log(chalk2.cyan(" npx dfl-components add button"));
115
- console.log(chalk2.cyan(" npx dfl-components add card input"));
116
- console.log(chalk2.cyan(" npx dfl-components add auth-pages"));
117
- logger.break();
118
- } catch (error) {
119
- spinner.fail("Failed to write configuration");
120
- throw error;
121
- }
122
- }
123
-
124
- // src/cli/commands/add.ts
125
- import fs2 from "fs-extra";
126
- import path2 from "path";
127
- import chalk3 from "chalk";
128
- import ora2 from "ora";
129
- import prompts2 from "prompts";
130
-
131
- // src/cli/utils/get-config.ts
132
- import { cosmiconfig } from "cosmiconfig";
133
- async function getConfig(cwd) {
134
- const explorer = cosmiconfig("dfl-components", {
135
- searchPlaces: ["dfl-components.json"]
136
- });
137
- const result = await explorer.search(cwd);
138
- if (!result) {
139
- return null;
140
- }
141
- return configSchema.parse(result.config);
142
- }
143
-
144
- // src/cli/utils/get-registry.ts
145
- import fetch2 from "node-fetch";
146
- async function getRegistry(registryUrl) {
147
- const response = await fetch2(`${registryUrl}/registry.json`);
148
- if (!response.ok) {
149
- throw new Error(`Failed to fetch registry: ${response.statusText}`);
150
- }
151
- return response.json();
152
- }
153
- function getComponentFolderByCategory(category) {
154
- switch (category) {
155
- case "Hooks":
156
- return "hooks";
157
- case "Providers":
158
- return "providers";
159
- case "Pages":
160
- return "pages";
161
- default:
162
- return "components";
163
- }
164
- }
165
-
166
- // src/cli/utils/resolve-alias.ts
167
- function resolveAlias(aliasPath) {
168
- if (aliasPath.startsWith("@/")) {
169
- return aliasPath.replace("@/", "src/");
170
- }
171
- return aliasPath;
172
- }
173
- function getTargetPath(category, aliases) {
174
- switch (category) {
175
- case "Hooks":
176
- return resolveAlias(aliases.hooks);
177
- case "Providers":
178
- return resolveAlias(aliases.providers);
179
- case "Pages":
180
- return resolveAlias(aliases.pages);
181
- default:
182
- return resolveAlias(aliases.components);
183
- }
184
- }
185
-
186
- // src/cli/commands/add.ts
187
- async function add(components, options) {
188
- const cwd = path2.resolve(options.cwd);
189
- const config = await getConfig(cwd);
190
- if (!config) {
191
- logger.error("No dfl-components.json found.");
192
- console.log("Run", chalk3.cyan("npx dfl-components init"), "first.");
193
- return;
194
- }
195
- const spinner = ora2("Fetching registry...").start();
196
- try {
197
- let resolveDeps2 = function(name) {
198
- if (allComponents.has(name)) return;
199
- allComponents.add(name);
200
- const item = registry.items.find((i) => i.name === name);
201
- if (item?.registryDependencies) {
202
- for (const dep of item.registryDependencies) {
203
- resolveDeps2(dep);
204
- }
205
- }
206
- };
207
- var resolveDeps = resolveDeps2;
208
- const registry = await getRegistry(config.registry);
209
- let toInstall;
210
- if (options.all) {
211
- toInstall = registry.items.map((item) => item.name);
212
- } else if (components.length === 0) {
213
- spinner.stop();
214
- const { selected } = await prompts2({
215
- type: "multiselect",
216
- name: "selected",
217
- message: "Which components would you like to add?",
218
- choices: registry.items.map((item) => ({
219
- title: `${item.title} (${item.category})`,
220
- value: item.name,
221
- description: item.description
222
- })),
223
- min: 1
224
- });
225
- if (!selected || selected.length === 0) {
226
- logger.warn("No components selected.");
227
- return;
228
- }
229
- toInstall = selected;
230
- spinner.start("Fetching components...");
231
- } else {
232
- toInstall = components;
233
- }
234
- const validComponents = [];
235
- for (const name of toInstall) {
236
- const item = registry.items.find((i) => i.name === name);
237
- if (!item) {
238
- logger.warn(`Component "${name}" not found in registry. Skipping.`);
239
- } else {
240
- validComponents.push(name);
241
- }
242
- }
243
- if (validComponents.length === 0) {
244
- spinner.fail("No valid components to install.");
245
- return;
246
- }
247
- const allComponents = /* @__PURE__ */ new Set();
248
- for (const component of validComponents) {
249
- resolveDeps2(component);
250
- }
251
- spinner.text = `Installing ${allComponents.size} component(s)...`;
252
- const installed = [];
253
- const errors = [];
254
- for (const componentName of allComponents) {
255
- const registryItem = registry.items.find((i) => i.name === componentName);
256
- if (!registryItem) continue;
257
- try {
258
- const folder = getComponentFolderByCategory(registryItem.category);
259
- const url = `${config.registry}/${folder}/${componentName}.json`;
260
- const response = await fetch(url);
261
- if (!response.ok) {
262
- throw new Error(`Failed to fetch: ${response.statusText}`);
263
- }
264
- const componentData = await response.json();
265
- for (const file of componentData.files) {
266
- const targetDir = file.target ? path2.dirname(path2.join(cwd, "src", file.target)) : path2.join(cwd, getTargetPath(registryItem.category, config.aliases));
267
- const targetPath = file.target ? path2.join(cwd, "src", file.target) : path2.join(targetDir, file.path);
268
- if (await fs2.pathExists(targetPath)) {
269
- if (!options.overwrite && !options.yes) {
270
- spinner.stop();
271
- const { overwrite } = await prompts2({
272
- type: "confirm",
273
- name: "overwrite",
274
- message: `${path2.relative(cwd, targetPath)} already exists. Overwrite?`,
275
- initial: false
276
- });
277
- if (!overwrite) {
278
- logger.info(`Skipping ${path2.basename(targetPath)}`);
279
- continue;
280
- }
281
- spinner.start();
282
- } else if (!options.overwrite) {
283
- logger.info(`Skipping ${path2.basename(targetPath)} (use --overwrite to replace)`);
284
- continue;
285
- }
286
- }
287
- await fs2.ensureDir(path2.dirname(targetPath));
288
- await fs2.writeFile(targetPath, file.content);
289
- installed.push(targetPath);
290
- }
291
- } catch (error) {
292
- errors.push(`${componentName}: ${error instanceof Error ? error.message : "Unknown error"}`);
293
- }
294
- }
295
- spinner.succeed(`Installed ${installed.length} file(s)`);
296
- if (installed.length > 0) {
297
- logger.break();
298
- console.log(chalk3.green("Files created:"));
299
- for (const file of installed) {
300
- console.log(chalk3.gray(" -"), path2.relative(cwd, file));
301
- }
302
- }
303
- if (errors.length > 0) {
304
- logger.break();
305
- console.log(chalk3.red("Errors:"));
306
- for (const error of errors) {
307
- console.log(chalk3.gray(" -"), error);
308
- }
309
- }
310
- logger.break();
311
- } catch (error) {
312
- spinner.fail("Failed to add components");
313
- throw error;
314
- }
315
- }
316
-
317
6
  // src/cli/ux-paths/commands/init.ts
318
7
  import { mkdirSync, writeFileSync, existsSync } from "fs";
319
8
  import { resolve, basename } from "path";
320
- import chalk4 from "chalk";
9
+ import chalk from "chalk";
321
10
  function registerInit(program2) {
322
11
  program2.command("init").description("Bootstrap a .dfl-ux-paths/ directory in the current cwd.").option("--app-id <id>", "App identifier (defaults to current dir name).").option("--force", "Overwrite an existing flows.json if present.", false).action((opts) => {
323
12
  const cwd = process.cwd();
@@ -326,7 +15,7 @@ function registerInit(program2) {
326
15
  const appId = opts.appId || basename(cwd);
327
16
  if (existsSync(flowsPath) && !opts.force) {
328
17
  console.error(
329
- chalk4.yellow(`${flowsPath} already exists. Use --force to overwrite.`)
18
+ chalk.yellow(`${flowsPath} already exists. Use --force to overwrite.`)
330
19
  );
331
20
  process.exit(1);
332
21
  }
@@ -342,9 +31,9 @@ function registerInit(program2) {
342
31
  flows: []
343
32
  };
344
33
  writeFileSync(flowsPath, JSON.stringify(stub, null, 2) + "\n", "utf8");
345
- console.log(chalk4.green("Created"), flowsPath);
34
+ console.log(chalk.green("Created"), flowsPath);
346
35
  console.log(
347
- chalk4.gray(
36
+ chalk.gray(
348
37
  "Next steps: populate screens/flows, then run `dfl-components ux-paths validate` and `dfl-components ux-paths generate-mermaid`."
349
38
  )
350
39
  );
@@ -356,7 +45,7 @@ import { readFileSync, existsSync as existsSync2 } from "fs";
356
45
  import { resolve as resolve2 } from "path";
357
46
  import Ajv2020 from "ajv/dist/2020.js";
358
47
  import addFormats from "ajv-formats";
359
- import chalk5 from "chalk";
48
+ import chalk2 from "chalk";
360
49
 
361
50
  // src/cli/ux-paths/lib/load-schema.ts
362
51
  var SCHEMA_URL = "https://raw.githubusercontent.com/devfellowship/dfl-ux-paths/main/schema/v1.json";
@@ -383,16 +72,16 @@ async function loadSchemaV1() {
383
72
  // src/cli/ux-paths/commands/validate.ts
384
73
  function registerValidate(program2) {
385
74
  program2.command("validate [path]").description("Validate a flows.json against the DFL UX Paths v1 schema.").action(async (maybePath) => {
386
- const path3 = resolve2(process.cwd(), maybePath || ".dfl-ux-paths/flows.json");
387
- if (!existsSync2(path3)) {
388
- console.error(chalk5.red("File not found:"), path3);
75
+ const path = resolve2(process.cwd(), maybePath || ".dfl-ux-paths/flows.json");
76
+ if (!existsSync2(path)) {
77
+ console.error(chalk2.red("File not found:"), path);
389
78
  process.exit(1);
390
79
  }
391
80
  let doc;
392
81
  try {
393
- doc = JSON.parse(readFileSync(path3, "utf8"));
82
+ doc = JSON.parse(readFileSync(path, "utf8"));
394
83
  } catch (err) {
395
- console.error(chalk5.red("Invalid JSON:"), err.message);
84
+ console.error(chalk2.red("Invalid JSON:"), err.message);
396
85
  process.exit(1);
397
86
  }
398
87
  const ajv = new Ajv2020({ allErrors: true, strict: false });
@@ -401,19 +90,19 @@ function registerValidate(program2) {
401
90
  try {
402
91
  schema = await loadSchemaV1();
403
92
  } catch (err) {
404
- console.error(chalk5.red("Schema error:"), err.message);
93
+ console.error(chalk2.red("Schema error:"), err.message);
405
94
  process.exit(1);
406
95
  }
407
96
  const validate = ajv.compile(schema);
408
97
  const ok = validate(doc);
409
98
  if (ok) {
410
- console.log(chalk5.green("OK"), path3, "conforms to schema v1.");
99
+ console.log(chalk2.green("OK"), path, "conforms to schema v1.");
411
100
  process.exit(0);
412
101
  }
413
- console.error(chalk5.red("FAIL"), path3);
102
+ console.error(chalk2.red("FAIL"), path);
414
103
  for (const err of validate.errors ?? []) {
415
104
  console.error(
416
- chalk5.yellow(" -"),
105
+ chalk2.yellow(" -"),
417
106
  err.instancePath || "<root>",
418
107
  err.message,
419
108
  err.params ? JSON.stringify(err.params) : ""
@@ -426,7 +115,7 @@ function registerValidate(program2) {
426
115
  // src/cli/ux-paths/commands/generate-mermaid.ts
427
116
  import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3 } from "fs";
428
117
  import { resolve as resolve3, dirname } from "path";
429
- import chalk6 from "chalk";
118
+ import chalk3 from "chalk";
430
119
 
431
120
  // src/cli/ux-paths/lib/json-to-mermaid.ts
432
121
  function jsonToMermaid(doc) {
@@ -516,23 +205,23 @@ function escapeLabel(raw) {
516
205
  var HEADER = "%% AUTO-GENERATED by dfl-components ux-paths \u2014 do not edit by hand.\n";
517
206
  function registerGenerateMermaid(program2) {
518
207
  program2.command("generate-mermaid [path]").description("Generate a Mermaid graph from a flows.json file.").option("-o, --out <file>", "Output path (defaults to <dir>/flows.mmd).").action((maybePath, opts) => {
519
- const path3 = resolve3(process.cwd(), maybePath || ".dfl-ux-paths/flows.json");
520
- if (!existsSync3(path3)) {
521
- console.error(chalk6.red("File not found:"), path3);
208
+ const path = resolve3(process.cwd(), maybePath || ".dfl-ux-paths/flows.json");
209
+ if (!existsSync3(path)) {
210
+ console.error(chalk3.red("File not found:"), path);
522
211
  process.exit(1);
523
212
  }
524
- const doc = JSON.parse(readFileSync2(path3, "utf8"));
525
- const out = opts.out ? resolve3(process.cwd(), opts.out) : resolve3(dirname(path3), "flows.mmd");
213
+ const doc = JSON.parse(readFileSync2(path, "utf8"));
214
+ const out = opts.out ? resolve3(process.cwd(), opts.out) : resolve3(dirname(path), "flows.mmd");
526
215
  const body = HEADER + jsonToMermaid(doc);
527
216
  writeFileSync2(out, body, "utf8");
528
- console.log(chalk6.green("Wrote"), out);
217
+ console.log(chalk3.green("Wrote"), out);
529
218
  });
530
219
  }
531
220
 
532
221
  // src/cli/ux-paths/commands/diff.ts
533
222
  import { readFileSync as readFileSync3, existsSync as existsSync4 } from "fs";
534
223
  import { resolve as resolve4 } from "path";
535
- import chalk7 from "chalk";
224
+ import chalk4 from "chalk";
536
225
 
537
226
  // src/cli/ux-paths/lib/flows-diff.ts
538
227
  function flowsDiff(a, b) {
@@ -612,15 +301,15 @@ function registerDiff(program2) {
612
301
  console.log(JSON.stringify(result, null, 2));
613
302
  return;
614
303
  }
615
- console.log(chalk7.bold(`Diff ${a.app_id}@${a.app_version} \u2192 ${b.app_id}@${b.app_version}`));
616
- printSection("Screens added", result.screens.added, chalk7.green);
617
- printSection("Screens removed", result.screens.removed, chalk7.red);
618
- printSection("Actions added", result.actions.added, chalk7.green);
619
- printSection("Actions removed", result.actions.removed, chalk7.red);
620
- printSection("Flows added", result.flows.added, chalk7.green);
621
- printSection("Flows removed", result.flows.removed, chalk7.red);
304
+ console.log(chalk4.bold(`Diff ${a.app_id}@${a.app_version} \u2192 ${b.app_id}@${b.app_version}`));
305
+ printSection("Screens added", result.screens.added, chalk4.green);
306
+ printSection("Screens removed", result.screens.removed, chalk4.red);
307
+ printSection("Actions added", result.actions.added, chalk4.green);
308
+ printSection("Actions removed", result.actions.removed, chalk4.red);
309
+ printSection("Flows added", result.flows.added, chalk4.green);
310
+ printSection("Flows removed", result.flows.removed, chalk4.red);
622
311
  if (result.flows.changed.length > 0) {
623
- console.log(chalk7.yellow("\nFlows changed:"));
312
+ console.log(chalk4.yellow("\nFlows changed:"));
624
313
  for (const ch of result.flows.changed) {
625
314
  console.log(` - ${ch.name}: ${ch.reason}`);
626
315
  }
@@ -628,12 +317,12 @@ function registerDiff(program2) {
628
317
  });
629
318
  }
630
319
  function loadDoc(p) {
631
- const path3 = resolve4(process.cwd(), p);
632
- if (!existsSync4(path3)) {
633
- console.error(chalk7.red("File not found:"), path3);
320
+ const path = resolve4(process.cwd(), p);
321
+ if (!existsSync4(path)) {
322
+ console.error(chalk4.red("File not found:"), path);
634
323
  process.exit(1);
635
324
  }
636
- return JSON.parse(readFileSync3(path3, "utf8"));
325
+ return JSON.parse(readFileSync3(path, "utf8"));
637
326
  }
638
327
  function printSection(label, items, color) {
639
328
  if (items.length === 0) return;
@@ -648,7 +337,7 @@ ${label} (${items.length}):`));
648
337
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5 } from "fs";
649
338
  import { resolve as resolve5 } from "path";
650
339
  import { execSync } from "child_process";
651
- import chalk8 from "chalk";
340
+ import chalk5 from "chalk";
652
341
 
653
342
  // src/cli/ux-paths/lib/preserve-format.ts
654
343
  function replaceTopLevelStringField(raw, key, newValue) {
@@ -678,12 +367,12 @@ function registerStamp(program2) {
678
367
  "--no-preserve-format",
679
368
  "Reformat the whole file (legacy). By default, stamp surgically updates only app_version/generated_at, preserving the existing formatting (minimal diff)."
680
369
  ).action((maybePath, opts) => {
681
- const path3 = resolve5(process.cwd(), maybePath || ".dfl-ux-paths/flows.json");
682
- if (!existsSync5(path3)) {
683
- console.error(chalk8.red("File not found:"), path3);
370
+ const path = resolve5(process.cwd(), maybePath || ".dfl-ux-paths/flows.json");
371
+ if (!existsSync5(path)) {
372
+ console.error(chalk5.red("File not found:"), path);
684
373
  process.exit(1);
685
374
  }
686
- const raw = readFileSync4(path3, "utf8");
375
+ const raw = readFileSync4(path, "utf8");
687
376
  const doc = JSON.parse(raw);
688
377
  const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
689
378
  let sha = "0000000";
@@ -709,10 +398,10 @@ function registerStamp(program2) {
709
398
  };
710
399
  output = JSON.stringify(updated, null, 2) + "\n";
711
400
  }
712
- writeFileSync3(path3, output, "utf8");
713
- console.log(chalk8.green("Stamped"), path3, preserve ? chalk8.gray("(minimal diff)") : "");
714
- console.log(chalk8.gray(` app_version: ${newVersion}`));
715
- console.log(chalk8.gray(` generated_at: ${newGeneratedAt}`));
401
+ writeFileSync3(path, output, "utf8");
402
+ console.log(chalk5.green("Stamped"), path, preserve ? chalk5.gray("(minimal diff)") : "");
403
+ console.log(chalk5.gray(` app_version: ${newVersion}`));
404
+ console.log(chalk5.gray(` generated_at: ${newGeneratedAt}`));
716
405
  });
717
406
  }
718
407
 
@@ -729,7 +418,7 @@ function registerUxPaths(program2) {
729
418
  // src/cli/check-style-imports/index.ts
730
419
  import { resolve as resolve6 } from "path";
731
420
  import { existsSync as existsSync6 } from "fs";
732
- import chalk9 from "chalk";
421
+ import chalk6 from "chalk";
733
422
 
734
423
  // src/cli/check-style-imports/detect.ts
735
424
  import { readdirSync, readFileSync as readFileSync5 } from "fs";
@@ -821,7 +510,7 @@ function registerCheckStyleImports(program2) {
821
510
  ).option("--json", "Emit the raw detection result as JSON instead of a human report.").action((maybeDir, opts) => {
822
511
  const root = resolve6(process.cwd(), maybeDir || ".");
823
512
  if (!existsSync6(root)) {
824
- console.error(chalk9.red("Directory not found:"), root);
513
+ console.error(chalk6.red("Directory not found:"), root);
825
514
  process.exit(2);
826
515
  }
827
516
  const result = detectInDir(root);
@@ -832,33 +521,33 @@ function registerCheckStyleImports(program2) {
832
521
  if (!result.conflict) {
833
522
  if (result.hits.length === 0) {
834
523
  console.log(
835
- chalk9.green("OK"),
524
+ chalk6.green("OK"),
836
525
  "no @devfellowship/components/{styles,shadcn} imports found."
837
526
  );
838
527
  } else {
839
528
  const which = result.styles.length > 0 ? "styles" : "shadcn";
840
529
  console.log(
841
- chalk9.green("OK"),
530
+ chalk6.green("OK"),
842
531
  `app imports only @devfellowship/components/${which} (${result.hits.length} reference${result.hits.length === 1 ? "" : "s"}).`
843
532
  );
844
533
  }
845
534
  process.exit(0);
846
535
  }
847
536
  console.error(
848
- chalk9.red("CONFLICT"),
537
+ chalk6.red("CONFLICT"),
849
538
  "this app imports BOTH @devfellowship/components/styles AND /shadcn."
850
539
  );
851
540
  console.error(
852
- chalk9.yellow(
541
+ chalk6.yellow(
853
542
  "\nThese exports define the SAME CSS vars (--background, --primary, \u2026) in INCOMPATIBLE formats:\n - /styles ships them as HEX (#0A0908)\n - /shadcn ships them as HSL CHANNELS (30 11% 4%)\nImporting both clobbers --background \u2014 e.g. hsl(#0A0908) is invalid CSS \u2192 the\ndeclaration drops \u2192 surfaces render TRANSPARENT (the transparent-dialog bug).\n"
854
543
  )
855
544
  );
856
- console.error(chalk9.bold(" /styles imports:"));
545
+ console.error(chalk6.bold(" /styles imports:"));
857
546
  for (const h of result.styles) console.error(` ${h.file}:${h.line} ${h.text}`);
858
- console.error(chalk9.bold(" /shadcn imports:"));
547
+ console.error(chalk6.bold(" /shadcn imports:"));
859
548
  for (const h of result.shadcn) console.error(` ${h.file}:${h.line} ${h.text}`);
860
549
  console.error(
861
- chalk9.cyan(
550
+ chalk6.cyan(
862
551
  `
863
552
  FIX: keep exactly ONE. A DS-native (hex) app imports /styles only; a
864
553
  shadcn-slate (HSL-channel) app imports /shadcn only. NEVER both.
@@ -872,10 +561,8 @@ See: ${DOC_URL}`
872
561
  // src/cli/index.ts
873
562
  var program = new Command();
874
563
  program.name("dfl-components").description(
875
- "DevFellowship components CLI \u2014 add shared components AND map app UX paths (folds the dfl-ux-paths CLI). Shipped as the `dfl-components` bin of @devfellowship/components."
876
- ).version("1.0.0");
877
- program.command("init").description("Initialize your project with dfl-components configuration").option("-y, --yes", "Skip prompts and use defaults").option("-c, --cwd <path>", "Working directory", process.cwd()).action(init);
878
- program.command("add").description("Add a component to your project").argument("[components...]", "Components to add").option("-y, --yes", "Skip confirmation prompts").option("-o, --overwrite", "Overwrite existing files").option("-c, --cwd <path>", "Working directory", process.cwd()).option("-a, --all", "Add all available components").action(add);
564
+ 'DevFellowship components CLI \u2014 map app UX paths (folds the dfl-ux-paths CLI). Shipped as the `dfl-components` bin of @devfellowship/components. The component set is consumed as a library import (`import { Button } from "@devfellowship/components"`), not scaffolded.'
565
+ ).version("3.0.0");
879
566
  registerUxPaths(program);
880
567
  registerCheckStyleImports(program);
881
568
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devfellowship/components",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "DFL Design System — UI components, hooks, utils and providers",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -43,6 +43,7 @@
43
43
  ],
44
44
  "scripts": {
45
45
  "build": "tsup && tsup --config tsup.cli.config.ts",
46
+ "release": "npm run build && changeset publish",
46
47
  "build:lib": "tsup",
47
48
  "build:cli": "tsup --config tsup.cli.config.ts",
48
49
  "build:watch": "tsup --watch",
@@ -68,6 +69,8 @@
68
69
  }
69
70
  },
70
71
  "devDependencies": {
72
+ "@changesets/changelog-github": "^0.7.0",
73
+ "@changesets/cli": "^2.31.0",
71
74
  "@storybook/addon-a11y": "^9.1.20",
72
75
  "@storybook/addon-themes": "^9.1.20",
73
76
  "@storybook/react": "^9.1.20",
@@ -76,9 +79,7 @@
76
79
  "@tailwindcss/vite": "^4.2.2",
77
80
  "@testing-library/jest-dom": "^6.9.1",
78
81
  "@testing-library/react": "^16.3.2",
79
- "@types/fs-extra": "^11.0.4",
80
82
  "@types/node": "^20.0.0",
81
- "@types/prompts": "^2.4.9",
82
83
  "@types/react": "^18.3.28",
83
84
  "@types/react-dom": "^18.3.7",
84
85
  "@vitejs/plugin-react": "^4.7.0",
@@ -128,16 +129,11 @@
128
129
  "clsx": "^2.1.1",
129
130
  "cmdk": "^1.1.1",
130
131
  "commander": "^12.0.0",
131
- "cosmiconfig": "^9.0.0",
132
132
  "date-fns": "^3.6.0",
133
133
  "embla-carousel-react": "^8.6.0",
134
- "fs-extra": "^11.2.0",
135
134
  "input-otp": "^1.4.2",
136
135
  "lucide-react": "^0.462.0",
137
136
  "next-themes": "^0.4.6",
138
- "node-fetch": "^3.3.2",
139
- "ora": "^8.0.1",
140
- "prompts": "^2.4.2",
141
137
  "react-day-picker": "^8.10.1",
142
138
  "react-hook-form": "^7.72.1",
143
139
  "react-resizable-panels": "^2.1.9",