nx-factory-cli 2.1.10 → 2.1.18

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 (46) hide show
  1. package/dist/commands/add-app.d.ts +1 -1
  2. package/dist/commands/add-app.d.ts.map +1 -1
  3. package/dist/commands/add-app.js +130 -61
  4. package/dist/commands/add-app.js.map +1 -1
  5. package/dist/commands/add-auth.d.ts.map +1 -1
  6. package/dist/commands/add-auth.js +112 -48
  7. package/dist/commands/add-auth.js.map +1 -1
  8. package/dist/commands/add-component.d.ts.map +1 -1
  9. package/dist/commands/add-component.js +78 -22
  10. package/dist/commands/add-component.js.map +1 -1
  11. package/dist/commands/add-lib.d.ts.map +1 -1
  12. package/dist/commands/add-lib.js +38 -31
  13. package/dist/commands/add-lib.js.map +1 -1
  14. package/dist/commands/add-storybook.d.ts.map +1 -1
  15. package/dist/commands/add-storybook.js +29 -14
  16. package/dist/commands/add-storybook.js.map +1 -1
  17. package/dist/commands/doctor.d.ts.map +1 -1
  18. package/dist/commands/doctor.js +136 -43
  19. package/dist/commands/doctor.js.map +1 -1
  20. package/dist/commands/init.d.ts.map +1 -1
  21. package/dist/commands/init.js +267 -122
  22. package/dist/commands/init.js.map +1 -1
  23. package/dist/commands/list.d.ts.map +1 -1
  24. package/dist/commands/list.js +15 -8
  25. package/dist/commands/list.js.map +1 -1
  26. package/dist/commands/publish.d.ts.map +1 -1
  27. package/dist/commands/publish.js +36 -10
  28. package/dist/commands/publish.js.map +1 -1
  29. package/dist/commands/remove-component.d.ts.map +1 -1
  30. package/dist/commands/remove-component.js +24 -5
  31. package/dist/commands/remove-component.js.map +1 -1
  32. package/dist/commands/update.d.ts.map +1 -1
  33. package/dist/commands/update.js +18 -5
  34. package/dist/commands/update.js.map +1 -1
  35. package/dist/config.d.ts +6 -0
  36. package/dist/config.d.ts.map +1 -1
  37. package/dist/config.js +15 -0
  38. package/dist/config.js.map +1 -1
  39. package/dist/index.js +0 -0
  40. package/dist/setups/auth/base.d.ts +1 -2
  41. package/dist/setups/auth/base.d.ts.map +1 -1
  42. package/dist/setups/auth/base.js +7 -26
  43. package/dist/setups/auth/base.js.map +1 -1
  44. package/dist/setups/auth/types.d.ts +2 -1
  45. package/dist/setups/auth/types.d.ts.map +1 -1
  46. package/package.json +47 -43
@@ -2,7 +2,7 @@ import inquirer from "inquirer";
2
2
  import path from "path";
3
3
  import { run, runInDir, pmAdd, pmx, pmxArgs } from "../exec.js";
4
4
  import { writeJson, writeFile, ensureDir, pathExists } from "../files.js";
5
- import { saveConfig } from "../config.js";
5
+ import { saveConfig, normalizeScope, scopedPackageName } from "../config.js";
6
6
  import { scaffoldExampleApp } from "./add-app.js";
7
7
  import { c, q, detected, createStepRunner, printSection, printSuccess, printWarn, } from "../ui.js";
8
8
  const TOTAL_STEPS = 8;
@@ -27,7 +27,8 @@ export async function initCommand(options) {
27
27
  name: "workspaceName",
28
28
  message: q("Workspace name", "lowercase letters, numbers, dashes only"),
29
29
  default: defaults.workspaceName,
30
- validate: (v) => /^[a-z0-9-]+$/.test(v) || c.red("Only lowercase letters, numbers, and dashes allowed"),
30
+ validate: (v) => /^[a-z0-9-]+$/.test(v) ||
31
+ c.red("Only lowercase letters, numbers, and dashes allowed"),
31
32
  },
32
33
  {
33
34
  type: "list",
@@ -44,7 +45,8 @@ export async function initCommand(options) {
44
45
  name: "uiPackageName",
45
46
  message: q("Shared UI package name", "lives at packages/<name>"),
46
47
  default: defaults.uiPackageName,
47
- validate: (v) => /^[a-z0-9-]+$/.test(v) || c.red("Only lowercase letters, numbers, and dashes"),
48
+ validate: (v) => /^[a-z0-9-]+$/.test(v) ||
49
+ c.red("Only lowercase letters, numbers, and dashes"),
48
50
  },
49
51
  {
50
52
  type: "list",
@@ -63,7 +65,18 @@ export async function initCommand(options) {
63
65
  type: "checkbox",
64
66
  name: "initialComponents",
65
67
  message: q("Pre-install shadcn components", "space to toggle · enter to confirm"),
66
- choices: ["button", "card", "dialog", "input", "label", "select", "separator", "toast", "tooltip", "badge"],
68
+ choices: [
69
+ "button",
70
+ "card",
71
+ "dialog",
72
+ "input",
73
+ "label",
74
+ "select",
75
+ "separator",
76
+ "toast",
77
+ "tooltip",
78
+ "badge",
79
+ ],
67
80
  },
68
81
  {
69
82
  type: "confirm",
@@ -74,19 +87,26 @@ export async function initCommand(options) {
74
87
  ]);
75
88
  const pm = (answers.pkgManager ?? options.pkgManager ?? "pnpm");
76
89
  const workspaceName = answers.workspaceName;
90
+ const scope = normalizeScope(workspaceName);
77
91
  const uiPkgName = answers.uiPackageName;
78
92
  const baseColor = (answers.baseColor ?? "neutral");
79
93
  const initialComponents = answers.initialComponents;
80
94
  const addExampleApp = answers.addExampleApp;
81
95
  const cwd = path.join(process.cwd(), workspaceName);
82
- const totalSteps = TOTAL_STEPS + (initialComponents.length > 0 ? 1 : 0) + (addExampleApp ? 1 : 0);
96
+ const totalSteps = TOTAL_STEPS +
97
+ (initialComponents.length > 0 ? 1 : 0) +
98
+ (addExampleApp ? 1 : 0);
83
99
  const step = createStepRunner(totalSteps, options.dryRun);
84
100
  printSection(`${options.dryRun ? "[dry run] " : ""}Creating workspace at ./${workspaceName}`);
85
101
  // ─── Steps ────────────────────────────────────────────────────────────────
86
102
  await step("Create Nx workspace", () => run("npx", [
87
- "--yes", "create-nx-workspace@latest", workspaceName,
88
- "--preset=ts", `--packageManager=${pm}`,
89
- "--nxCloud=skip", "--no-interactive",
103
+ "--yes",
104
+ "create-nx-workspace@latest",
105
+ workspaceName,
106
+ "--preset=ts",
107
+ `--packageManager=${pm}`,
108
+ "--nxCloud=skip",
109
+ "--no-interactive",
90
110
  ]));
91
111
  await step("Write workspace config", async () => {
92
112
  if (pm === "pnpm") {
@@ -100,25 +120,27 @@ export async function initCommand(options) {
100
120
  rootPkg.workspaces = ["packages/*", "apps/*"];
101
121
  await fs.default.writeJson(rootPkgPath, rootPkg, { spaces: 2 });
102
122
  }
103
- catch { /* nx will write it */ }
123
+ catch {
124
+ /* nx will write it */
125
+ }
104
126
  }
105
127
  await ensureDir(path.join(cwd, "packages"));
106
128
  await ensureDir(path.join(cwd, "apps"));
107
129
  });
108
- await step(`Scaffold packages/${uiPkgName}`, () => scaffoldUiPackage(cwd, uiPkgName, pm));
130
+ await step(`Scaffold packages/${uiPkgName}`, () => scaffoldUiPackage(cwd, uiPkgName, pm, scope));
109
131
  await step("Install Tailwind v4", () => installUiDeps(cwd, uiPkgName, pm));
110
132
  await step("Write shadcn config", async () => {
111
- await writeShadcnConfig(cwd, uiPkgName, baseColor);
112
- await writeTailwindCss(cwd, uiPkgName, baseColor);
133
+ await writeShadcnConfig(cwd, uiPkgName, baseColor, scope);
134
+ await writeTailwindCss(cwd, uiPkgName, baseColor, scope);
113
135
  });
114
136
  if (initialComponents.length > 0) {
115
137
  await step(`Add shadcn components (${initialComponents.join(", ")})`, () => installShadcnComponents(cwd, uiPkgName, pm, initialComponents));
116
138
  }
117
- await step("Update nx.json", () => updateNxJson(cwd, uiPkgName));
139
+ await step("Update nx.json", () => updateNxJson(cwd));
118
140
  if (addExampleApp) {
119
- await step("Scaffold example Next.js app", () => scaffoldExampleApp(cwd, "example-app", uiPkgName, pm));
141
+ await step("Scaffold example Next.js app", () => scaffoldExampleApp(cwd, "example-app", uiPkgName, pm, scope));
120
142
  }
121
- await step("Update tsconfig.json", () => updateTsConfig(cwd, uiPkgName));
143
+ await step("Update tsconfig.json", () => updateTsConfig(cwd, scope));
122
144
  await step("Update package.json", () => updatePackageJson(cwd));
123
145
  await step("Install all dependencies", async () => {
124
146
  try {
@@ -132,6 +154,7 @@ export async function initCommand(options) {
132
154
  if (!options.dryRun) {
133
155
  await saveConfig({
134
156
  workspaceName,
157
+ scope,
135
158
  pkgManager: pm,
136
159
  uiPackage: uiPkgName,
137
160
  version: "1.0.0",
@@ -144,28 +167,47 @@ export async function initCommand(options) {
144
167
  commands: [
145
168
  { cmd: `cd ${workspaceName}` },
146
169
  ...(addExampleApp
147
- ? [{ cmd: `${pm} dev --filter=example-app`, comment: "start the example app" }]
170
+ ? [
171
+ {
172
+ cmd: `${pm} dev --filter=example-app`,
173
+ comment: "start the example app",
174
+ },
175
+ ]
148
176
  : []),
149
- { cmd: `${pm} nx build @workspace/${uiPkgName}`, comment: "build the UI package" },
177
+ {
178
+ cmd: `${pm} nx build ${scopedPackageName(scope, uiPkgName)}`,
179
+ comment: "build the UI package",
180
+ },
150
181
  ],
151
182
  tips: [
152
- { label: "Add more components:", cmd: `nx-shadcn add-component button card` },
153
- { label: "Add a new app:", cmd: `nx-shadcn add-app --name dashboard --framework vite` },
183
+ {
184
+ label: "Add more components:",
185
+ cmd: `nx-shadcn add-component button card`,
186
+ },
187
+ {
188
+ label: "Add a new app:",
189
+ cmd: `nx-shadcn add-app --name dashboard --framework vite`,
190
+ },
154
191
  ],
155
192
  });
156
193
  }
157
194
  // ─── Helpers ──────────────────────────────────────────────────────────────────
158
- async function scaffoldUiPackage(cwd, uiPkgName, pm) {
195
+ async function scaffoldUiPackage(cwd, uiPkgName, pm, scope) {
159
196
  const pkgDir = path.join(cwd, "packages", uiPkgName);
160
197
  await ensureDir(path.join(pkgDir, "components"));
161
198
  await ensureDir(path.join(pkgDir, "lib"));
162
199
  await ensureDir(path.join(pkgDir, "styles"));
163
200
  // package.json for the UI package
164
201
  await writeJson(path.join(pkgDir, "package.json"), {
165
- name: `@workspace/${uiPkgName}`,
202
+ name: scopedPackageName(scope, uiPkgName),
166
203
  version: "0.0.1",
167
204
  private: true,
168
205
  type: "module",
206
+ scripts: {
207
+ build: "tsc -p tsconfig.json",
208
+ "build:watch": "tsc -p tsconfig.json --watch",
209
+ typecheck: "tsc --noEmit",
210
+ },
169
211
  peerDependencies: {
170
212
  react: " ^19",
171
213
  "react-dom": " ^19",
@@ -197,14 +239,16 @@ async function scaffoldUiPackage(cwd, uiPkgName, pm) {
197
239
  sourceMap: true,
198
240
  esModuleInterop: true,
199
241
  skipLibCheck: true,
242
+ outDir: "dist",
243
+ rootDir: ".",
200
244
  baseUrl: ".",
201
245
  paths: {
202
- "@workspace/*": ["../../packages/*"],
203
- [`@workspace/${uiPkgName}/*`]: ["./*"],
246
+ [`@${scope}/*`]: ["../../packages/*"],
247
+ [`${scopedPackageName(scope, uiPkgName)}/*`]: ["./*"],
204
248
  },
205
249
  },
206
250
  include: ["**/*"],
207
- exclude: ["node_modules"],
251
+ exclude: ["node_modules", "dist"],
208
252
  });
209
253
  // lib/utils.ts (cn helper)
210
254
  await writeFile(path.join(pkgDir, "lib/utils.ts"), `import { clsx, type ClassValue } from "clsx";
@@ -217,8 +261,9 @@ export function cn(...inputs: ClassValue[]) {
217
261
  // index.ts — barrel export
218
262
  await writeFile(path.join(pkgDir, "index.tsx"), `// Auto-generated barrel — add new component exports here
219
263
  // Example: export { Button, type ButtonProps } from "./components/button";
220
- export { cn } from "@workspace/${uiPkgName}/lib/utils";
264
+ export { cn } from "${scopedPackageName(scope, uiPkgName)}/lib/utils";
221
265
  `);
266
+ void pm;
222
267
  }
223
268
  async function installUiDeps(cwd, uiPkgName, pm) {
224
269
  const pkgDir = path.join(cwd, "packages", uiPkgName);
@@ -226,7 +271,7 @@ async function installUiDeps(cwd, uiPkgName, pm) {
226
271
  await runInDir(pkgDir, pm, [addCmd, "tailwindcss@^4.0.0"], "Installing Tailwind v4");
227
272
  await runInDir(pkgDir, pm, [addCmd, "-D", "tw-animate-css"], "Installing tw-animate-css");
228
273
  }
229
- async function writeShadcnConfig(cwd, uiPkgName, baseColor = "neutral") {
274
+ async function writeShadcnConfig(cwd, uiPkgName, baseColor = "neutral", scope = "workspace") {
230
275
  const pkgDir = path.join(cwd, "packages", uiPkgName);
231
276
  await writeJson(path.join(pkgDir, "components.json"), {
232
277
  $schema: "https://ui.shadcn.com/schema.json",
@@ -240,11 +285,11 @@ async function writeShadcnConfig(cwd, uiPkgName, baseColor = "neutral") {
240
285
  cssVariables: true,
241
286
  },
242
287
  aliases: {
243
- components: `@workspace/${uiPkgName}/components`,
244
- utils: `@workspace/${uiPkgName}/lib/utils`,
245
- ui: `@workspace/${uiPkgName}/components/ui`,
246
- lib: `@workspace/${uiPkgName}/lib`,
247
- hooks: `@workspace/${uiPkgName}/hooks`,
288
+ components: `${scopedPackageName(scope, uiPkgName)}/components`,
289
+ utils: `${scopedPackageName(scope, uiPkgName)}/lib/utils`,
290
+ ui: `${scopedPackageName(scope, uiPkgName)}/components/ui`,
291
+ lib: `${scopedPackageName(scope, uiPkgName)}/lib`,
292
+ hooks: `${scopedPackageName(scope, uiPkgName)}/hooks`,
248
293
  },
249
294
  iconLibrary: "lucide",
250
295
  });
@@ -253,122 +298,217 @@ async function writeShadcnConfig(cwd, uiPkgName, baseColor = "neutral") {
253
298
  const THEME_PALETTES = {
254
299
  neutral: {
255
300
  light: {
256
- radius: "0.625rem", background: "oklch(1 0 0)", foreground: "oklch(0.145 0 0)",
257
- card: "oklch(1 0 0)", "card-foreground": "oklch(0.145 0 0)",
258
- popover: "oklch(1 0 0)", "popover-foreground": "oklch(0.145 0 0)",
259
- primary: "oklch(0.205 0 0)", "primary-foreground": "oklch(0.985 0 0)",
260
- secondary: "oklch(0.97 0 0)", "secondary-foreground": "oklch(0.205 0 0)",
261
- muted: "oklch(0.97 0 0)", "muted-foreground": "oklch(0.556 0 0)",
262
- accent: "oklch(0.97 0 0)", "accent-foreground": "oklch(0.205 0 0)",
301
+ radius: "0.625rem",
302
+ background: "oklch(1 0 0)",
303
+ foreground: "oklch(0.145 0 0)",
304
+ card: "oklch(1 0 0)",
305
+ "card-foreground": "oklch(0.145 0 0)",
306
+ popover: "oklch(1 0 0)",
307
+ "popover-foreground": "oklch(0.145 0 0)",
308
+ primary: "oklch(0.205 0 0)",
309
+ "primary-foreground": "oklch(0.985 0 0)",
310
+ secondary: "oklch(0.97 0 0)",
311
+ "secondary-foreground": "oklch(0.205 0 0)",
312
+ muted: "oklch(0.97 0 0)",
313
+ "muted-foreground": "oklch(0.556 0 0)",
314
+ accent: "oklch(0.97 0 0)",
315
+ "accent-foreground": "oklch(0.205 0 0)",
263
316
  destructive: "oklch(0.577 0.245 27.325)",
264
- border: "oklch(0.922 0 0)", input: "oklch(0.922 0 0)", ring: "oklch(0.708 0 0)",
317
+ border: "oklch(0.922 0 0)",
318
+ input: "oklch(0.922 0 0)",
319
+ ring: "oklch(0.708 0 0)",
265
320
  },
266
321
  dark: {
267
- background: "oklch(0.145 0 0)", foreground: "oklch(0.985 0 0)",
268
- card: "oklch(0.205 0 0)", "card-foreground": "oklch(0.985 0 0)",
269
- popover: "oklch(0.205 0 0)", "popover-foreground": "oklch(0.985 0 0)",
270
- primary: "oklch(0.985 0 0)", "primary-foreground": "oklch(0.205 0 0)",
271
- secondary: "oklch(0.269 0 0)", "secondary-foreground": "oklch(0.985 0 0)",
272
- muted: "oklch(0.269 0 0)", "muted-foreground": "oklch(0.708 0 0)",
273
- accent: "oklch(0.269 0 0)", "accent-foreground": "oklch(0.985 0 0)",
322
+ background: "oklch(0.145 0 0)",
323
+ foreground: "oklch(0.985 0 0)",
324
+ card: "oklch(0.205 0 0)",
325
+ "card-foreground": "oklch(0.985 0 0)",
326
+ popover: "oklch(0.205 0 0)",
327
+ "popover-foreground": "oklch(0.985 0 0)",
328
+ primary: "oklch(0.985 0 0)",
329
+ "primary-foreground": "oklch(0.205 0 0)",
330
+ secondary: "oklch(0.269 0 0)",
331
+ "secondary-foreground": "oklch(0.985 0 0)",
332
+ muted: "oklch(0.269 0 0)",
333
+ "muted-foreground": "oklch(0.708 0 0)",
334
+ accent: "oklch(0.269 0 0)",
335
+ "accent-foreground": "oklch(0.985 0 0)",
274
336
  destructive: "oklch(0.704 0.191 22.216)",
275
- border: "oklch(1 0 0 / 10%)", input: "oklch(1 0 0 / 15%)", ring: "oklch(0.556 0 0)",
337
+ border: "oklch(1 0 0 / 10%)",
338
+ input: "oklch(1 0 0 / 15%)",
339
+ ring: "oklch(0.556 0 0)",
276
340
  },
277
341
  },
278
342
  zinc: {
279
343
  light: {
280
- radius: "0.5rem", background: "oklch(1 0 0)", foreground: "oklch(0.141 0.005 285.823)",
281
- card: "oklch(1 0 0)", "card-foreground": "oklch(0.141 0.005 285.823)",
282
- popover: "oklch(1 0 0)", "popover-foreground": "oklch(0.141 0.005 285.823)",
283
- primary: "oklch(0.21 0.006 285.885)", "primary-foreground": "oklch(0.985 0 0)",
284
- secondary: "oklch(0.967 0.001 286.375)", "secondary-foreground": "oklch(0.21 0.006 285.885)",
285
- muted: "oklch(0.967 0.001 286.375)", "muted-foreground": "oklch(0.552 0.016 285.938)",
286
- accent: "oklch(0.967 0.001 286.375)", "accent-foreground": "oklch(0.21 0.006 285.885)",
344
+ radius: "0.5rem",
345
+ background: "oklch(1 0 0)",
346
+ foreground: "oklch(0.141 0.005 285.823)",
347
+ card: "oklch(1 0 0)",
348
+ "card-foreground": "oklch(0.141 0.005 285.823)",
349
+ popover: "oklch(1 0 0)",
350
+ "popover-foreground": "oklch(0.141 0.005 285.823)",
351
+ primary: "oklch(0.21 0.006 285.885)",
352
+ "primary-foreground": "oklch(0.985 0 0)",
353
+ secondary: "oklch(0.967 0.001 286.375)",
354
+ "secondary-foreground": "oklch(0.21 0.006 285.885)",
355
+ muted: "oklch(0.967 0.001 286.375)",
356
+ "muted-foreground": "oklch(0.552 0.016 285.938)",
357
+ accent: "oklch(0.967 0.001 286.375)",
358
+ "accent-foreground": "oklch(0.21 0.006 285.885)",
287
359
  destructive: "oklch(0.577 0.245 27.325)",
288
- border: "oklch(0.92 0.004 286.32)", input: "oklch(0.92 0.004 286.32)", ring: "oklch(0.705 0.015 286.067)",
360
+ border: "oklch(0.92 0.004 286.32)",
361
+ input: "oklch(0.92 0.004 286.32)",
362
+ ring: "oklch(0.705 0.015 286.067)",
289
363
  },
290
364
  dark: {
291
- background: "oklch(0.141 0.005 285.823)", foreground: "oklch(0.985 0 0)",
292
- card: "oklch(0.21 0.006 285.885)", "card-foreground": "oklch(0.985 0 0)",
293
- popover: "oklch(0.21 0.006 285.885)", "popover-foreground": "oklch(0.985 0 0)",
294
- primary: "oklch(0.985 0 0)", "primary-foreground": "oklch(0.21 0.006 285.885)",
295
- secondary: "oklch(0.274 0.006 286.033)", "secondary-foreground": "oklch(0.985 0 0)",
296
- muted: "oklch(0.274 0.006 286.033)", "muted-foreground": "oklch(0.705 0.015 286.067)",
297
- accent: "oklch(0.274 0.006 286.033)", "accent-foreground": "oklch(0.985 0 0)",
365
+ background: "oklch(0.141 0.005 285.823)",
366
+ foreground: "oklch(0.985 0 0)",
367
+ card: "oklch(0.21 0.006 285.885)",
368
+ "card-foreground": "oklch(0.985 0 0)",
369
+ popover: "oklch(0.21 0.006 285.885)",
370
+ "popover-foreground": "oklch(0.985 0 0)",
371
+ primary: "oklch(0.985 0 0)",
372
+ "primary-foreground": "oklch(0.21 0.006 285.885)",
373
+ secondary: "oklch(0.274 0.006 286.033)",
374
+ "secondary-foreground": "oklch(0.985 0 0)",
375
+ muted: "oklch(0.274 0.006 286.033)",
376
+ "muted-foreground": "oklch(0.705 0.015 286.067)",
377
+ accent: "oklch(0.274 0.006 286.033)",
378
+ "accent-foreground": "oklch(0.985 0 0)",
298
379
  destructive: "oklch(0.704 0.191 22.216)",
299
- border: "oklch(1 0 0 / 10%)", input: "oklch(1 0 0 / 15%)", ring: "oklch(0.552 0.016 285.938)",
380
+ border: "oklch(1 0 0 / 10%)",
381
+ input: "oklch(1 0 0 / 15%)",
382
+ ring: "oklch(0.552 0.016 285.938)",
300
383
  },
301
384
  },
302
385
  slate: {
303
386
  light: {
304
- radius: "0.5rem", background: "oklch(1 0 0)", foreground: "oklch(0.129 0.042 264.695)",
305
- card: "oklch(1 0 0)", "card-foreground": "oklch(0.129 0.042 264.695)",
306
- popover: "oklch(1 0 0)", "popover-foreground": "oklch(0.129 0.042 264.695)",
307
- primary: "oklch(0.208 0.042 265.755)", "primary-foreground": "oklch(0.984 0.003 247.858)",
308
- secondary: "oklch(0.968 0.007 247.896)", "secondary-foreground": "oklch(0.208 0.042 265.755)",
309
- muted: "oklch(0.968 0.007 247.896)", "muted-foreground": "oklch(0.554 0.046 257.417)",
310
- accent: "oklch(0.968 0.007 247.896)", "accent-foreground": "oklch(0.208 0.042 265.755)",
387
+ radius: "0.5rem",
388
+ background: "oklch(1 0 0)",
389
+ foreground: "oklch(0.129 0.042 264.695)",
390
+ card: "oklch(1 0 0)",
391
+ "card-foreground": "oklch(0.129 0.042 264.695)",
392
+ popover: "oklch(1 0 0)",
393
+ "popover-foreground": "oklch(0.129 0.042 264.695)",
394
+ primary: "oklch(0.208 0.042 265.755)",
395
+ "primary-foreground": "oklch(0.984 0.003 247.858)",
396
+ secondary: "oklch(0.968 0.007 247.896)",
397
+ "secondary-foreground": "oklch(0.208 0.042 265.755)",
398
+ muted: "oklch(0.968 0.007 247.896)",
399
+ "muted-foreground": "oklch(0.554 0.046 257.417)",
400
+ accent: "oklch(0.968 0.007 247.896)",
401
+ "accent-foreground": "oklch(0.208 0.042 265.755)",
311
402
  destructive: "oklch(0.577 0.245 27.325)",
312
- border: "oklch(0.929 0.013 255.508)", input: "oklch(0.929 0.013 255.508)", ring: "oklch(0.704 0.04 256.788)",
403
+ border: "oklch(0.929 0.013 255.508)",
404
+ input: "oklch(0.929 0.013 255.508)",
405
+ ring: "oklch(0.704 0.04 256.788)",
313
406
  },
314
407
  dark: {
315
- background: "oklch(0.129 0.042 264.695)", foreground: "oklch(0.984 0.003 247.858)",
316
- card: "oklch(0.208 0.042 265.755)", "card-foreground": "oklch(0.984 0.003 247.858)",
317
- popover: "oklch(0.208 0.042 265.755)", "popover-foreground": "oklch(0.984 0.003 247.858)",
318
- primary: "oklch(0.984 0.003 247.858)", "primary-foreground": "oklch(0.208 0.042 265.755)",
319
- secondary: "oklch(0.279 0.041 260.031)", "secondary-foreground": "oklch(0.984 0.003 247.858)",
320
- muted: "oklch(0.279 0.041 260.031)", "muted-foreground": "oklch(0.704 0.04 256.788)",
321
- accent: "oklch(0.279 0.041 260.031)", "accent-foreground": "oklch(0.984 0.003 247.858)",
408
+ background: "oklch(0.129 0.042 264.695)",
409
+ foreground: "oklch(0.984 0.003 247.858)",
410
+ card: "oklch(0.208 0.042 265.755)",
411
+ "card-foreground": "oklch(0.984 0.003 247.858)",
412
+ popover: "oklch(0.208 0.042 265.755)",
413
+ "popover-foreground": "oklch(0.984 0.003 247.858)",
414
+ primary: "oklch(0.984 0.003 247.858)",
415
+ "primary-foreground": "oklch(0.208 0.042 265.755)",
416
+ secondary: "oklch(0.279 0.041 260.031)",
417
+ "secondary-foreground": "oklch(0.984 0.003 247.858)",
418
+ muted: "oklch(0.279 0.041 260.031)",
419
+ "muted-foreground": "oklch(0.704 0.04 256.788)",
420
+ accent: "oklch(0.279 0.041 260.031)",
421
+ "accent-foreground": "oklch(0.984 0.003 247.858)",
322
422
  destructive: "oklch(0.704 0.191 22.216)",
323
- border: "oklch(1 0 0 / 10%)", input: "oklch(1 0 0 / 15%)", ring: "oklch(0.554 0.046 257.417)",
423
+ border: "oklch(1 0 0 / 10%)",
424
+ input: "oklch(1 0 0 / 15%)",
425
+ ring: "oklch(0.554 0.046 257.417)",
324
426
  },
325
427
  },
326
428
  stone: {
327
429
  light: {
328
- radius: "0.625rem", background: "oklch(1 0 0)", foreground: "oklch(0.147 0.004 49.25)",
329
- card: "oklch(1 0 0)", "card-foreground": "oklch(0.147 0.004 49.25)",
330
- popover: "oklch(1 0 0)", "popover-foreground": "oklch(0.147 0.004 49.25)",
331
- primary: "oklch(0.216 0.006 56.043)", "primary-foreground": "oklch(0.985 0.001 106.423)",
332
- secondary: "oklch(0.97 0.001 106.424)", "secondary-foreground": "oklch(0.216 0.006 56.043)",
333
- muted: "oklch(0.97 0.001 106.424)", "muted-foreground": "oklch(0.553 0.013 58.071)",
334
- accent: "oklch(0.97 0.001 106.424)", "accent-foreground": "oklch(0.216 0.006 56.043)",
430
+ radius: "0.625rem",
431
+ background: "oklch(1 0 0)",
432
+ foreground: "oklch(0.147 0.004 49.25)",
433
+ card: "oklch(1 0 0)",
434
+ "card-foreground": "oklch(0.147 0.004 49.25)",
435
+ popover: "oklch(1 0 0)",
436
+ "popover-foreground": "oklch(0.147 0.004 49.25)",
437
+ primary: "oklch(0.216 0.006 56.043)",
438
+ "primary-foreground": "oklch(0.985 0.001 106.423)",
439
+ secondary: "oklch(0.97 0.001 106.424)",
440
+ "secondary-foreground": "oklch(0.216 0.006 56.043)",
441
+ muted: "oklch(0.97 0.001 106.424)",
442
+ "muted-foreground": "oklch(0.553 0.013 58.071)",
443
+ accent: "oklch(0.97 0.001 106.424)",
444
+ "accent-foreground": "oklch(0.216 0.006 56.043)",
335
445
  destructive: "oklch(0.577 0.245 27.325)",
336
- border: "oklch(0.923 0.003 48.717)", input: "oklch(0.923 0.003 48.717)", ring: "oklch(0.709 0.01 56.259)",
446
+ border: "oklch(0.923 0.003 48.717)",
447
+ input: "oklch(0.923 0.003 48.717)",
448
+ ring: "oklch(0.709 0.01 56.259)",
337
449
  },
338
450
  dark: {
339
- background: "oklch(0.147 0.004 49.25)", foreground: "oklch(0.985 0.001 106.423)",
340
- card: "oklch(0.216 0.006 56.043)", "card-foreground": "oklch(0.985 0.001 106.423)",
341
- popover: "oklch(0.216 0.006 56.043)", "popover-foreground": "oklch(0.985 0.001 106.423)",
342
- primary: "oklch(0.985 0.001 106.423)", "primary-foreground": "oklch(0.216 0.006 56.043)",
343
- secondary: "oklch(0.268 0.007 34.298)", "secondary-foreground": "oklch(0.985 0.001 106.423)",
344
- muted: "oklch(0.268 0.007 34.298)", "muted-foreground": "oklch(0.709 0.01 56.259)",
345
- accent: "oklch(0.268 0.007 34.298)", "accent-foreground": "oklch(0.985 0.001 106.423)",
451
+ background: "oklch(0.147 0.004 49.25)",
452
+ foreground: "oklch(0.985 0.001 106.423)",
453
+ card: "oklch(0.216 0.006 56.043)",
454
+ "card-foreground": "oklch(0.985 0.001 106.423)",
455
+ popover: "oklch(0.216 0.006 56.043)",
456
+ "popover-foreground": "oklch(0.985 0.001 106.423)",
457
+ primary: "oklch(0.985 0.001 106.423)",
458
+ "primary-foreground": "oklch(0.216 0.006 56.043)",
459
+ secondary: "oklch(0.268 0.007 34.298)",
460
+ "secondary-foreground": "oklch(0.985 0.001 106.423)",
461
+ muted: "oklch(0.268 0.007 34.298)",
462
+ "muted-foreground": "oklch(0.709 0.01 56.259)",
463
+ accent: "oklch(0.268 0.007 34.298)",
464
+ "accent-foreground": "oklch(0.985 0.001 106.423)",
346
465
  destructive: "oklch(0.704 0.191 22.216)",
347
- border: "oklch(1 0 0 / 10%)", input: "oklch(1 0 0 / 15%)", ring: "oklch(0.553 0.013 58.071)",
466
+ border: "oklch(1 0 0 / 10%)",
467
+ input: "oklch(1 0 0 / 15%)",
468
+ ring: "oklch(0.553 0.013 58.071)",
348
469
  },
349
470
  },
350
471
  gray: {
351
472
  light: {
352
- radius: "0.625rem", background: "oklch(1 0 0)", foreground: "oklch(0.13 0 0)",
353
- card: "oklch(1 0 0)", "card-foreground": "oklch(0.13 0 0)",
354
- popover: "oklch(1 0 0)", "popover-foreground": "oklch(0.13 0 0)",
355
- primary: "oklch(0.205 0 0)", "primary-foreground": "oklch(0.985 0 0)",
356
- secondary: "oklch(0.97 0 0)", "secondary-foreground": "oklch(0.205 0 0)",
357
- muted: "oklch(0.97 0 0)", "muted-foreground": "oklch(0.556 0 0)",
358
- accent: "oklch(0.97 0 0)", "accent-foreground": "oklch(0.205 0 0)",
473
+ radius: "0.625rem",
474
+ background: "oklch(1 0 0)",
475
+ foreground: "oklch(0.13 0 0)",
476
+ card: "oklch(1 0 0)",
477
+ "card-foreground": "oklch(0.13 0 0)",
478
+ popover: "oklch(1 0 0)",
479
+ "popover-foreground": "oklch(0.13 0 0)",
480
+ primary: "oklch(0.205 0 0)",
481
+ "primary-foreground": "oklch(0.985 0 0)",
482
+ secondary: "oklch(0.97 0 0)",
483
+ "secondary-foreground": "oklch(0.205 0 0)",
484
+ muted: "oklch(0.97 0 0)",
485
+ "muted-foreground": "oklch(0.556 0 0)",
486
+ accent: "oklch(0.97 0 0)",
487
+ "accent-foreground": "oklch(0.205 0 0)",
359
488
  destructive: "oklch(0.577 0.245 27.325)",
360
- border: "oklch(0.922 0 0)", input: "oklch(0.922 0 0)", ring: "oklch(0.708 0 0)",
489
+ border: "oklch(0.922 0 0)",
490
+ input: "oklch(0.922 0 0)",
491
+ ring: "oklch(0.708 0 0)",
361
492
  },
362
493
  dark: {
363
- background: "oklch(0.13 0 0)", foreground: "oklch(0.985 0 0)",
364
- card: "oklch(0.205 0 0)", "card-foreground": "oklch(0.985 0 0)",
365
- popover: "oklch(0.205 0 0)", "popover-foreground": "oklch(0.985 0 0)",
366
- primary: "oklch(0.985 0 0)", "primary-foreground": "oklch(0.205 0 0)",
367
- secondary: "oklch(0.269 0 0)", "secondary-foreground": "oklch(0.985 0 0)",
368
- muted: "oklch(0.269 0 0)", "muted-foreground": "oklch(0.708 0 0)",
369
- accent: "oklch(0.269 0 0)", "accent-foreground": "oklch(0.985 0 0)",
494
+ background: "oklch(0.13 0 0)",
495
+ foreground: "oklch(0.985 0 0)",
496
+ card: "oklch(0.205 0 0)",
497
+ "card-foreground": "oklch(0.985 0 0)",
498
+ popover: "oklch(0.205 0 0)",
499
+ "popover-foreground": "oklch(0.985 0 0)",
500
+ primary: "oklch(0.985 0 0)",
501
+ "primary-foreground": "oklch(0.205 0 0)",
502
+ secondary: "oklch(0.269 0 0)",
503
+ "secondary-foreground": "oklch(0.985 0 0)",
504
+ muted: "oklch(0.269 0 0)",
505
+ "muted-foreground": "oklch(0.708 0 0)",
506
+ accent: "oklch(0.269 0 0)",
507
+ "accent-foreground": "oklch(0.985 0 0)",
370
508
  destructive: "oklch(0.704 0.191 22.216)",
371
- border: "oklch(1 0 0 / 10%)", input: "oklch(1 0 0 / 15%)", ring: "oklch(0.556 0 0)",
509
+ border: "oklch(1 0 0 / 10%)",
510
+ input: "oklch(1 0 0 / 15%)",
511
+ ring: "oklch(0.556 0 0)",
372
512
  },
373
513
  },
374
514
  };
@@ -377,7 +517,7 @@ function buildCssVars(vars, indent = " ") {
377
517
  .map(([k, v]) => `${indent}--${k}: ${v};`)
378
518
  .join("\n");
379
519
  }
380
- async function writeTailwindCss(cwd, uiPkgName, baseColor = "neutral") {
520
+ async function writeTailwindCss(cwd, uiPkgName, baseColor = "neutral", scope = "workspace") {
381
521
  const pkgDir = path.join(cwd, "packages", uiPkgName);
382
522
  const palette = THEME_PALETTES[baseColor] ?? THEME_PALETTES.neutral;
383
523
  const { radius, ...lightVars } = palette.light;
@@ -389,7 +529,7 @@ async function writeTailwindCss(cwd, uiPkgName, baseColor = "neutral") {
389
529
  *
390
530
  * @source covers:
391
531
  * - This UI package's own components
392
- * - Any app in apps/ that imports from @workspace/${uiPkgName}
532
+ * - Any app in apps/ that imports from ${scopedPackageName(scope, uiPkgName)}
393
533
  *
394
534
  * Apps can extend this by adding their own @source lines in their
395
535
  * local globals.css after importing this file.
@@ -437,13 +577,13 @@ async function installShadcnComponents(cwd, uiPkgName, pm, components) {
437
577
  const pkgDir = path.join(cwd, "packages", uiPkgName);
438
578
  try {
439
579
  await runInDir(pkgDir, pmx(pm), pmxArgs(pm, "shadcn@latest", ["add", "--yes", ...components]));
440
- await updateBarrelExports(pkgDir, uiPkgName, components);
580
+ await updateBarrelExports(pkgDir, components);
441
581
  }
442
582
  catch {
443
583
  printWarn("Failed to add shadcn components", "Add them manually later with: nx-shadcn add-component");
444
584
  }
445
585
  }
446
- async function updateBarrelExports(pkgDir, uiPkgName, components) {
586
+ async function updateBarrelExports(pkgDir, components) {
447
587
  const indexPath = path.join(pkgDir, "index.tsx");
448
588
  const { default: fs } = await import("fs-extra");
449
589
  let existing = "";
@@ -454,8 +594,8 @@ async function updateBarrelExports(pkgDir, uiPkgName, components) {
454
594
  // file doesn't exist yet — start fresh
455
595
  }
456
596
  const newExports = components
457
- .filter((c) => !existing.includes(`@workspace/${uiPkgName}/components/ui/${c}`))
458
- .map((c) => `export * from "@workspace/${uiPkgName}/components/ui/${c}";`)
597
+ .filter((c) => !existing.includes(`/components/ui/${c}`))
598
+ .map((c) => `export * from "./components/ui/${c}";`)
459
599
  .join("\n");
460
600
  if (newExports) {
461
601
  if (existing && !existing.endsWith("\n"))
@@ -463,7 +603,7 @@ async function updateBarrelExports(pkgDir, uiPkgName, components) {
463
603
  await writeFile(indexPath, existing + newExports + "\n");
464
604
  }
465
605
  }
466
- async function updateNxJson(cwd, uiPkgName) {
606
+ async function updateNxJson(cwd) {
467
607
  const nxJsonPath = path.join(cwd, "nx.json");
468
608
  try {
469
609
  const fs = await import("fs-extra");
@@ -503,7 +643,7 @@ async function updatePackageJson(cwd) {
503
643
  await fs.writeJson(pkgJsonPath, pkgJson, { spaces: 2 });
504
644
  }
505
645
  // Update scaffolded app tsConfig to extend the typescript config of the root workspace
506
- async function updateTsConfig(cwd, uiPkgName) {
646
+ async function updateTsConfig(cwd, scope) {
507
647
  const tsConfigPath = path.join(cwd, "apps/example-app/tsconfig.json");
508
648
  const { default: fs } = await import("fs-extra");
509
649
  if (!(await pathExists(tsConfigPath)))
@@ -516,11 +656,16 @@ async function updateTsConfig(cwd, uiPkgName) {
516
656
  paths: {
517
657
  ...currentPaths,
518
658
  "@/*": ["./*"],
519
- "@workspace/*": ["../../packages/*"],
659
+ [`@${scope}/*`]: ["../../packages/*"],
520
660
  },
521
661
  };
522
- const includeEntries = Array.isArray(tsConfig.include) ? tsConfig.include : [];
523
- const requiredIncludes = ["../../packages/**/*.ts", "../../packages/**/*.tsx"];
662
+ const includeEntries = Array.isArray(tsConfig.include)
663
+ ? tsConfig.include
664
+ : [];
665
+ const requiredIncludes = [
666
+ "../../packages/**/*.ts",
667
+ "../../packages/**/*.tsx",
668
+ ];
524
669
  tsConfig.include = Array.from(new Set([...includeEntries, ...requiredIncludes]));
525
670
  await fs.writeJson(tsConfigPath, tsConfig, { spaces: 2 });
526
671
  }