@getcoherent/cli 0.2.0 → 0.2.2

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/index.js +186 -119
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -601,7 +601,7 @@ function installPackages(projectRoot, packages) {
601
601
  if (packages.length === 0) return Promise.resolve(true);
602
602
  const safe = packages.filter((p) => SAFE_PKG_NAME.test(p));
603
603
  if (safe.length === 0) return Promise.resolve(true);
604
- return new Promise((resolve16) => {
604
+ return new Promise((resolve17) => {
605
605
  try {
606
606
  const hasPnpm = existsSync4(join2(projectRoot, "pnpm-lock.yaml"));
607
607
  if (hasPnpm) {
@@ -612,10 +612,10 @@ function installPackages(projectRoot, packages) {
612
612
  stdio: "pipe"
613
613
  });
614
614
  }
615
- resolve16(true);
615
+ resolve17(true);
616
616
  } catch (e) {
617
617
  if (process.env.COHERENT_DEBUG === "1") console.error("Failed to install packages:", e);
618
- resolve16(false);
618
+ resolve17(false);
619
619
  }
620
620
  });
621
621
  }
@@ -2425,7 +2425,7 @@ export default config
2425
2425
  // src/commands/chat.ts
2426
2426
  import chalk13 from "chalk";
2427
2427
  import ora2 from "ora";
2428
- import { resolve as resolve9 } from "path";
2428
+ import { resolve as resolve10 } from "path";
2429
2429
  import { existsSync as existsSync16, readFileSync as readFileSync11, mkdirSync as mkdirSync6 } from "fs";
2430
2430
  import {
2431
2431
  DesignSystemManager as DesignSystemManager7,
@@ -6519,6 +6519,53 @@ ${fixed}`;
6519
6519
  }
6520
6520
  }
6521
6521
  }
6522
+ const lucideImportMatch2 = fixed.match(/import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/);
6523
+ if (lucideImportMatch2) {
6524
+ let lucideExports2 = null;
6525
+ try {
6526
+ const { createRequire } = await import("module");
6527
+ const req = createRequire(process.cwd() + "/package.json");
6528
+ const lr = req("lucide-react");
6529
+ lucideExports2 = new Set(Object.keys(lr).filter((k) => /^[A-Z]/.test(k)));
6530
+ } catch {
6531
+ }
6532
+ if (lucideExports2) {
6533
+ const importedNames = new Set(
6534
+ lucideImportMatch2[1].split(",").map((s) => s.trim()).filter(Boolean)
6535
+ );
6536
+ const jsxIconRefs = [...fixed.matchAll(/<([A-Z][a-zA-Z]*(?:Icon)?)\s/g)].map((m) => m[1]);
6537
+ const htmlElements = /* @__PURE__ */ new Set(["Link", "Fragment", "Suspense", "Image"]);
6538
+ const missing = [];
6539
+ for (const ref of jsxIconRefs) {
6540
+ if (importedNames.has(ref) || htmlElements.has(ref)) continue;
6541
+ if (fixed.includes(`function ${ref}`) || fixed.includes(`const ${ref}`)) continue;
6542
+ if (/^import\s.*\b${ref}\b/m.test(fixed)) continue;
6543
+ const baseName = ref.replace(/Icon$/, "");
6544
+ if (lucideExports2.has(ref)) {
6545
+ missing.push(ref);
6546
+ importedNames.add(ref);
6547
+ } else if (lucideExports2.has(baseName)) {
6548
+ const re = new RegExp(`\\b${ref}\\b`, "g");
6549
+ fixed = fixed.replace(re, baseName);
6550
+ missing.push(baseName);
6551
+ importedNames.add(baseName);
6552
+ fixes.push(`renamed ${ref} \u2192 ${baseName} (lucide-react)`);
6553
+ } else {
6554
+ const fallback = "Circle";
6555
+ const re = new RegExp(`\\b${ref}\\b`, "g");
6556
+ fixed = fixed.replace(re, fallback);
6557
+ importedNames.add(fallback);
6558
+ fixes.push(`unknown icon ${ref} \u2192 ${fallback}`);
6559
+ }
6560
+ }
6561
+ if (missing.length > 0) {
6562
+ const allNames = [...importedNames];
6563
+ const origLine = lucideImportMatch2[0];
6564
+ fixed = fixed.replace(origLine, `import { ${allNames.join(", ")} } from "lucide-react"`);
6565
+ fixes.push(`added missing lucide imports: ${missing.join(", ")}`);
6566
+ }
6567
+ }
6568
+ }
6522
6569
  fixed = fixed.replace(/className="([^"]*)"/g, (_match, inner) => {
6523
6570
  const cleaned = inner.replace(/\s{2,}/g, " ").trim();
6524
6571
  return `className="${cleaned}"`;
@@ -7542,7 +7589,8 @@ ${pagesCtx}`
7542
7589
  }
7543
7590
 
7544
7591
  // src/commands/chat/layout-extractor.ts
7545
- import { readFileSync as readFileSync9 } from "fs";
7592
+ import { readFileSync as readFileSync9, readdirSync as readdirSync2 } from "fs";
7593
+ import { join as join9, resolve as resolve8 } from "path";
7546
7594
  import chalk11 from "chalk";
7547
7595
  import { loadManifest as loadManifest6, generateSharedComponent as generateSharedComponent3, integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout3 } from "@getcoherent/core";
7548
7596
 
@@ -7645,6 +7693,21 @@ function addActiveNavToHeader(code) {
7645
7693
  }
7646
7694
 
7647
7695
  // src/commands/chat/layout-extractor.ts
7696
+ function findAllPageFiles(dir) {
7697
+ const results = [];
7698
+ try {
7699
+ for (const entry of readdirSync2(dir, { withFileTypes: true })) {
7700
+ const full = join9(dir, entry.name);
7701
+ if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".next" && entry.name !== "design-system") {
7702
+ results.push(...findAllPageFiles(full));
7703
+ } else if (entry.name === "page.tsx" || entry.name === "page.jsx") {
7704
+ results.push(full);
7705
+ }
7706
+ }
7707
+ } catch {
7708
+ }
7709
+ return results;
7710
+ }
7648
7711
  async function extractAndShareLayoutComponents(projectRoot, generatedPageFiles) {
7649
7712
  const manifest = await loadManifest6(projectRoot);
7650
7713
  const hasSharedHeader = manifest.shared.some((c) => c.type === "layout" && /header|nav/i.test(c.name));
@@ -7727,7 +7790,11 @@ ${stateBlock}${returnIndent}return (
7727
7790
  if (!extracted) return false;
7728
7791
  await integrateSharedLayoutIntoRootLayout3(projectRoot);
7729
7792
  await ensureAuthRouteGroup(projectRoot);
7730
- for (const file of generatedPageFiles) {
7793
+ const allPageFiles = /* @__PURE__ */ new Set([
7794
+ ...generatedPageFiles,
7795
+ ...findAllPageFiles(resolve8(projectRoot, "app"))
7796
+ ]);
7797
+ for (const file of allPageFiles) {
7731
7798
  try {
7732
7799
  let code = await readFile(file);
7733
7800
  const original = code;
@@ -7752,7 +7819,7 @@ ${stateBlock}${returnIndent}return (
7752
7819
 
7753
7820
  // src/commands/chat/interactive.ts
7754
7821
  import chalk12 from "chalk";
7755
- import { resolve as resolve8 } from "path";
7822
+ import { resolve as resolve9 } from "path";
7756
7823
  import { existsSync as existsSync15, readFileSync as readFileSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
7757
7824
  import { DesignSystemManager as DesignSystemManager6, ComponentManager as ComponentManager3, loadManifest as loadManifest7 } from "@getcoherent/core";
7758
7825
  var DEBUG3 = process.env.COHERENT_DEBUG === "1";
@@ -7773,8 +7840,8 @@ async function interactiveChat(options, chatCommandFn) {
7773
7840
  \u274C Invalid provider: ${options.provider}`));
7774
7841
  process.exit(1);
7775
7842
  }
7776
- const historyDir = resolve8(homedir2(), ".coherent");
7777
- const historyFile = resolve8(historyDir, "history");
7843
+ const historyDir = resolve9(homedir2(), ".coherent");
7844
+ const historyFile = resolve9(historyDir, "history");
7778
7845
  let history = [];
7779
7846
  try {
7780
7847
  mkdirSync5(historyDir, { recursive: true });
@@ -8003,7 +8070,7 @@ async function chatCommand(message, options) {
8003
8070
  }
8004
8071
  if (/switch to light mode|default to light|make.*light.*(default|theme)|light theme/i.test(message)) {
8005
8072
  spinner.start("Setting default theme to light...");
8006
- const layoutPath = resolve9(projectRoot, "app/layout.tsx");
8073
+ const layoutPath = resolve10(projectRoot, "app/layout.tsx");
8007
8074
  try {
8008
8075
  let layout = await readFile(layoutPath);
8009
8076
  layout = layout.replace(/className="dark"/, "");
@@ -8042,7 +8109,7 @@ async function chatCommand(message, options) {
8042
8109
  spinner.start("Parsing your request...");
8043
8110
  let manifest = await loadManifest8(project.root);
8044
8111
  const validShared = manifest.shared.filter((s) => {
8045
- const fp = resolve9(project.root, s.file);
8112
+ const fp = resolve10(project.root, s.file);
8046
8113
  return existsSync16(fp);
8047
8114
  });
8048
8115
  if (validShared.length !== manifest.shared.length) {
@@ -8443,7 +8510,7 @@ async function chatCommand(message, options) {
8443
8510
  const isAuth = isAuthRoute(linkedRoute);
8444
8511
  const filePath = routeToFsPath(projectRoot, linkedRoute, isAuth);
8445
8512
  if (isAuth) await ensureAuthRouteGroup(projectRoot);
8446
- const dir = resolve9(filePath, "..");
8513
+ const dir = resolve10(filePath, "..");
8447
8514
  if (!existsSync16(dir)) {
8448
8515
  mkdirSync6(dir, { recursive: true });
8449
8516
  }
@@ -8479,7 +8546,7 @@ async function chatCommand(message, options) {
8479
8546
  dsm.updateConfig(latestConfig);
8480
8547
  if (DEBUG4) console.log(chalk13.dim(` [theme] Set defaultMode to "${targetMode}"`));
8481
8548
  }
8482
- const layoutPath = resolve9(projectRoot, "app", "layout.tsx");
8549
+ const layoutPath = resolve10(projectRoot, "app", "layout.tsx");
8483
8550
  try {
8484
8551
  let layoutCode = await readFile(layoutPath);
8485
8552
  if (targetMode === "dark" && !layoutCode.includes('className="dark"')) {
@@ -8534,7 +8601,7 @@ async function chatCommand(message, options) {
8534
8601
  console.log("");
8535
8602
  }
8536
8603
  if (uxRecommendations) {
8537
- const recPath = resolve9(projectRoot, "recommendations.md");
8604
+ const recPath = resolve10(projectRoot, "recommendations.md");
8538
8605
  const section = `
8539
8606
 
8540
8607
  ---
@@ -8619,18 +8686,18 @@ import chalk14 from "chalk";
8619
8686
  import ora3 from "ora";
8620
8687
  import { spawn } from "child_process";
8621
8688
  import { existsSync as existsSync19, rmSync as rmSync3, readFileSync as readFileSync14, writeFileSync as writeFileSync10 } from "fs";
8622
- import { resolve as resolve10, join as join11 } from "path";
8689
+ import { resolve as resolve11, join as join12 } from "path";
8623
8690
  import { readdir as readdir2 } from "fs/promises";
8624
8691
  import { DesignSystemManager as DesignSystemManager8, ComponentGenerator as ComponentGenerator3 } from "@getcoherent/core";
8625
8692
 
8626
8693
  // src/utils/file-watcher.ts
8627
8694
  import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, existsSync as existsSync18 } from "fs";
8628
- import { relative as relative3, join as join10 } from "path";
8695
+ import { relative as relative3, join as join11 } from "path";
8629
8696
  import { loadManifest as loadManifest9, saveManifest as saveManifest3 } from "@getcoherent/core";
8630
8697
 
8631
8698
  // src/utils/component-integrity.ts
8632
- import { existsSync as existsSync17, readFileSync as readFileSync12, readdirSync as readdirSync2 } from "fs";
8633
- import { join as join9, relative as relative2 } from "path";
8699
+ import { existsSync as existsSync17, readFileSync as readFileSync12, readdirSync as readdirSync3 } from "fs";
8700
+ import { join as join10, relative as relative2 } from "path";
8634
8701
  function extractExportedComponentNames(code) {
8635
8702
  const names = [];
8636
8703
  let m;
@@ -8656,7 +8723,7 @@ function arraysEqual(a, b) {
8656
8723
  }
8657
8724
  function findPagesImporting(projectRoot, componentName, componentFile) {
8658
8725
  const results = [];
8659
- const appDir = join9(projectRoot, "app");
8726
+ const appDir = join10(projectRoot, "app");
8660
8727
  if (!existsSync17(appDir)) return results;
8661
8728
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
8662
8729
  const componentImportPath = componentFile.replace(/\.tsx$/, "").replace(/\.jsx$/, "");
@@ -8676,7 +8743,7 @@ function findPagesImporting(projectRoot, componentName, componentFile) {
8676
8743
  return results;
8677
8744
  }
8678
8745
  function isUsedInLayout(projectRoot, componentName) {
8679
- const layoutPath = join9(projectRoot, "app", "layout.tsx");
8746
+ const layoutPath = join10(projectRoot, "app", "layout.tsx");
8680
8747
  if (!existsSync17(layoutPath)) return false;
8681
8748
  try {
8682
8749
  const code = readFileSync12(layoutPath, "utf-8");
@@ -8687,7 +8754,7 @@ function isUsedInLayout(projectRoot, componentName) {
8687
8754
  }
8688
8755
  function findUnregisteredComponents(projectRoot, manifest) {
8689
8756
  const results = [];
8690
- const componentsDir = join9(projectRoot, "components");
8757
+ const componentsDir = join10(projectRoot, "components");
8691
8758
  if (!existsSync17(componentsDir)) return results;
8692
8759
  const registeredFiles = new Set(manifest.shared.map((s) => s.file));
8693
8760
  const registeredNames = new Set(manifest.shared.map((s) => s.name));
@@ -8715,7 +8782,7 @@ function findUnregisteredComponents(projectRoot, manifest) {
8715
8782
  }
8716
8783
  function findInlineDuplicates(projectRoot, manifest) {
8717
8784
  const results = [];
8718
- const appDir = join9(projectRoot, "app");
8785
+ const appDir = join10(projectRoot, "app");
8719
8786
  if (!existsSync17(appDir)) return results;
8720
8787
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
8721
8788
  for (const absPath of pageFiles) {
@@ -8745,7 +8812,7 @@ function findInlineDuplicates(projectRoot, manifest) {
8745
8812
  return results;
8746
8813
  }
8747
8814
  function findComponentFileByExportName(projectRoot, componentName) {
8748
- const componentsDir = join9(projectRoot, "components");
8815
+ const componentsDir = join10(projectRoot, "components");
8749
8816
  if (!existsSync17(componentsDir)) return null;
8750
8817
  const files = collectFiles(
8751
8818
  componentsDir,
@@ -8767,7 +8834,7 @@ function findComponentFileByExportName(projectRoot, componentName) {
8767
8834
  function removeOrphanedEntries(projectRoot, manifest) {
8768
8835
  const removed = [];
8769
8836
  const valid = manifest.shared.filter((entry) => {
8770
- const filePath = join9(projectRoot, entry.file);
8837
+ const filePath = join10(projectRoot, entry.file);
8771
8838
  if (existsSync17(filePath)) return true;
8772
8839
  removed.push({ id: entry.id, name: entry.name });
8773
8840
  return false;
@@ -8786,7 +8853,7 @@ function reconcileComponents(projectRoot, manifest) {
8786
8853
  };
8787
8854
  const m = { ...manifest, shared: [...manifest.shared], nextId: manifest.nextId };
8788
8855
  m.shared = m.shared.filter((entry) => {
8789
- const filePath = join9(projectRoot, entry.file);
8856
+ const filePath = join10(projectRoot, entry.file);
8790
8857
  if (!existsSync17(filePath)) {
8791
8858
  const newPath = findComponentFileByExportName(projectRoot, entry.name);
8792
8859
  if (newPath) {
@@ -8799,7 +8866,7 @@ function reconcileComponents(projectRoot, manifest) {
8799
8866
  }
8800
8867
  let code;
8801
8868
  try {
8802
- code = readFileSync12(join9(projectRoot, entry.file), "utf-8");
8869
+ code = readFileSync12(join10(projectRoot, entry.file), "utf-8");
8803
8870
  } catch {
8804
8871
  return true;
8805
8872
  }
@@ -8876,12 +8943,12 @@ function collectFiles(dir, filter, skipDirs = []) {
8876
8943
  function walk(d) {
8877
8944
  let entries;
8878
8945
  try {
8879
- entries = readdirSync2(d, { withFileTypes: true });
8946
+ entries = readdirSync3(d, { withFileTypes: true });
8880
8947
  } catch {
8881
8948
  return;
8882
8949
  }
8883
8950
  for (const e of entries) {
8884
- const full = join9(d, e.name);
8951
+ const full = join10(d, e.name);
8885
8952
  if (e.isDirectory()) {
8886
8953
  if (skipDirs.includes(e.name) || e.name.startsWith(".")) continue;
8887
8954
  walk(full);
@@ -8920,7 +8987,7 @@ function findInlineDuplicatesOfShared(content, manifest) {
8920
8987
  }
8921
8988
  function getWatcherConfig(projectRoot) {
8922
8989
  try {
8923
- const pkgPath = join10(projectRoot, "package.json");
8990
+ const pkgPath = join11(projectRoot, "package.json");
8924
8991
  if (!existsSync18(pkgPath)) return defaultWatcherConfig();
8925
8992
  const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
8926
8993
  const c = pkg?.coherent?.watcher ?? {};
@@ -9049,8 +9116,8 @@ function startFileWatcher(projectRoot) {
9049
9116
  let watcher = null;
9050
9117
  let manifestWatcher = null;
9051
9118
  import("chokidar").then((chokidar) => {
9052
- const appGlob = join10(projectRoot, "app", "**", "*.tsx");
9053
- const compGlob = join10(projectRoot, "components", "**", "*.tsx");
9119
+ const appGlob = join11(projectRoot, "app", "**", "*.tsx");
9120
+ const compGlob = join11(projectRoot, "components", "**", "*.tsx");
9054
9121
  watcher = chokidar.default.watch([appGlob, compGlob], {
9055
9122
  ignoreInitial: true,
9056
9123
  awaitWriteFinish: { stabilityThreshold: 500 }
@@ -9062,7 +9129,7 @@ function startFileWatcher(projectRoot) {
9062
9129
  });
9063
9130
  watcher.on("unlink", (fp) => handleFileDelete(projectRoot, fp));
9064
9131
  });
9065
- const manifestPath = join10(projectRoot, "coherent.components.json");
9132
+ const manifestPath = join11(projectRoot, "coherent.components.json");
9066
9133
  if (existsSync18(manifestPath)) {
9067
9134
  import("chokidar").then((chokidar) => {
9068
9135
  manifestWatcher = chokidar.default.watch(manifestPath, { ignoreInitial: true });
@@ -9077,7 +9144,7 @@ function startFileWatcher(projectRoot) {
9077
9144
 
9078
9145
  // src/commands/preview.ts
9079
9146
  function getPackageManager(projectRoot) {
9080
- const hasPnpm = existsSync19(resolve10(projectRoot, "pnpm-lock.yaml"));
9147
+ const hasPnpm = existsSync19(resolve11(projectRoot, "pnpm-lock.yaml"));
9081
9148
  return hasPnpm ? "pnpm" : "npm";
9082
9149
  }
9083
9150
  function runInstall(projectRoot) {
@@ -9099,8 +9166,8 @@ function runInstall(projectRoot) {
9099
9166
  });
9100
9167
  }
9101
9168
  function checkProjectInitialized(projectRoot) {
9102
- const configPath = resolve10(projectRoot, "design-system.config.ts");
9103
- const packageJsonPath = resolve10(projectRoot, "package.json");
9169
+ const configPath = resolve11(projectRoot, "design-system.config.ts");
9170
+ const packageJsonPath = resolve11(projectRoot, "package.json");
9104
9171
  if (!existsSync19(configPath)) {
9105
9172
  return false;
9106
9173
  }
@@ -9110,11 +9177,11 @@ function checkProjectInitialized(projectRoot) {
9110
9177
  return true;
9111
9178
  }
9112
9179
  function checkDependenciesInstalled(projectRoot) {
9113
- const nodeModulesPath = resolve10(projectRoot, "node_modules");
9180
+ const nodeModulesPath = resolve11(projectRoot, "node_modules");
9114
9181
  return existsSync19(nodeModulesPath);
9115
9182
  }
9116
9183
  function clearStaleCache(projectRoot) {
9117
- const nextDir = join11(projectRoot, ".next");
9184
+ const nextDir = join12(projectRoot, ".next");
9118
9185
  if (existsSync19(nextDir)) {
9119
9186
  rmSync3(nextDir, { recursive: true, force: true });
9120
9187
  console.log(chalk14.dim(" \u2714 Cleared stale build cache"));
@@ -9135,7 +9202,7 @@ async function listPageFiles(appDir) {
9135
9202
  async function walk(dir) {
9136
9203
  const entries = await readdir2(dir, { withFileTypes: true });
9137
9204
  for (const e of entries) {
9138
- const full = join11(dir, e.name);
9205
+ const full = join12(dir, e.name);
9139
9206
  if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "api" && e.name !== "design-system") await walk(full);
9140
9207
  else if (e.isFile() && e.name === "page.tsx") out.push(full);
9141
9208
  }
@@ -9144,7 +9211,7 @@ async function listPageFiles(appDir) {
9144
9211
  return out;
9145
9212
  }
9146
9213
  async function validateSyntax(projectRoot) {
9147
- const appDir = join11(projectRoot, "app");
9214
+ const appDir = join12(projectRoot, "app");
9148
9215
  const pages = await listPageFiles(appDir);
9149
9216
  for (const file of pages) {
9150
9217
  const content = readFileSync14(file, "utf-8");
@@ -9156,8 +9223,8 @@ async function validateSyntax(projectRoot) {
9156
9223
  }
9157
9224
  }
9158
9225
  async function fixMissingComponentExports(projectRoot) {
9159
- const appDir = join11(projectRoot, "app");
9160
- const uiDir = join11(projectRoot, "components", "ui");
9226
+ const appDir = join12(projectRoot, "app");
9227
+ const uiDir = join12(projectRoot, "components", "ui");
9161
9228
  if (!existsSync19(appDir) || !existsSync19(uiDir)) return;
9162
9229
  const pages = await listPageFiles(appDir);
9163
9230
  const neededExports = /* @__PURE__ */ new Map();
@@ -9172,7 +9239,7 @@ async function fixMissingComponentExports(projectRoot) {
9172
9239
  for (const name of names) neededExports.get(componentId).add(name);
9173
9240
  }
9174
9241
  }
9175
- const configPath = join11(projectRoot, "design-system.config.ts");
9242
+ const configPath = join12(projectRoot, "design-system.config.ts");
9176
9243
  let config2 = null;
9177
9244
  try {
9178
9245
  const mgr = new DesignSystemManager8(configPath);
@@ -9181,7 +9248,7 @@ async function fixMissingComponentExports(projectRoot) {
9181
9248
  }
9182
9249
  const generator = new ComponentGenerator3(config2 || { components: [], pages: [], tokens: {} });
9183
9250
  for (const [componentId, needed] of neededExports) {
9184
- const componentFile = join11(uiDir, `${componentId}.tsx`);
9251
+ const componentFile = join12(uiDir, `${componentId}.tsx`);
9185
9252
  const def = getShadcnComponent(componentId);
9186
9253
  if (!existsSync19(componentFile)) {
9187
9254
  if (!def) continue;
@@ -9218,7 +9285,7 @@ async function fixMissingComponentExports(projectRoot) {
9218
9285
  }
9219
9286
  }
9220
9287
  async function backfillPageAnalysis(projectRoot) {
9221
- const configPath = join11(projectRoot, "design-system.config.ts");
9288
+ const configPath = join12(projectRoot, "design-system.config.ts");
9222
9289
  if (!existsSync19(configPath)) return;
9223
9290
  try {
9224
9291
  const mgr = new DesignSystemManager8(configPath);
@@ -9230,11 +9297,11 @@ async function backfillPageAnalysis(projectRoot) {
9230
9297
  const isAuth = route.includes("login") || route.includes("register") || route.includes("signup") || route.includes("sign-up");
9231
9298
  let filePath;
9232
9299
  if (route === "/") {
9233
- filePath = join11(projectRoot, "app", "page.tsx");
9300
+ filePath = join12(projectRoot, "app", "page.tsx");
9234
9301
  } else if (isAuth) {
9235
- filePath = join11(projectRoot, "app", "(auth)", route.slice(1), "page.tsx");
9302
+ filePath = join12(projectRoot, "app", "(auth)", route.slice(1), "page.tsx");
9236
9303
  } else {
9237
- filePath = join11(projectRoot, "app", route.slice(1), "page.tsx");
9304
+ filePath = join12(projectRoot, "app", route.slice(1), "page.tsx");
9238
9305
  }
9239
9306
  if (!existsSync19(filePath)) continue;
9240
9307
  const code = readFileSync14(filePath, "utf-8");
@@ -9264,7 +9331,7 @@ async function autoInstallShadcnComponent(componentId, projectRoot) {
9264
9331
  const def = getShadcnComponent(componentId);
9265
9332
  if (!def) return false;
9266
9333
  try {
9267
- const configPath = join11(projectRoot, "design-system.config.ts");
9334
+ const configPath = join12(projectRoot, "design-system.config.ts");
9268
9335
  let config2 = null;
9269
9336
  try {
9270
9337
  const mgr = new DesignSystemManager8(configPath);
@@ -9273,10 +9340,10 @@ async function autoInstallShadcnComponent(componentId, projectRoot) {
9273
9340
  }
9274
9341
  const generator = new ComponentGenerator3(config2 || { components: [], pages: [], tokens: {} });
9275
9342
  const code = await generator.generate(def);
9276
- const uiDir = join11(projectRoot, "components", "ui");
9343
+ const uiDir = join12(projectRoot, "components", "ui");
9277
9344
  const { mkdirSync: mkdirSync9 } = await import("fs");
9278
9345
  mkdirSync9(uiDir, { recursive: true });
9279
- writeFileSync10(join11(uiDir, `${componentId}.tsx`), code, "utf-8");
9346
+ writeFileSync10(join12(uiDir, `${componentId}.tsx`), code, "utf-8");
9280
9347
  return true;
9281
9348
  } catch {
9282
9349
  return false;
@@ -9399,12 +9466,12 @@ async function openBrowser(url) {
9399
9466
  }
9400
9467
  }
9401
9468
  function startDevServer(projectRoot) {
9402
- const packageJsonPath = resolve10(projectRoot, "package.json");
9469
+ const packageJsonPath = resolve11(projectRoot, "package.json");
9403
9470
  if (!existsSync19(packageJsonPath)) {
9404
9471
  throw new Error('package.json not found. Run "coherent init" first.');
9405
9472
  }
9406
- const hasPnpm = existsSync19(resolve10(projectRoot, "pnpm-lock.yaml"));
9407
- const hasNpm = existsSync19(resolve10(projectRoot, "package-lock.json"));
9473
+ const hasPnpm = existsSync19(resolve11(projectRoot, "pnpm-lock.yaml"));
9474
+ const hasNpm = existsSync19(resolve11(projectRoot, "package-lock.json"));
9408
9475
  const command = hasPnpm ? "pnpm" : hasNpm ? "npm" : "npx";
9409
9476
  const args = hasPnpm ? ["dev", "--turbo"] : hasNpm ? ["run", "dev", "--", "--turbo"] : ["next", "dev", "--turbo"];
9410
9477
  const child = spawn(command, args, {
@@ -9451,7 +9518,7 @@ async function previewCommand() {
9451
9518
  if (needsGlobalsFix(projectRoot)) {
9452
9519
  spinner.text = "Fixing globals.css...";
9453
9520
  try {
9454
- const dsm = new DesignSystemManager8(resolve10(projectRoot, "design-system.config.ts"));
9521
+ const dsm = new DesignSystemManager8(resolve11(projectRoot, "design-system.config.ts"));
9455
9522
  await dsm.load();
9456
9523
  const config2 = dsm.getConfig();
9457
9524
  fixGlobalsCss(projectRoot, config2);
@@ -9490,8 +9557,8 @@ async function previewCommand() {
9490
9557
  import chalk15 from "chalk";
9491
9558
  import ora4 from "ora";
9492
9559
  import { spawn as spawn2 } from "child_process";
9493
- import { existsSync as existsSync20, rmSync as rmSync4, readdirSync as readdirSync3 } from "fs";
9494
- import { resolve as resolve11, join as join12, dirname as dirname7 } from "path";
9560
+ import { existsSync as existsSync20, rmSync as rmSync4, readdirSync as readdirSync4 } from "fs";
9561
+ import { resolve as resolve12, join as join13, dirname as dirname7 } from "path";
9495
9562
  import { readdir as readdir3, readFile as readFile5, writeFile as writeFile4, mkdir as mkdir4, copyFile as copyFile2 } from "fs/promises";
9496
9563
  var COPY_EXCLUDE = /* @__PURE__ */ new Set([
9497
9564
  "node_modules",
@@ -9513,8 +9580,8 @@ async function copyDir(src, dest) {
9513
9580
  await mkdir4(dest, { recursive: true });
9514
9581
  const entries = await readdir3(src, { withFileTypes: true });
9515
9582
  for (const e of entries) {
9516
- const srcPath = join12(src, e.name);
9517
- const destPath = join12(dest, e.name);
9583
+ const srcPath = join13(src, e.name);
9584
+ const destPath = join13(dest, e.name);
9518
9585
  if (COPY_EXCLUDE.has(e.name)) continue;
9519
9586
  if (e.isDirectory()) {
9520
9587
  await copyDir(srcPath, destPath);
@@ -9525,16 +9592,16 @@ async function copyDir(src, dest) {
9525
9592
  }
9526
9593
  }
9527
9594
  function checkProjectInitialized2(projectRoot) {
9528
- return existsSync20(resolve11(projectRoot, "design-system.config.ts")) && existsSync20(resolve11(projectRoot, "package.json"));
9595
+ return existsSync20(resolve12(projectRoot, "design-system.config.ts")) && existsSync20(resolve12(projectRoot, "package.json"));
9529
9596
  }
9530
9597
  function getPackageManager2(projectRoot) {
9531
- if (existsSync20(resolve11(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
9532
- if (existsSync20(resolve11(projectRoot, "package-lock.json"))) return "npm";
9598
+ if (existsSync20(resolve12(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
9599
+ if (existsSync20(resolve12(projectRoot, "package-lock.json"))) return "npm";
9533
9600
  return "npx";
9534
9601
  }
9535
9602
  async function patchNextConfigForExport(outRoot) {
9536
9603
  for (const name of ["next.config.ts", "next.config.mjs", "next.config.js"]) {
9537
- const p = join12(outRoot, name);
9604
+ const p = join13(outRoot, name);
9538
9605
  if (!existsSync20(p)) continue;
9539
9606
  let content = await readFile5(p, "utf-8");
9540
9607
  if (content.includes("ignoreDuringBuilds")) return;
@@ -9550,9 +9617,9 @@ async function buildProduction(projectRoot) {
9550
9617
  const pm = getPackageManager2(projectRoot);
9551
9618
  const command = pm === "pnpm" ? "pnpm" : pm === "npm" ? "npm" : "npx";
9552
9619
  const args = pm === "npx" ? ["next", "build"] : ["run", "build"];
9553
- return new Promise((resolve16, reject) => {
9620
+ return new Promise((resolve17, reject) => {
9554
9621
  const child = spawn2(command, args, { cwd: projectRoot, stdio: "inherit", shell: true });
9555
- child.on("exit", (code) => code === 0 ? resolve16() : reject(new Error(`Build failed with exit code ${code}`)));
9622
+ child.on("exit", (code) => code === 0 ? resolve17() : reject(new Error(`Build failed with exit code ${code}`)));
9556
9623
  child.on("error", (error) => reject(new Error(`Failed to start build: ${error.message}`)));
9557
9624
  });
9558
9625
  }
@@ -9576,7 +9643,7 @@ EXPOSE 3000
9576
9643
  \`\`\`
9577
9644
  `;
9578
9645
  async function ensureReadmeDeploySection(outRoot) {
9579
- const readmePath = join12(outRoot, "README.md");
9646
+ const readmePath = join13(outRoot, "README.md");
9580
9647
  if (!existsSync20(readmePath)) return;
9581
9648
  try {
9582
9649
  let content = await readFile5(readmePath, "utf-8");
@@ -9596,22 +9663,22 @@ async function countPages(outRoot) {
9596
9663
  return;
9597
9664
  }
9598
9665
  for (const e of entries) {
9599
- const full = join12(dir, e.name);
9666
+ const full = join13(dir, e.name);
9600
9667
  if (e.isFile() && e.name === "page.tsx") n++;
9601
9668
  else if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "api") await walk(full);
9602
9669
  }
9603
9670
  }
9604
- const appDir = join12(outRoot, "app");
9671
+ const appDir = join13(outRoot, "app");
9605
9672
  if (existsSync20(appDir)) await walk(appDir);
9606
9673
  return n;
9607
9674
  }
9608
9675
  function countComponents(outRoot) {
9609
9676
  let n = 0;
9610
9677
  for (const sub of ["ui", "shared"]) {
9611
- const dir = join12(outRoot, "components", sub);
9678
+ const dir = join13(outRoot, "components", sub);
9612
9679
  if (!existsSync20(dir)) continue;
9613
9680
  try {
9614
- n += readdirSync3(dir).filter((f) => f.endsWith(".tsx") || f.endsWith(".jsx")).length;
9681
+ n += readdirSync4(dir).filter((f) => f.endsWith(".tsx") || f.endsWith(".jsx")).length;
9615
9682
  } catch {
9616
9683
  }
9617
9684
  }
@@ -9624,7 +9691,7 @@ async function collectImportedPackages2(dir, extensions) {
9624
9691
  async function walk(d) {
9625
9692
  const entries = await readdir3(d, { withFileTypes: true });
9626
9693
  for (const e of entries) {
9627
- const full = join12(d, e.name);
9694
+ const full = join13(d, e.name);
9628
9695
  if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules") {
9629
9696
  await walk(full);
9630
9697
  continue;
@@ -9647,7 +9714,7 @@ async function collectImportedPackages2(dir, extensions) {
9647
9714
  return packages;
9648
9715
  }
9649
9716
  async function findMissingDepsInExport(outRoot) {
9650
- const pkgPath = join12(outRoot, "package.json");
9717
+ const pkgPath = join13(outRoot, "package.json");
9651
9718
  if (!existsSync20(pkgPath)) return [];
9652
9719
  let pkg;
9653
9720
  try {
@@ -9656,7 +9723,7 @@ async function findMissingDepsInExport(outRoot) {
9656
9723
  return [];
9657
9724
  }
9658
9725
  const inDeps = /* @__PURE__ */ new Set([...Object.keys(pkg.dependencies ?? {}), ...Object.keys(pkg.devDependencies ?? {})]);
9659
- const codeDirs = [join12(outRoot, "app"), join12(outRoot, "components")];
9726
+ const codeDirs = [join13(outRoot, "app"), join13(outRoot, "components")];
9660
9727
  const extensions = /* @__PURE__ */ new Set(["ts", "tsx", "js", "jsx"]);
9661
9728
  const imported = /* @__PURE__ */ new Set();
9662
9729
  for (const dir of codeDirs) {
@@ -9668,25 +9735,25 @@ async function findMissingDepsInExport(outRoot) {
9668
9735
  async function stripCoherentArtifacts(outputDir) {
9669
9736
  const removed = [];
9670
9737
  for (const p of ["app/design-system", "app/api/design-system"]) {
9671
- const full = join12(outputDir, p);
9738
+ const full = join13(outputDir, p);
9672
9739
  if (existsSync20(full)) {
9673
9740
  rmSync4(full, { recursive: true, force: true });
9674
9741
  removed.push(p);
9675
9742
  }
9676
9743
  }
9677
- const appNavPath = join12(outputDir, "app", "AppNav.tsx");
9744
+ const appNavPath = join13(outputDir, "app", "AppNav.tsx");
9678
9745
  if (existsSync20(appNavPath)) {
9679
9746
  rmSync4(appNavPath, { force: true });
9680
9747
  removed.push("app/AppNav.tsx");
9681
9748
  }
9682
- const layoutPath = join12(outputDir, "app", "layout.tsx");
9749
+ const layoutPath = join13(outputDir, "app", "layout.tsx");
9683
9750
  if (existsSync20(layoutPath)) {
9684
9751
  let layout = await readFile5(layoutPath, "utf-8");
9685
9752
  layout = layout.replace(/import\s*\{?\s*AppNav\s*\}?\s*from\s*['"][^'"]+['"]\s*\n?/g, "");
9686
9753
  layout = layout.replace(/\s*<AppNav\s*\/?\s*>\s*/g, "\n");
9687
9754
  await writeFile4(layoutPath, layout, "utf-8");
9688
9755
  }
9689
- const guardPath = join12(outputDir, "app", "ShowWhenNotAuthRoute.tsx");
9756
+ const guardPath = join13(outputDir, "app", "ShowWhenNotAuthRoute.tsx");
9690
9757
  if (existsSync20(guardPath)) {
9691
9758
  let guard = await readFile5(guardPath, "utf-8");
9692
9759
  guard = guard.replace(/['"],?\s*'\/design-system['"],?\s*/g, "");
@@ -9715,14 +9782,14 @@ async function stripCoherentArtifacts(outputDir) {
9715
9782
  ".env.local",
9716
9783
  "recommendations.md"
9717
9784
  ]) {
9718
- const full = join12(outputDir, name);
9785
+ const full = join13(outputDir, name);
9719
9786
  if (existsSync20(full)) {
9720
9787
  rmSync4(full, { force: true });
9721
9788
  removed.push(name);
9722
9789
  }
9723
9790
  }
9724
9791
  for (const dir of [".claude", ".coherent"]) {
9725
- const full = join12(outputDir, dir);
9792
+ const full = join13(outputDir, dir);
9726
9793
  if (existsSync20(full)) {
9727
9794
  rmSync4(full, { recursive: true, force: true });
9728
9795
  removed.push(dir + "/");
@@ -9731,7 +9798,7 @@ async function stripCoherentArtifacts(outputDir) {
9731
9798
  return removed;
9732
9799
  }
9733
9800
  async function exportCommand(options = {}) {
9734
- const outputDir = resolve11(process.cwd(), options.output ?? "./export");
9801
+ const outputDir = resolve12(process.cwd(), options.output ?? "./export");
9735
9802
  const doBuild = options.build !== false;
9736
9803
  const keepDs = options.keepDs === true;
9737
9804
  const spinner = ora4("Preparing export...").start();
@@ -9922,8 +9989,8 @@ async function regenerateDocsCommand() {
9922
9989
 
9923
9990
  // src/commands/fix.ts
9924
9991
  import chalk18 from "chalk";
9925
- import { readdirSync as readdirSync4, readFileSync as readFileSync15, existsSync as existsSync21, writeFileSync as writeFileSync11, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
9926
- import { resolve as resolve12, join as join13 } from "path";
9992
+ import { readdirSync as readdirSync5, readFileSync as readFileSync15, existsSync as existsSync21, writeFileSync as writeFileSync11, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
9993
+ import { resolve as resolve13, join as join14 } from "path";
9927
9994
  import {
9928
9995
  DesignSystemManager as DesignSystemManager11,
9929
9996
  ComponentManager as ComponentManager5,
@@ -9947,9 +10014,9 @@ function extractComponentIdsFromCode2(code) {
9947
10014
  function listTsxFiles(dir) {
9948
10015
  const files = [];
9949
10016
  try {
9950
- const entries = readdirSync4(dir, { withFileTypes: true });
10017
+ const entries = readdirSync5(dir, { withFileTypes: true });
9951
10018
  for (const e of entries) {
9952
- const full = join13(dir, e.name);
10019
+ const full = join14(dir, e.name);
9953
10020
  if (e.isDirectory() && e.name !== "node_modules" && !e.name.startsWith(".")) {
9954
10021
  files.push(...listTsxFiles(full));
9955
10022
  } else if (e.isFile() && e.name.endsWith(".tsx")) {
@@ -9978,7 +10045,7 @@ async function fixCommand(opts = {}) {
9978
10045
  console.log(chalk18.cyan("\ncoherent fix\n"));
9979
10046
  }
9980
10047
  if (!skipCache) {
9981
- const nextDir = join13(projectRoot, ".next");
10048
+ const nextDir = join14(projectRoot, ".next");
9982
10049
  if (existsSync21(nextDir)) {
9983
10050
  if (!dryRun) rmSync5(nextDir, { recursive: true, force: true });
9984
10051
  fixes.push("Cleared build cache");
@@ -10001,9 +10068,9 @@ async function fixCommand(opts = {}) {
10001
10068
  }
10002
10069
  }
10003
10070
  }
10004
- const appDir = resolve12(projectRoot, "app");
10071
+ const appDir = resolve13(projectRoot, "app");
10005
10072
  const allTsxFiles = listTsxFiles(appDir);
10006
- const componentsTsxFiles = listTsxFiles(resolve12(projectRoot, "components"));
10073
+ const componentsTsxFiles = listTsxFiles(resolve13(projectRoot, "components"));
10007
10074
  const allComponentIds = /* @__PURE__ */ new Set();
10008
10075
  for (const file of [...allTsxFiles, ...componentsTsxFiles]) {
10009
10076
  const content = readFileSync15(file, "utf-8");
@@ -10025,7 +10092,7 @@ async function fixCommand(opts = {}) {
10025
10092
  missingComponents.push(id);
10026
10093
  } else {
10027
10094
  const fileName = toKebabCase(id) + ".tsx";
10028
- const filePath = resolve12(projectRoot, "components", "ui", fileName);
10095
+ const filePath = resolve13(projectRoot, "components", "ui", fileName);
10029
10096
  if (!existsSync21(filePath)) missingFiles.push(id);
10030
10097
  }
10031
10098
  }
@@ -10053,8 +10120,8 @@ async function fixCommand(opts = {}) {
10053
10120
  const generator = new ComponentGenerator4(updatedConfig);
10054
10121
  const code = await generator.generate(component);
10055
10122
  const fileName = toKebabCase(component.name) + ".tsx";
10056
- const filePath = resolve12(projectRoot, "components", "ui", fileName);
10057
- mkdirSync7(resolve12(projectRoot, "components", "ui"), { recursive: true });
10123
+ const filePath = resolve13(projectRoot, "components", "ui", fileName);
10124
+ mkdirSync7(resolve13(projectRoot, "components", "ui"), { recursive: true });
10058
10125
  await writeFile(filePath, code);
10059
10126
  installed++;
10060
10127
  }
@@ -10234,16 +10301,16 @@ async function fixCommand(opts = {}) {
10234
10301
 
10235
10302
  // src/commands/check.ts
10236
10303
  import chalk19 from "chalk";
10237
- import { resolve as resolve13 } from "path";
10238
- import { readdirSync as readdirSync5, readFileSync as readFileSync16, statSync as statSync2, existsSync as existsSync22 } from "fs";
10304
+ import { resolve as resolve14 } from "path";
10305
+ import { readdirSync as readdirSync6, readFileSync as readFileSync16, statSync as statSync2, existsSync as existsSync22 } from "fs";
10239
10306
  import { loadManifest as loadManifest11 } from "@getcoherent/core";
10240
10307
  var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", "design-system"]);
10241
10308
  function findTsxFiles(dir) {
10242
10309
  const results = [];
10243
10310
  try {
10244
- const entries = readdirSync5(dir);
10311
+ const entries = readdirSync6(dir);
10245
10312
  for (const entry of entries) {
10246
- const full = resolve13(dir, entry);
10313
+ const full = resolve14(dir, entry);
10247
10314
  const stat = statSync2(full);
10248
10315
  if (stat.isDirectory() && !entry.startsWith(".") && !EXCLUDED_DIRS.has(entry)) {
10249
10316
  results.push(...findTsxFiles(full));
@@ -10278,7 +10345,7 @@ async function checkCommand(opts = {}) {
10278
10345
  } catch {
10279
10346
  }
10280
10347
  if (!skipPages) {
10281
- const appDir = resolve13(projectRoot, "app");
10348
+ const appDir = resolve14(projectRoot, "app");
10282
10349
  const files = findTsxFiles(appDir);
10283
10350
  result.pages.total = files.length;
10284
10351
  if (!opts.json) console.log(chalk19.cyan("\n \u{1F4C4} Pages") + chalk19.dim(` (${files.length} scanned)
@@ -10366,7 +10433,7 @@ async function checkCommand(opts = {}) {
10366
10433
  const manifest = await loadManifest11(project.root);
10367
10434
  if (manifest.shared.length > 0) {
10368
10435
  for (const entry of manifest.shared) {
10369
- const fullPath = resolve13(project.root, entry.file);
10436
+ const fullPath = resolve14(project.root, entry.file);
10370
10437
  if (!existsSync22(fullPath)) {
10371
10438
  result.pages.withErrors++;
10372
10439
  if (!opts.json) console.log(chalk19.red(`
@@ -10391,7 +10458,7 @@ async function checkCommand(opts = {}) {
10391
10458
  let _staleUsedIn = 0;
10392
10459
  let _nameMismatch = 0;
10393
10460
  for (const entry of manifest.shared) {
10394
- const filePath = resolve13(projectRoot, entry.file);
10461
+ const filePath = resolve14(projectRoot, entry.file);
10395
10462
  const fileExists = existsSync22(filePath);
10396
10463
  if (!fileExists) {
10397
10464
  _orphaned++;
@@ -10470,7 +10537,7 @@ async function checkCommand(opts = {}) {
10470
10537
  id: e.id,
10471
10538
  name: e.name,
10472
10539
  type: e.type,
10473
- status: existsSync22(resolve13(projectRoot, e.file)) ? "ok" : "unused",
10540
+ status: existsSync22(resolve14(projectRoot, e.file)) ? "ok" : "unused",
10474
10541
  message: "",
10475
10542
  suggestions: void 0
10476
10543
  }))
@@ -10566,11 +10633,11 @@ import {
10566
10633
  integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout4
10567
10634
  } from "@getcoherent/core";
10568
10635
  import { existsSync as existsSync23 } from "fs";
10569
- import { resolve as resolve14 } from "path";
10636
+ import { resolve as resolve15 } from "path";
10570
10637
 
10571
10638
  // src/utils/ds-files.ts
10572
10639
  import { mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
10573
- import { join as join14, dirname as dirname8 } from "path";
10640
+ import { join as join15, dirname as dirname8 } from "path";
10574
10641
  import { DesignSystemGenerator } from "@getcoherent/core";
10575
10642
  var SHARED_DS_KEYS = [
10576
10643
  "app/design-system/shared/page.tsx",
@@ -10584,7 +10651,7 @@ async function writeDesignSystemFiles(projectRoot, config2, options) {
10584
10651
  const toWrite = options?.sharedOnly ? new Map([...files].filter(([path3]) => SHARED_DS_KEYS.includes(path3))) : files;
10585
10652
  const written = [];
10586
10653
  for (const [relativePath, content] of toWrite) {
10587
- const fullPath = join14(projectRoot, relativePath);
10654
+ const fullPath = join15(projectRoot, relativePath);
10588
10655
  await mkdir5(dirname8(fullPath), { recursive: true });
10589
10656
  await writeFile5(fullPath, content, "utf-8");
10590
10657
  written.push(relativePath);
@@ -10696,7 +10763,7 @@ function createComponentsCommand() {
10696
10763
  const updated = await integrateSharedLayoutIntoRootLayout4(project.root);
10697
10764
  if (updated) console.log(chalk25.cyan(" Updated app/layout.tsx to use shared layout components.\n"));
10698
10765
  }
10699
- const sharedPagePath = resolve14(project.root, "app/design-system/shared/page.tsx");
10766
+ const sharedPagePath = resolve15(project.root, "app/design-system/shared/page.tsx");
10700
10767
  if (!existsSync23(sharedPagePath)) {
10701
10768
  try {
10702
10769
  const dsm = new DesignSystemManager12(project.configPath);
@@ -10723,7 +10790,7 @@ function createComponentsCommand() {
10723
10790
  import chalk26 from "chalk";
10724
10791
  import ora6 from "ora";
10725
10792
  import { writeFile as writeFile6, mkdir as mkdir6 } from "fs/promises";
10726
- import { resolve as resolve15, join as join15, dirname as dirname9 } from "path";
10793
+ import { resolve as resolve16, join as join16, dirname as dirname9 } from "path";
10727
10794
  import { existsSync as existsSync24 } from "fs";
10728
10795
  import {
10729
10796
  FigmaClient,
@@ -10871,7 +10938,7 @@ async function importFigmaAction(urlOrKey, opts) {
10871
10938
  stats.filesWritten.push(filePath);
10872
10939
  return;
10873
10940
  }
10874
- const fullPath = join15(projectRoot, filePath);
10941
+ const fullPath = join16(projectRoot, filePath);
10875
10942
  await mkdir6(dirname9(fullPath), { recursive: true });
10876
10943
  await writeFile6(fullPath, content, "utf-8");
10877
10944
  stats.filesWritten.push(filePath);
@@ -10948,7 +11015,7 @@ async function importFigmaAction(urlOrKey, opts) {
10948
11015
  if (dryRun) stats.filesWritten.push(FIGMA_COMPONENT_MAP_FILENAME);
10949
11016
  else
10950
11017
  await writeFile6(
10951
- resolve15(projectRoot, FIGMA_COMPONENT_MAP_FILENAME),
11018
+ resolve16(projectRoot, FIGMA_COMPONENT_MAP_FILENAME),
10952
11019
  JSON.stringify(componentMapObj, null, 2),
10953
11020
  "utf-8"
10954
11021
  );
@@ -10971,7 +11038,7 @@ async function importFigmaAction(urlOrKey, opts) {
10971
11038
  const fullConfig = buildFigmaImportConfig(mergedConfig, pageDefs, intermediate.fileName);
10972
11039
  if (!dryRun) {
10973
11040
  spinner.start("Updating design-system.config.ts...");
10974
- const configPath = resolve15(projectRoot, DESIGN_SYSTEM_CONFIG_PATH);
11041
+ const configPath = resolve16(projectRoot, DESIGN_SYSTEM_CONFIG_PATH);
10975
11042
  const dsm = new DesignSystemManager13(configPath);
10976
11043
  if (existsSync24(configPath)) {
10977
11044
  await dsm.load();
@@ -11002,7 +11069,7 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
11002
11069
  stats.configUpdated = true;
11003
11070
  spinner.succeed("design-system.config.ts updated");
11004
11071
  spinner.start("Ensuring root layout...");
11005
- const layoutPath = join15(projectRoot, "app/layout.tsx");
11072
+ const layoutPath = join16(projectRoot, "app/layout.tsx");
11006
11073
  if (!existsSync24(layoutPath)) {
11007
11074
  await mkdir6(dirname9(layoutPath), { recursive: true });
11008
11075
  await writeFile6(layoutPath, MINIMAL_ROOT_LAYOUT, "utf-8");
@@ -11094,7 +11161,7 @@ async function dsRegenerateCommand() {
11094
11161
  import chalk28 from "chalk";
11095
11162
  import ora8 from "ora";
11096
11163
  import { readFileSync as readFileSync17, existsSync as existsSync25 } from "fs";
11097
- import { join as join16 } from "path";
11164
+ import { join as join17 } from "path";
11098
11165
  import { DesignSystemManager as DesignSystemManager15, CLI_VERSION as CLI_VERSION4 } from "@getcoherent/core";
11099
11166
 
11100
11167
  // src/utils/migrations.ts
@@ -11263,7 +11330,7 @@ var EXPECTED_CSS_VARS = [
11263
11330
  "--sidebar-ring"
11264
11331
  ];
11265
11332
  function checkMissingCssVars(projectRoot) {
11266
- const globalsPath = join16(projectRoot, "app", "globals.css");
11333
+ const globalsPath = join17(projectRoot, "app", "globals.css");
11267
11334
  if (!existsSync25(globalsPath)) return [];
11268
11335
  try {
11269
11336
  const content = readFileSync17(globalsPath, "utf-8");
@@ -11273,7 +11340,7 @@ function checkMissingCssVars(projectRoot) {
11273
11340
  }
11274
11341
  }
11275
11342
  function patchGlobalsCss(projectRoot, missingVars) {
11276
- const globalsPath = join16(projectRoot, "app", "globals.css");
11343
+ const globalsPath = join17(projectRoot, "app", "globals.css");
11277
11344
  if (!existsSync25(globalsPath) || missingVars.length === 0) return;
11278
11345
  const { writeFileSync: writeFileSync13 } = __require("fs");
11279
11346
  let content = readFileSync17(globalsPath, "utf-8");
@@ -11355,14 +11422,14 @@ async function undoCommand(options) {
11355
11422
  import chalk30 from "chalk";
11356
11423
  import ora9 from "ora";
11357
11424
  import { existsSync as existsSync26, readFileSync as readFileSync18 } from "fs";
11358
- import { join as join17, relative as relative4, dirname as dirname10 } from "path";
11425
+ import { join as join18, relative as relative4, dirname as dirname10 } from "path";
11359
11426
  import { readdir as readdir4, readFile as readFile6 } from "fs/promises";
11360
11427
  import { DesignSystemManager as DesignSystemManager16 } from "@getcoherent/core";
11361
11428
  import { loadManifest as loadManifest13, saveManifest as saveManifest5, findSharedComponent } from "@getcoherent/core";
11362
11429
  function extractTokensFromProject(projectRoot) {
11363
11430
  const lightColors = {};
11364
11431
  const darkColors = {};
11365
- const globalsPath = join17(projectRoot, "app", "globals.css");
11432
+ const globalsPath = join18(projectRoot, "app", "globals.css");
11366
11433
  if (existsSync26(globalsPath)) {
11367
11434
  const css = readFileSync18(globalsPath, "utf-8");
11368
11435
  const rootMatch = css.match(/:root\s*\{([^}]+)\}/s);
@@ -11370,7 +11437,7 @@ function extractTokensFromProject(projectRoot) {
11370
11437
  const darkMatch = css.match(/\.dark\s*\{([^}]+)\}/s);
11371
11438
  if (darkMatch) parseVarsInto(darkMatch[1], darkColors);
11372
11439
  }
11373
- const layoutPath = join17(projectRoot, "app", "layout.tsx");
11440
+ const layoutPath = join18(projectRoot, "app", "layout.tsx");
11374
11441
  let layoutCode = "";
11375
11442
  if (existsSync26(layoutPath)) {
11376
11443
  layoutCode = readFileSync18(layoutPath, "utf-8");
@@ -11414,7 +11481,7 @@ function parseVarsInto(block, target) {
11414
11481
  }
11415
11482
  async function detectCustomComponents(projectRoot, allPageCode) {
11416
11483
  const results = [];
11417
- const componentsDir = join17(projectRoot, "components");
11484
+ const componentsDir = join18(projectRoot, "components");
11418
11485
  if (!existsSync26(componentsDir)) return results;
11419
11486
  const files = [];
11420
11487
  await walkForTsx(componentsDir, files, ["ui"]);
@@ -11442,7 +11509,7 @@ async function walkForTsx(dir, files, skipDirs) {
11442
11509
  return;
11443
11510
  }
11444
11511
  for (const e of entries) {
11445
- const full = join17(dir, e.name);
11512
+ const full = join18(dir, e.name);
11446
11513
  if (e.isDirectory()) {
11447
11514
  if (skipDirs.includes(e.name) || e.name.startsWith(".")) continue;
11448
11515
  await walkForTsx(full, files, skipDirs);
@@ -11516,7 +11583,7 @@ async function discoverPages(appDir) {
11516
11583
  return;
11517
11584
  }
11518
11585
  for (const entry of entries) {
11519
- const full = join17(dir, entry.name);
11586
+ const full = join18(dir, entry.name);
11520
11587
  if (entry.isDirectory()) {
11521
11588
  if (["design-system", "api", "_not-found"].includes(entry.name)) continue;
11522
11589
  if (entry.name.startsWith(".")) continue;
@@ -11593,7 +11660,7 @@ async function syncCommand(options = {}) {
11593
11660
  if (dryRun) console.log(chalk30.yellow(" [dry-run] No files will be written\n"));
11594
11661
  const spinner = ora9("Scanning project files...").start();
11595
11662
  try {
11596
- const appDir = join17(project.root, "app");
11663
+ const appDir = join18(project.root, "app");
11597
11664
  if (!existsSync26(appDir)) {
11598
11665
  spinner.fail("No app/ directory found");
11599
11666
  process.exit(1);
@@ -11820,14 +11887,14 @@ async function syncCommand(options = {}) {
11820
11887
 
11821
11888
  // src/utils/update-notifier.ts
11822
11889
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync12 } from "fs";
11823
- import { join as join18 } from "path";
11890
+ import { join as join19 } from "path";
11824
11891
  import { homedir } from "os";
11825
11892
  import chalk31 from "chalk";
11826
11893
  import { CLI_VERSION as CLI_VERSION5 } from "@getcoherent/core";
11827
11894
  var DEBUG5 = process.env.COHERENT_DEBUG === "1";
11828
11895
  var PACKAGE_NAME = "@getcoherent/cli";
11829
- var CACHE_DIR = join18(homedir(), ".coherent");
11830
- var CACHE_FILE = join18(CACHE_DIR, "update-check.json");
11896
+ var CACHE_DIR = join19(homedir(), ".coherent");
11897
+ var CACHE_FILE = join19(CACHE_DIR, "update-check.json");
11831
11898
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
11832
11899
  function readCache() {
11833
11900
  try {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.2.0",
6
+ "version": "0.2.2",
7
7
  "description": "CLI interface for Coherent Design Method",
8
8
  "type": "module",
9
9
  "main": "./dist/index.js",
@@ -43,7 +43,7 @@
43
43
  "ora": "^7.0.1",
44
44
  "prompts": "^2.4.2",
45
45
  "zod": "^3.22.4",
46
- "@getcoherent/core": "0.2.0"
46
+ "@getcoherent/core": "0.2.2"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/node": "^20.11.0",