@getcoherent/cli 0.6.9 → 0.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  CORE_CONSTRAINTS,
3
3
  DESIGN_QUALITY,
4
+ DESIGN_QUALITY_COMMON,
4
5
  DESIGN_THINKING,
5
6
  INTERACTION_PATTERNS,
6
7
  VISUAL_DEPTH,
@@ -13,7 +14,7 @@ import {
13
14
  routeToKey,
14
15
  savePlan,
15
16
  selectContextualRules
16
- } from "./chunk-33HL6ERR.js";
17
+ } from "./chunk-CLPILU3Z.js";
17
18
  import {
18
19
  __require
19
20
  } from "./chunk-3RG5ZIWI.js";
@@ -1369,10 +1370,10 @@ var ShadcnProvider = class {
1369
1370
  const componentPath = path.join(projectRoot, "components", "ui", `${name}.tsx`);
1370
1371
  if (!force && deps.existsSync(componentPath)) return;
1371
1372
  try {
1372
- await new Promise((resolve16, reject) => {
1373
+ await new Promise((resolve17, reject) => {
1373
1374
  deps.exec(`npx shadcn@latest add ${name} --yes --overwrite`, { cwd: projectRoot, timeout: 15e3 }, (err) => {
1374
1375
  if (err) reject(err);
1375
- else resolve16();
1376
+ else resolve17();
1376
1377
  });
1377
1378
  });
1378
1379
  } catch {
@@ -1413,13 +1414,13 @@ var ShadcnProvider = class {
1413
1414
  }
1414
1415
  if (toInstall.length === 0) return results;
1415
1416
  try {
1416
- await new Promise((resolve16, reject) => {
1417
+ await new Promise((resolve17, reject) => {
1417
1418
  deps.exec(
1418
1419
  `npx shadcn@latest add ${toInstall.join(" ")} --yes --overwrite`,
1419
1420
  { cwd: projectRoot, timeout: 3e4 },
1420
1421
  (err) => {
1421
1422
  if (err) reject(err);
1422
- else resolve16();
1423
+ else resolve17();
1423
1424
  }
1424
1425
  );
1425
1426
  });
@@ -1931,7 +1932,7 @@ function installPackages(projectRoot, packages) {
1931
1932
  if (packages.length === 0) return Promise.resolve(true);
1932
1933
  const safe = packages.filter((p) => SAFE_PKG_NAME.test(p));
1933
1934
  if (safe.length === 0) return Promise.resolve(true);
1934
- return new Promise((resolve16) => {
1935
+ return new Promise((resolve17) => {
1935
1936
  try {
1936
1937
  const hasPnpm = existsSync4(join3(projectRoot, "pnpm-lock.yaml"));
1937
1938
  if (hasPnpm) {
@@ -1942,10 +1943,10 @@ function installPackages(projectRoot, packages) {
1942
1943
  stdio: "pipe"
1943
1944
  });
1944
1945
  }
1945
- resolve16(true);
1946
+ resolve17(true);
1946
1947
  } catch (e) {
1947
1948
  if (process.env.COHERENT_DEBUG === "1") console.error("Failed to install packages:", e);
1948
- resolve16(false);
1949
+ resolve17(false);
1949
1950
  }
1950
1951
  });
1951
1952
  }
@@ -3372,6 +3373,7 @@ function generateV4GlobalsCss(config2) {
3372
3373
  --color-accent-foreground: var(--accent-foreground);
3373
3374
  --color-destructive: var(--destructive);
3374
3375
  --color-destructive-foreground: var(--destructive-foreground);
3376
+ --color-transparent: transparent;
3375
3377
  --color-border: var(--border);
3376
3378
  --color-input: var(--input);
3377
3379
  --color-ring: var(--ring);
@@ -3763,8 +3765,8 @@ async function createAppRouteGroupLayout(projectPath) {
3763
3765
  // src/commands/chat.ts
3764
3766
  import chalk14 from "chalk";
3765
3767
  import ora2 from "ora";
3766
- import { resolve as resolve9, relative as relative2, join as join11 } from "path";
3767
- import { existsSync as existsSync16, readFileSync as readFileSync11, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
3768
+ import { resolve as resolve10, relative as relative2, join as join11 } from "path";
3769
+ import { existsSync as existsSync17, readFileSync as readFileSync12, mkdirSync as mkdirSync6, readdirSync as readdirSync4 } from "fs";
3768
3770
  import {
3769
3771
  DesignSystemManager as DesignSystemManager7,
3770
3772
  ComponentManager as ComponentManager5,
@@ -4919,6 +4921,7 @@ function needsGlobalsFix(projectRoot) {
4919
4921
  if (isTailwindV4(projectRoot)) {
4920
4922
  if (!content.includes("@theme inline")) return true;
4921
4923
  if (content.includes("@tailwind base")) return true;
4924
+ if (!content.includes("--color-transparent")) return true;
4922
4925
  return false;
4923
4926
  }
4924
4927
  if (content.includes(":root {") || content.includes(".dark {")) return true;
@@ -6084,14 +6087,6 @@ ${selectImport}`
6084
6087
  if (fixed !== beforeTabsFix) {
6085
6088
  fixes.push("stripped border from TabsTrigger (shadcn handles active state)");
6086
6089
  }
6087
- const beforeTabsListFix = fixed;
6088
- fixed = fixed.replace(
6089
- /<TabsList\b(?![^>]*variant=)/g,
6090
- '<TabsList variant="line"'
6091
- );
6092
- if (fixed !== beforeTabsListFix) {
6093
- fixes.push('added variant="line" to TabsList (clean underline style)');
6094
- }
6095
6090
  fixed = fixed.replace(/className="([^"]*)"/g, (_match, inner) => {
6096
6091
  const cleaned = inner.replace(/\s{2,}/g, " ").trim();
6097
6092
  return `className="${cleaned}"`;
@@ -6811,6 +6806,8 @@ function applyDefaults(request) {
6811
6806
  }
6812
6807
 
6813
6808
  // src/commands/chat/split-generator.ts
6809
+ import { existsSync as existsSync14, readFileSync as readFileSync9, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
6810
+ import { resolve as resolve6 } from "path";
6814
6811
  import { z } from "zod";
6815
6812
  import {
6816
6813
  loadManifest as loadManifest5,
@@ -7042,9 +7039,55 @@ ${groupLines.join("\n")}`];
7042
7039
  if (compLines.length > 0) {
7043
7040
  parts.push(`Shared Components:
7044
7041
  ${compLines.join("\n")}`);
7042
+ }
7043
+ const noteEntries = Object.entries(plan.pageNotes || {}).filter(
7044
+ ([, note]) => note.sections && note.sections.length > 0
7045
+ );
7046
+ if (noteEntries.length > 0) {
7047
+ const noteLines = noteEntries.map(([key, note]) => ` ${key}: ${note.sections.join(", ")}`);
7048
+ parts.push(`Page Sections:
7049
+ ${noteLines.join("\n")}`);
7045
7050
  }
7046
7051
  return parts.join("\n");
7047
7052
  }
7053
+ function readExistingAppPageForReference(projectRoot, plan) {
7054
+ if (!projectRoot) return null;
7055
+ if (plan?.pageNotes) {
7056
+ for (const [key, note] of Object.entries(plan.pageNotes)) {
7057
+ if (note.type !== "app") continue;
7058
+ for (const group of ["(app)", "(admin)", "(dashboard)"]) {
7059
+ const filePath = resolve6(projectRoot, "app", group, key, "page.tsx");
7060
+ if (existsSync14(filePath)) {
7061
+ const code = readFileSync9(filePath, "utf-8");
7062
+ const lines = code.split("\n");
7063
+ return lines.slice(0, 200).join("\n");
7064
+ }
7065
+ }
7066
+ }
7067
+ }
7068
+ const appDir = resolve6(projectRoot, "app");
7069
+ if (!existsSync14(appDir)) return null;
7070
+ try {
7071
+ const entries = readdirSync2(appDir);
7072
+ for (const entry of entries) {
7073
+ if (!entry.startsWith("(") || entry === "(auth)") continue;
7074
+ const groupDir = resolve6(appDir, entry);
7075
+ if (!statSync2(groupDir).isDirectory()) continue;
7076
+ const subDirs = readdirSync2(groupDir);
7077
+ for (const sub of subDirs) {
7078
+ const pagePath = resolve6(groupDir, sub, "page.tsx");
7079
+ if (existsSync14(pagePath)) {
7080
+ const code = readFileSync9(pagePath, "utf-8");
7081
+ const lines = code.split("\n");
7082
+ return lines.slice(0, 200).join("\n");
7083
+ }
7084
+ }
7085
+ }
7086
+ } catch {
7087
+ return null;
7088
+ }
7089
+ return null;
7090
+ }
7048
7091
  async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts) {
7049
7092
  let pageNames = [];
7050
7093
  spinner.start("Phase 1/6 \u2014 Planning pages...");
@@ -7199,7 +7242,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7199
7242
  if (plan && plan.sharedComponents.length > 0) {
7200
7243
  spinner.start(`Phase 4.5/6 \u2014 Generating ${plan.sharedComponents.length} shared components from plan...`);
7201
7244
  try {
7202
- const { generateSharedComponentsFromPlan } = await import("./plan-generator-WTLO5B76.js");
7245
+ const { generateSharedComponentsFromPlan } = await import("./plan-generator-QUESV7GS.js");
7203
7246
  const generated = await generateSharedComponentsFromPlan(
7204
7247
  plan,
7205
7248
  styleContext,
@@ -7246,6 +7289,13 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7246
7289
  const routeNote = `EXISTING ROUTES in this project: ${allRoutes}. All internal links MUST point to one of these routes. If a target doesn't exist, use href="#".`;
7247
7290
  const alignmentNote = 'CRITICAL LAYOUT RULE: Every <section> must wrap its content in a container div matching the header width. Use the EXACT same container classes as shown in the style context (e.g. className="container max-w-6xl px-4" or className="max-w-6xl mx-auto px-4"). Inner content can use narrower max-w for text centering, but the outer section container MUST match.';
7248
7291
  const planSummaryNote = plan ? formatPlanSummary(plan) : "";
7292
+ const existingAppPageCode = readExistingAppPageForReference(parseOpts?.projectRoot ?? null, plan);
7293
+ const existingAppPageNote = existingAppPageCode ? `
7294
+ EXISTING APP PAGE (match these UI patterns for consistency):
7295
+ \`\`\`
7296
+ ${existingAppPageCode}
7297
+ \`\`\`
7298
+ ` : "";
7249
7299
  const existingPagesContext = buildExistingPagesContext(modCtx.config);
7250
7300
  const AI_CONCURRENCY = 3;
7251
7301
  let phase5Done = 0;
@@ -7268,6 +7318,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7268
7318
  alignmentNote,
7269
7319
  authNote,
7270
7320
  planSummaryNote,
7321
+ pageType !== "auth" ? existingAppPageNote : void 0,
7271
7322
  existingPagesContext,
7272
7323
  styleContext
7273
7324
  ].filter(Boolean).join("\n\n");
@@ -7428,7 +7479,7 @@ function extractAppNameFromPrompt(prompt) {
7428
7479
  }
7429
7480
 
7430
7481
  // src/commands/chat/modification-handler.ts
7431
- import { resolve as resolve7 } from "path";
7482
+ import { resolve as resolve8 } from "path";
7432
7483
  import { mkdir as mkdir4 } from "fs/promises";
7433
7484
  import { dirname as dirname6 } from "path";
7434
7485
  import chalk12 from "chalk";
@@ -7442,8 +7493,8 @@ import {
7442
7493
  } from "@getcoherent/core";
7443
7494
 
7444
7495
  // src/commands/chat/code-generator.ts
7445
- import { resolve as resolve6 } from "path";
7446
- import { existsSync as existsSync14, readdirSync as readdirSync2, readFileSync as readFileSync9 } from "fs";
7496
+ import { resolve as resolve7 } from "path";
7497
+ import { existsSync as existsSync15, readdirSync as readdirSync3, readFileSync as readFileSync10 } from "fs";
7447
7498
  import { mkdir as mkdir3 } from "fs/promises";
7448
7499
  import { dirname as dirname5 } from "path";
7449
7500
  import {
@@ -7508,8 +7559,8 @@ async function ensureComponentsInstalled(componentIds, cm, dsm, pm, projectRoot)
7508
7559
  for (const componentId of ids) {
7509
7560
  const isRegistered = !!cm.read(componentId);
7510
7561
  const fileName = toKebabCase(componentId) + ".tsx";
7511
- const filePath = resolve6(projectRoot, "components", "ui", fileName);
7512
- const fileExists = existsSync14(filePath);
7562
+ const filePath = resolve7(projectRoot, "components", "ui", fileName);
7563
+ const fileExists = existsSync15(filePath);
7513
7564
  if (isRegistered && fileExists) continue;
7514
7565
  const result = await provider.installComponent(componentId, projectRoot);
7515
7566
  if (result.success && result.componentDef) {
@@ -7533,7 +7584,7 @@ async function regenerateComponent(componentId, config2, projectRoot) {
7533
7584
  const generator = new ComponentGenerator2(config2);
7534
7585
  const code = await generator.generate(component);
7535
7586
  const fileName = toKebabCase(component.name) + ".tsx";
7536
- const filePath = resolve6(projectRoot, "components", "ui", fileName);
7587
+ const filePath = resolve7(projectRoot, "components", "ui", fileName);
7537
7588
  await writeFile(filePath, code);
7538
7589
  }
7539
7590
  async function regeneratePage(pageId, config2, projectRoot) {
@@ -7550,8 +7601,8 @@ async function regeneratePage(pageId, config2, projectRoot) {
7550
7601
  await writeFile(filePath, code);
7551
7602
  }
7552
7603
  async function canOverwriteShared(projectRoot, componentFile, storedHashes) {
7553
- const filePath = resolve6(projectRoot, componentFile);
7554
- if (!existsSync14(filePath)) return true;
7604
+ const filePath = resolve7(projectRoot, componentFile);
7605
+ if (!existsSync15(filePath)) return true;
7555
7606
  const storedHash = storedHashes[componentFile];
7556
7607
  if (!storedHash) return true;
7557
7608
  const edited = await isManuallyEdited(filePath, storedHash);
@@ -7568,7 +7619,7 @@ async function regenerateLayout(config2, projectRoot, options = { navChanged: fa
7568
7619
  if (!initialized) {
7569
7620
  const layout = config2.pages[0]?.layout || "centered";
7570
7621
  const code = await generator.generateLayout(layout, appType, { skipNav: true });
7571
- await writeFile(resolve6(projectRoot, "app", "layout.tsx"), code);
7622
+ await writeFile(resolve7(projectRoot, "app", "layout.tsx"), code);
7572
7623
  }
7573
7624
  if (config2.navigation?.enabled && appType === "multi-page") {
7574
7625
  const navType = config2.navigation.type || "header";
@@ -7624,17 +7675,17 @@ async function regenerateLayout(config2, projectRoot, options = { navChanged: fa
7624
7675
  }
7625
7676
  }
7626
7677
  async function scanAndInstallSharedDeps(projectRoot) {
7627
- const sharedDir = resolve6(projectRoot, "components", "shared");
7628
- if (!existsSync14(sharedDir)) return [];
7629
- const files = readdirSync2(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts"));
7678
+ const sharedDir = resolve7(projectRoot, "components", "shared");
7679
+ if (!existsSync15(sharedDir)) return [];
7680
+ const files = readdirSync3(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts"));
7630
7681
  const installed = [];
7631
7682
  const provider = getComponentProvider();
7632
7683
  for (const file of files) {
7633
- const code = readFileSync9(resolve6(sharedDir, file), "utf-8");
7684
+ const code = readFileSync10(resolve7(sharedDir, file), "utf-8");
7634
7685
  const importMatches = [...code.matchAll(/@\/components\/ui\/([a-z0-9-]+)/g)];
7635
7686
  for (const [, componentId] of importMatches) {
7636
- const uiPath = resolve6(projectRoot, "components", "ui", `${componentId}.tsx`);
7637
- if (!existsSync14(uiPath) && provider.has(componentId)) {
7687
+ const uiPath = resolve7(projectRoot, "components", "ui", `${componentId}.tsx`);
7688
+ if (!existsSync15(uiPath) && provider.has(componentId)) {
7638
7689
  try {
7639
7690
  await provider.installComponent(componentId, projectRoot);
7640
7691
  installed.push(componentId);
@@ -7646,10 +7697,10 @@ async function scanAndInstallSharedDeps(projectRoot) {
7646
7697
  return [...new Set(installed)];
7647
7698
  }
7648
7699
  async function ensureAppRouteGroupLayout(projectRoot, navType, forceUpdate = false) {
7649
- const layoutPath = resolve6(projectRoot, "app", "(app)", "layout.tsx");
7650
- if (existsSync14(layoutPath) && !forceUpdate) return;
7700
+ const layoutPath = resolve7(projectRoot, "app", "(app)", "layout.tsx");
7701
+ if (existsSync15(layoutPath) && !forceUpdate) return;
7651
7702
  const { mkdir: mkdirAsync } = await import("fs/promises");
7652
- await mkdirAsync(resolve6(projectRoot, "app", "(app)"), { recursive: true });
7703
+ await mkdirAsync(resolve7(projectRoot, "app", "(app)"), { recursive: true });
7653
7704
  const code = buildAppLayoutCode(navType);
7654
7705
  await writeFile(layoutPath, code);
7655
7706
  }
@@ -7737,9 +7788,9 @@ export default function GroupLayout({
7737
7788
  async function ensurePlanGroupLayouts(projectRoot, plan) {
7738
7789
  const { mkdir: mkdirAsync } = await import("fs/promises");
7739
7790
  for (const group of plan.groups) {
7740
- const groupDir = resolve6(projectRoot, "app", `(${group.id})`);
7791
+ const groupDir = resolve7(projectRoot, "app", `(${group.id})`);
7741
7792
  await mkdirAsync(groupDir, { recursive: true });
7742
- const layoutPath = resolve6(groupDir, "layout.tsx");
7793
+ const layoutPath = resolve7(groupDir, "layout.tsx");
7743
7794
  const code = buildGroupLayoutCode(group.layout, group.pages);
7744
7795
  await writeFile(layoutPath, code);
7745
7796
  }
@@ -7766,11 +7817,11 @@ async function regenerateFiles(modified, config2, projectRoot, options = { navCh
7766
7817
  }
7767
7818
  if (componentIds.size > 0) {
7768
7819
  const twGen = new TailwindConfigGenerator(config2);
7769
- const twPath = resolve6(projectRoot, "tailwind.config.ts");
7770
- const twCjsPath = resolve6(projectRoot, "tailwind.config.cjs");
7771
- if (existsSync14(twPath)) {
7820
+ const twPath = resolve7(projectRoot, "tailwind.config.ts");
7821
+ const twCjsPath = resolve7(projectRoot, "tailwind.config.cjs");
7822
+ if (existsSync15(twPath)) {
7772
7823
  await writeFile(twPath, await twGen.generate());
7773
- } else if (existsSync14(twCjsPath)) {
7824
+ } else if (existsSync15(twCjsPath)) {
7774
7825
  await writeFile(twCjsPath, await twGen.generateCjs());
7775
7826
  }
7776
7827
  }
@@ -8142,7 +8193,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8142
8193
  modified: []
8143
8194
  };
8144
8195
  }
8145
- const fullPath = resolve7(projectRoot, resolved.file);
8196
+ const fullPath = resolve8(projectRoot, resolved.file);
8146
8197
  let currentCode;
8147
8198
  try {
8148
8199
  currentCode = await readFile(fullPath);
@@ -8216,7 +8267,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8216
8267
  } catch {
8217
8268
  return { success: false, message: `Could not read ${pageFilePath}`, modified: [] };
8218
8269
  }
8219
- const sharedPath = resolve7(projectRoot, resolved.file);
8270
+ const sharedPath = resolve8(projectRoot, resolved.file);
8220
8271
  let sharedCode;
8221
8272
  try {
8222
8273
  sharedCode = await readFile(sharedPath);
@@ -8295,7 +8346,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8295
8346
  }
8296
8347
  let sourceCode;
8297
8348
  try {
8298
- sourceCode = await readFile(resolve7(projectRoot, sourcePath));
8349
+ sourceCode = await readFile(resolve8(projectRoot, sourcePath));
8299
8350
  } catch {
8300
8351
  return { success: false, message: `Could not read ${sourcePath}`, modified: [] };
8301
8352
  }
@@ -8315,7 +8366,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8315
8366
  description: `Extracted from ${sourcePageName}: ${blockHint}`,
8316
8367
  usedIn: []
8317
8368
  });
8318
- const sharedPath = resolve7(projectRoot, created.file);
8369
+ const sharedPath = resolve8(projectRoot, created.file);
8319
8370
  let sharedCode;
8320
8371
  try {
8321
8372
  sharedCode = await readFile(sharedPath);
@@ -8326,7 +8377,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8326
8377
  for (const pageName of allPagesToLink) {
8327
8378
  const relPath = routeToPath(pageName);
8328
8379
  if (!relPath) continue;
8329
- const fullPath = resolve7(projectRoot, relPath);
8380
+ const fullPath = resolve8(projectRoot, relPath);
8330
8381
  let linkPageCode;
8331
8382
  try {
8332
8383
  linkPageCode = await readFile(fullPath);
@@ -8660,7 +8711,10 @@ Rules:
8660
8711
  if (ai.editPageCode) {
8661
8712
  console.log(chalk12.dim(" \u270F\uFE0F Applying changes to existing page..."));
8662
8713
  const coreRules = CORE_CONSTRAINTS;
8663
- const qualityRules = DESIGN_QUALITY;
8714
+ const pageRoute = pageDef.route || `/${pageDef.id}`;
8715
+ const pageType = inferPageTypeFromRoute(pageRoute);
8716
+ const qualityRules = `${DESIGN_QUALITY_COMMON}
8717
+ ${getDesignQualityForType(pageType)}`;
8664
8718
  const contextualRules = selectContextualRules(instruction);
8665
8719
  const existingRoutes = dsm.getConfig().pages.map((p) => p.route).join(", ");
8666
8720
  const routeRules = `
@@ -8950,8 +9004,8 @@ function hasNavChanged(before, after) {
8950
9004
 
8951
9005
  // src/commands/chat/interactive.ts
8952
9006
  import chalk13 from "chalk";
8953
- import { resolve as resolve8 } from "path";
8954
- import { existsSync as existsSync15, readFileSync as readFileSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
9007
+ import { resolve as resolve9 } from "path";
9008
+ import { existsSync as existsSync16, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
8955
9009
  import { DesignSystemManager as DesignSystemManager6, ComponentManager as ComponentManager4, loadManifest as loadManifest7 } from "@getcoherent/core";
8956
9010
  var DEBUG3 = process.env.COHERENT_DEBUG === "1";
8957
9011
  async function interactiveChat(options, chatCommandFn) {
@@ -8971,13 +9025,13 @@ async function interactiveChat(options, chatCommandFn) {
8971
9025
  \u274C Invalid provider: ${options.provider}`));
8972
9026
  process.exit(1);
8973
9027
  }
8974
- const historyDir = resolve8(homedir2(), ".coherent");
8975
- const historyFile = resolve8(historyDir, "history");
9028
+ const historyDir = resolve9(homedir2(), ".coherent");
9029
+ const historyFile = resolve9(historyDir, "history");
8976
9030
  let history = [];
8977
9031
  try {
8978
9032
  mkdirSync5(historyDir, { recursive: true });
8979
- if (existsSync15(historyFile)) {
8980
- history = readFileSync10(historyFile, "utf-8").split("\n").filter(Boolean).slice(-200);
9033
+ if (existsSync16(historyFile)) {
9034
+ history = readFileSync11(historyFile, "utf-8").split("\n").filter(Boolean).slice(-200);
8981
9035
  }
8982
9036
  } catch (e) {
8983
9037
  if (DEBUG3) console.error("Failed to load REPL history:", e);
@@ -9148,7 +9202,7 @@ async function chatCommand(message, options) {
9148
9202
  const projectRoot = project.root;
9149
9203
  const configPath = project.configPath;
9150
9204
  const migrationGuard = join11(projectRoot, ".coherent", "migration-in-progress");
9151
- if (existsSync16(migrationGuard)) {
9205
+ if (existsSync17(migrationGuard)) {
9152
9206
  spinner.fail("Migration in progress");
9153
9207
  console.error(chalk14.red("\n\u274C A migration is in progress. Run `coherent migrate --rollback` to undo first."));
9154
9208
  bail("Migration in progress");
@@ -9208,7 +9262,7 @@ async function chatCommand(message, options) {
9208
9262
  }
9209
9263
  if (/switch to light mode|default to light|make.*light.*(default|theme)|light theme/i.test(message)) {
9210
9264
  spinner.start("Setting default theme to light...");
9211
- const layoutPath = resolve9(projectRoot, "app/layout.tsx");
9265
+ const layoutPath = resolve10(projectRoot, "app/layout.tsx");
9212
9266
  try {
9213
9267
  let layout = await readFile(layoutPath);
9214
9268
  layout = layout.replace(/className="dark"/, "");
@@ -9247,8 +9301,8 @@ async function chatCommand(message, options) {
9247
9301
  spinner.start("Parsing your request...");
9248
9302
  let manifest = await loadManifest8(project.root);
9249
9303
  const validShared = manifest.shared.filter((s) => {
9250
- const fp = resolve9(project.root, s.file);
9251
- return existsSync16(fp);
9304
+ const fp = resolve10(project.root, s.file);
9305
+ return existsSync17(fp);
9252
9306
  });
9253
9307
  if (validShared.length !== manifest.shared.length) {
9254
9308
  const cleaned = manifest.shared.length - validShared.length;
@@ -9452,9 +9506,9 @@ async function chatCommand(message, options) {
9452
9506
  if (manifest.shared.length > 0) {
9453
9507
  for (const entry of manifest.shared) {
9454
9508
  try {
9455
- const sharedPath = resolve9(projectRoot, entry.file);
9456
- if (existsSync16(sharedPath)) {
9457
- const sharedCode = readFileSync11(sharedPath, "utf-8");
9509
+ const sharedPath = resolve10(projectRoot, entry.file);
9510
+ if (existsSync17(sharedPath)) {
9511
+ const sharedCode = readFileSync12(sharedPath, "utf-8");
9458
9512
  const sharedImports = sharedCode.matchAll(/@\/components\/ui\/([a-z0-9-]+)/g);
9459
9513
  for (const m of sharedImports) {
9460
9514
  if (m[1]) allNeededComponentIds.add(m[1]);
@@ -9475,7 +9529,7 @@ async function chatCommand(message, options) {
9475
9529
  for (const componentId of allNeededComponentIds) {
9476
9530
  const isRegistered = !!cm.read(componentId);
9477
9531
  const filePath = join11(projectRoot, "components", "ui", `${componentId}.tsx`);
9478
- const fileExists = existsSync16(filePath);
9532
+ const fileExists = existsSync17(filePath);
9479
9533
  if (DEBUG4) console.log(chalk14.gray(` Checking ${componentId}: registered=${isRegistered} file=${fileExists}`));
9480
9534
  if (!isRegistered || !fileExists) {
9481
9535
  missingComponents.push(componentId);
@@ -9601,9 +9655,9 @@ async function chatCommand(message, options) {
9601
9655
  const route = page.route || `/${page.id || "page"}`;
9602
9656
  const pageFilePath = routeToFsPath(projectRoot, route, false);
9603
9657
  let pageCode = "";
9604
- if (existsSync16(pageFilePath)) {
9658
+ if (existsSync17(pageFilePath)) {
9605
9659
  try {
9606
- pageCode = readFileSync11(pageFilePath, "utf-8");
9660
+ pageCode = readFileSync12(pageFilePath, "utf-8");
9607
9661
  } catch {
9608
9662
  }
9609
9663
  }
@@ -9623,8 +9677,8 @@ async function chatCommand(message, options) {
9623
9677
  }
9624
9678
  const missingRoutes = [...allLinkedRoutes].filter((route) => {
9625
9679
  if (expandedExisting.has(route)) return false;
9626
- if (existsSync16(routeToFsPath(projectRoot, route, false))) return false;
9627
- if (existsSync16(routeToFsPath(projectRoot, route, true))) return false;
9680
+ if (existsSync17(routeToFsPath(projectRoot, route, false))) return false;
9681
+ if (existsSync17(routeToFsPath(projectRoot, route, true))) return false;
9628
9682
  return true;
9629
9683
  });
9630
9684
  const SCAFFOLD_AI_LIMIT = 10;
@@ -9688,8 +9742,8 @@ async function chatCommand(message, options) {
9688
9742
  const isAuth = isAuthRoute(linkedRoute);
9689
9743
  const filePath = routeToFsPath(projectRoot, linkedRoute, isAuth);
9690
9744
  if (isAuth) await ensureAuthRouteGroup(projectRoot);
9691
- const dir = resolve9(filePath, "..");
9692
- if (!existsSync16(dir)) {
9745
+ const dir = resolve10(filePath, "..");
9746
+ if (!existsSync17(dir)) {
9693
9747
  mkdirSync6(dir, { recursive: true });
9694
9748
  }
9695
9749
  const placeholderCode = `export default function ${pageName.replace(/\s/g, "")}Page() {
@@ -9722,7 +9776,7 @@ async function chatCommand(message, options) {
9722
9776
  for (const mod of result.modified) {
9723
9777
  if (mod.startsWith("app/") && mod.endsWith("/page.tsx")) {
9724
9778
  try {
9725
- const code = readFileSync11(resolve9(projectRoot, mod), "utf-8");
9779
+ const code = readFileSync12(resolve10(projectRoot, mod), "utf-8");
9726
9780
  const issues = validatePageQuality(code, allRoutes).filter(
9727
9781
  (i) => i.type === "BROKEN_INTERNAL_LINK"
9728
9782
  );
@@ -9752,7 +9806,7 @@ async function chatCommand(message, options) {
9752
9806
  dsm.updateConfig(latestConfig);
9753
9807
  if (DEBUG4) console.log(chalk14.dim(` [theme] Set defaultMode to "${targetMode}"`));
9754
9808
  }
9755
- const layoutPath = resolve9(projectRoot, "app", "layout.tsx");
9809
+ const layoutPath = resolve10(projectRoot, "app", "layout.tsx");
9756
9810
  try {
9757
9811
  let layoutCode = await readFile(layoutPath);
9758
9812
  if (targetMode === "dark" && !layoutCode.includes('className="dark"')) {
@@ -9802,16 +9856,16 @@ async function chatCommand(message, options) {
9802
9856
  }
9803
9857
  try {
9804
9858
  const updatedHashes = { ...storedHashes };
9805
- const sharedDir = resolve9(projectRoot, "components", "shared");
9806
- const layoutFile = resolve9(projectRoot, "app", "layout.tsx");
9859
+ const sharedDir = resolve10(projectRoot, "components", "shared");
9860
+ const layoutFile = resolve10(projectRoot, "app", "layout.tsx");
9807
9861
  const filesToHash = [layoutFile];
9808
- if (existsSync16(sharedDir)) {
9809
- for (const f of readdirSync3(sharedDir)) {
9810
- if (f.endsWith(".tsx")) filesToHash.push(resolve9(sharedDir, f));
9862
+ if (existsSync17(sharedDir)) {
9863
+ for (const f of readdirSync4(sharedDir)) {
9864
+ if (f.endsWith(".tsx")) filesToHash.push(resolve10(sharedDir, f));
9811
9865
  }
9812
9866
  }
9813
9867
  for (const filePath of filesToHash) {
9814
- if (existsSync16(filePath)) {
9868
+ if (existsSync17(filePath)) {
9815
9869
  const rel = relative2(projectRoot, filePath);
9816
9870
  updatedHashes[rel] = await computeFileHash(filePath);
9817
9871
  }
@@ -9843,7 +9897,7 @@ async function chatCommand(message, options) {
9843
9897
  console.log("");
9844
9898
  }
9845
9899
  if (uxRecommendations) {
9846
- const recPath = resolve9(projectRoot, "recommendations.md");
9900
+ const recPath = resolve10(projectRoot, "recommendations.md");
9847
9901
  const section = `
9848
9902
 
9849
9903
  ---
@@ -9853,7 +9907,7 @@ async function chatCommand(message, options) {
9853
9907
  ${uxRecommendations}
9854
9908
  `;
9855
9909
  try {
9856
- if (!existsSync16(recPath)) {
9910
+ if (!existsSync17(recPath)) {
9857
9911
  await writeFile(
9858
9912
  recPath,
9859
9913
  "# UX/UI Recommendations\n\nRecommendations are added here when you use `coherent chat` and the AI suggests improvements.\n"
@@ -9927,18 +9981,18 @@ ${uxRecommendations}
9927
9981
  import chalk15 from "chalk";
9928
9982
  import ora3 from "ora";
9929
9983
  import { spawn } from "child_process";
9930
- import { existsSync as existsSync19, rmSync as rmSync3, readFileSync as readFileSync14, writeFileSync as writeFileSync10, readdirSync as readdirSync5 } from "fs";
9931
- import { resolve as resolve10, join as join14 } from "path";
9984
+ import { existsSync as existsSync20, rmSync as rmSync3, readFileSync as readFileSync15, writeFileSync as writeFileSync10, readdirSync as readdirSync6 } from "fs";
9985
+ import { resolve as resolve11, join as join14 } from "path";
9932
9986
  import { readdir as readdir2 } from "fs/promises";
9933
9987
  import { DesignSystemManager as DesignSystemManager8, ComponentGenerator as ComponentGenerator3 } from "@getcoherent/core";
9934
9988
 
9935
9989
  // src/utils/file-watcher.ts
9936
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, existsSync as existsSync18 } from "fs";
9990
+ import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, existsSync as existsSync19 } from "fs";
9937
9991
  import { relative as relative4, join as join13 } from "path";
9938
9992
  import { loadManifest as loadManifest9, saveManifest as saveManifest3 } from "@getcoherent/core";
9939
9993
 
9940
9994
  // src/utils/component-integrity.ts
9941
- import { existsSync as existsSync17, readFileSync as readFileSync12, readdirSync as readdirSync4 } from "fs";
9995
+ import { existsSync as existsSync18, readFileSync as readFileSync13, readdirSync as readdirSync5 } from "fs";
9942
9996
  import { join as join12, relative as relative3 } from "path";
9943
9997
  function extractExportedComponentNames(code) {
9944
9998
  const names = [];
@@ -9966,13 +10020,13 @@ function arraysEqual(a, b) {
9966
10020
  function findPagesImporting(projectRoot, componentName, componentFile) {
9967
10021
  const results = [];
9968
10022
  const appDir = join12(projectRoot, "app");
9969
- if (!existsSync17(appDir)) return results;
10023
+ if (!existsSync18(appDir)) return results;
9970
10024
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
9971
10025
  const componentImportPath = componentFile.replace(/\.tsx$/, "").replace(/\.jsx$/, "");
9972
10026
  for (const absPath of pageFiles) {
9973
10027
  if (absPath.includes("design-system")) continue;
9974
10028
  try {
9975
- const code = readFileSync12(absPath, "utf-8");
10029
+ const code = readFileSync13(absPath, "utf-8");
9976
10030
  const hasNamedImport = new RegExp(`import\\s+\\{[^}]*\\b${componentName}\\b[^}]*\\}\\s+from\\s+['"]`).test(code);
9977
10031
  const hasDefaultImport = new RegExp(`import\\s+${componentName}\\s+from\\s+['"]`).test(code);
9978
10032
  const hasPathImport = code.includes(`@/${componentImportPath}`);
@@ -9986,9 +10040,9 @@ function findPagesImporting(projectRoot, componentName, componentFile) {
9986
10040
  }
9987
10041
  function isUsedInLayout(projectRoot, componentName) {
9988
10042
  const layoutPath = join12(projectRoot, "app", "layout.tsx");
9989
- if (!existsSync17(layoutPath)) return false;
10043
+ if (!existsSync18(layoutPath)) return false;
9990
10044
  try {
9991
- const code = readFileSync12(layoutPath, "utf-8");
10045
+ const code = readFileSync13(layoutPath, "utf-8");
9992
10046
  return code.includes(componentName);
9993
10047
  } catch {
9994
10048
  return false;
@@ -9997,7 +10051,7 @@ function isUsedInLayout(projectRoot, componentName) {
9997
10051
  function findUnregisteredComponents(projectRoot, manifest) {
9998
10052
  const results = [];
9999
10053
  const componentsDir = join12(projectRoot, "components");
10000
- if (!existsSync17(componentsDir)) return results;
10054
+ if (!existsSync18(componentsDir)) return results;
10001
10055
  const registeredFiles = new Set(manifest.shared.map((s) => s.file));
10002
10056
  const registeredNames = new Set(manifest.shared.map((s) => s.name));
10003
10057
  const files = collectFiles(
@@ -10009,7 +10063,7 @@ function findUnregisteredComponents(projectRoot, manifest) {
10009
10063
  const relFile = relative3(projectRoot, absPath);
10010
10064
  if (registeredFiles.has(relFile)) continue;
10011
10065
  try {
10012
- const code = readFileSync12(absPath, "utf-8");
10066
+ const code = readFileSync13(absPath, "utf-8");
10013
10067
  const exports = extractExportedComponentNames(code);
10014
10068
  for (const name of exports) {
10015
10069
  if (registeredNames.has(name)) continue;
@@ -10025,13 +10079,13 @@ function findUnregisteredComponents(projectRoot, manifest) {
10025
10079
  function findInlineDuplicates(projectRoot, manifest) {
10026
10080
  const results = [];
10027
10081
  const appDir = join12(projectRoot, "app");
10028
- if (!existsSync17(appDir)) return results;
10082
+ if (!existsSync18(appDir)) return results;
10029
10083
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
10030
10084
  for (const absPath of pageFiles) {
10031
10085
  if (absPath.includes("design-system")) continue;
10032
10086
  let code;
10033
10087
  try {
10034
- code = readFileSync12(absPath, "utf-8");
10088
+ code = readFileSync13(absPath, "utf-8");
10035
10089
  } catch {
10036
10090
  continue;
10037
10091
  }
@@ -10055,7 +10109,7 @@ function findInlineDuplicates(projectRoot, manifest) {
10055
10109
  }
10056
10110
  function findComponentFileByExportName(projectRoot, componentName) {
10057
10111
  const componentsDir = join12(projectRoot, "components");
10058
- if (!existsSync17(componentsDir)) return null;
10112
+ if (!existsSync18(componentsDir)) return null;
10059
10113
  const files = collectFiles(
10060
10114
  componentsDir,
10061
10115
  (name) => (name.endsWith(".tsx") || name.endsWith(".jsx")) && !name.startsWith("."),
@@ -10063,7 +10117,7 @@ function findComponentFileByExportName(projectRoot, componentName) {
10063
10117
  );
10064
10118
  for (const absPath of files) {
10065
10119
  try {
10066
- const code = readFileSync12(absPath, "utf-8");
10120
+ const code = readFileSync13(absPath, "utf-8");
10067
10121
  const exports = extractExportedComponentNames(code);
10068
10122
  if (exports.includes(componentName)) {
10069
10123
  return relative3(projectRoot, absPath);
@@ -10077,7 +10131,7 @@ function removeOrphanedEntries(projectRoot, manifest) {
10077
10131
  const removed = [];
10078
10132
  const valid = manifest.shared.filter((entry) => {
10079
10133
  const filePath = join12(projectRoot, entry.file);
10080
- if (existsSync17(filePath)) return true;
10134
+ if (existsSync18(filePath)) return true;
10081
10135
  removed.push({ id: entry.id, name: entry.name });
10082
10136
  return false;
10083
10137
  });
@@ -10096,7 +10150,7 @@ function reconcileComponents(projectRoot, manifest) {
10096
10150
  const m = { ...manifest, shared: [...manifest.shared], nextId: manifest.nextId };
10097
10151
  m.shared = m.shared.filter((entry) => {
10098
10152
  const filePath = join12(projectRoot, entry.file);
10099
- if (!existsSync17(filePath)) {
10153
+ if (!existsSync18(filePath)) {
10100
10154
  const newPath = findComponentFileByExportName(projectRoot, entry.name);
10101
10155
  if (newPath) {
10102
10156
  result.updated.push({ id: entry.id, field: "file", from: entry.file, to: newPath });
@@ -10108,7 +10162,7 @@ function reconcileComponents(projectRoot, manifest) {
10108
10162
  }
10109
10163
  let code;
10110
10164
  try {
10111
- code = readFileSync12(join12(projectRoot, entry.file), "utf-8");
10165
+ code = readFileSync13(join12(projectRoot, entry.file), "utf-8");
10112
10166
  } catch {
10113
10167
  return true;
10114
10168
  }
@@ -10185,7 +10239,7 @@ function collectFiles(dir, filter, skipDirs = []) {
10185
10239
  function walk(d) {
10186
10240
  let entries;
10187
10241
  try {
10188
- entries = readdirSync4(d, { withFileTypes: true });
10242
+ entries = readdirSync5(d, { withFileTypes: true });
10189
10243
  } catch {
10190
10244
  return;
10191
10245
  }
@@ -10230,8 +10284,8 @@ function findInlineDuplicatesOfShared(content, manifest) {
10230
10284
  function getWatcherConfig(projectRoot) {
10231
10285
  try {
10232
10286
  const pkgPath = join13(projectRoot, "package.json");
10233
- if (!existsSync18(pkgPath)) return defaultWatcherConfig();
10234
- const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
10287
+ if (!existsSync19(pkgPath)) return defaultWatcherConfig();
10288
+ const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
10235
10289
  const c = pkg?.coherent?.watcher ?? {};
10236
10290
  return {
10237
10291
  enabled: c.enabled !== false,
@@ -10259,7 +10313,7 @@ async function handleFileChange(projectRoot, filePath) {
10259
10313
  if (relativePath.includes("node_modules") || relativePath.includes(".next")) return;
10260
10314
  let content;
10261
10315
  try {
10262
- content = readFileSync13(filePath, "utf-8");
10316
+ content = readFileSync14(filePath, "utf-8");
10263
10317
  } catch {
10264
10318
  return;
10265
10319
  }
@@ -10332,7 +10386,7 @@ async function detectNewComponent(projectRoot, filePath) {
10332
10386
  const manifest = await loadManifest9(projectRoot);
10333
10387
  const alreadyRegistered = manifest.shared.some((s) => s.file === relativePath);
10334
10388
  if (alreadyRegistered) return;
10335
- const code = readFileSync13(filePath, "utf-8");
10389
+ const code = readFileSync14(filePath, "utf-8");
10336
10390
  const exports = extractExportedComponentNames(code);
10337
10391
  if (exports.length > 0) {
10338
10392
  const alreadyByName = exports.every((n) => manifest.shared.some((s) => s.name === n));
@@ -10372,7 +10426,7 @@ function startFileWatcher(projectRoot) {
10372
10426
  watcher.on("unlink", (fp) => handleFileDelete(projectRoot, fp));
10373
10427
  });
10374
10428
  const manifestPath = join13(projectRoot, "coherent.components.json");
10375
- if (existsSync18(manifestPath)) {
10429
+ if (existsSync19(manifestPath)) {
10376
10430
  import("chokidar").then((chokidar) => {
10377
10431
  manifestWatcher = chokidar.default.watch(manifestPath, { ignoreInitial: true });
10378
10432
  manifestWatcher.on("change", () => handleManifestChange(projectRoot));
@@ -10386,7 +10440,7 @@ function startFileWatcher(projectRoot) {
10386
10440
 
10387
10441
  // src/commands/preview.ts
10388
10442
  function getPackageManager(projectRoot) {
10389
- const hasPnpm = existsSync19(resolve10(projectRoot, "pnpm-lock.yaml"));
10443
+ const hasPnpm = existsSync20(resolve11(projectRoot, "pnpm-lock.yaml"));
10390
10444
  return hasPnpm ? "pnpm" : "npm";
10391
10445
  }
10392
10446
  function runInstall(projectRoot) {
@@ -10408,23 +10462,23 @@ function runInstall(projectRoot) {
10408
10462
  });
10409
10463
  }
10410
10464
  function checkProjectInitialized(projectRoot) {
10411
- const configPath = resolve10(projectRoot, "design-system.config.ts");
10412
- const packageJsonPath = resolve10(projectRoot, "package.json");
10413
- if (!existsSync19(configPath)) {
10465
+ const configPath = resolve11(projectRoot, "design-system.config.ts");
10466
+ const packageJsonPath = resolve11(projectRoot, "package.json");
10467
+ if (!existsSync20(configPath)) {
10414
10468
  return false;
10415
10469
  }
10416
- if (!existsSync19(packageJsonPath)) {
10470
+ if (!existsSync20(packageJsonPath)) {
10417
10471
  return false;
10418
10472
  }
10419
10473
  return true;
10420
10474
  }
10421
10475
  function checkDependenciesInstalled(projectRoot) {
10422
- const nodeModulesPath = resolve10(projectRoot, "node_modules");
10423
- return existsSync19(nodeModulesPath);
10476
+ const nodeModulesPath = resolve11(projectRoot, "node_modules");
10477
+ return existsSync20(nodeModulesPath);
10424
10478
  }
10425
10479
  function clearStaleCache(projectRoot) {
10426
10480
  const nextDir = join14(projectRoot, ".next");
10427
- if (existsSync19(nextDir)) {
10481
+ if (existsSync20(nextDir)) {
10428
10482
  rmSync3(nextDir, { recursive: true, force: true });
10429
10483
  console.log(chalk15.dim(" \u2714 Cleared stale build cache"));
10430
10484
  }
@@ -10440,7 +10494,7 @@ async function preflightDependencyCheck(projectRoot) {
10440
10494
  }
10441
10495
  async function listPageFiles(appDir) {
10442
10496
  const out = [];
10443
- if (!existsSync19(appDir)) return out;
10497
+ if (!existsSync20(appDir)) return out;
10444
10498
  async function walk(dir) {
10445
10499
  const entries = await readdir2(dir, { withFileTypes: true });
10446
10500
  for (const e of entries) {
@@ -10456,7 +10510,7 @@ async function validateSyntax(projectRoot) {
10456
10510
  const appDir = join14(projectRoot, "app");
10457
10511
  const pages = await listPageFiles(appDir);
10458
10512
  for (const file of pages) {
10459
- const content = readFileSync14(file, "utf-8");
10513
+ const content = readFileSync15(file, "utf-8");
10460
10514
  const fixed = fixUnescapedLtInJsx(sanitizeMetadataStrings(ensureUseClientIfNeeded(content)));
10461
10515
  if (fixed !== content) {
10462
10516
  writeFileSync10(file, fixed, "utf-8");
@@ -10467,16 +10521,16 @@ async function validateSyntax(projectRoot) {
10467
10521
  async function fixMissingComponentExports(projectRoot) {
10468
10522
  const appDir = join14(projectRoot, "app");
10469
10523
  const uiDir = join14(projectRoot, "components", "ui");
10470
- if (!existsSync19(appDir) || !existsSync19(uiDir)) return;
10524
+ if (!existsSync20(appDir) || !existsSync20(uiDir)) return;
10471
10525
  const pages = await listPageFiles(appDir);
10472
10526
  const sharedDir = join14(projectRoot, "components", "shared");
10473
- if (existsSync19(sharedDir)) {
10474
- const sharedFiles = readdirSync5(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => join14(sharedDir, f));
10527
+ if (existsSync20(sharedDir)) {
10528
+ const sharedFiles = readdirSync6(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => join14(sharedDir, f));
10475
10529
  pages.push(...sharedFiles);
10476
10530
  }
10477
10531
  const neededExports = /* @__PURE__ */ new Map();
10478
10532
  for (const file of pages) {
10479
- const content = readFileSync14(file, "utf-8");
10533
+ const content = readFileSync15(file, "utf-8");
10480
10534
  const importRe = /import\s*\{([^}]+)\}\s*from\s*['"]@\/components\/ui\/([^'"]+)['"]/g;
10481
10535
  let m;
10482
10536
  while ((m = importRe.exec(content)) !== null) {
@@ -10497,7 +10551,7 @@ async function fixMissingComponentExports(projectRoot) {
10497
10551
  const provider = getComponentProvider();
10498
10552
  for (const [componentId, needed] of neededExports) {
10499
10553
  const componentFile = join14(uiDir, `${componentId}.tsx`);
10500
- if (!existsSync19(componentFile)) {
10554
+ if (!existsSync20(componentFile)) {
10501
10555
  if (provider.has(componentId)) {
10502
10556
  try {
10503
10557
  const result = await provider.installComponent(componentId, projectRoot);
@@ -10520,7 +10574,7 @@ async function fixMissingComponentExports(projectRoot) {
10520
10574
  }
10521
10575
  continue;
10522
10576
  }
10523
- const content = readFileSync14(componentFile, "utf-8");
10577
+ const content = readFileSync15(componentFile, "utf-8");
10524
10578
  const exportRe = /export\s+(?:const|function|class)\s+(\w+)|export\s*\{([^}]+)\}/g;
10525
10579
  const existingExports = /* @__PURE__ */ new Set();
10526
10580
  let em;
@@ -10555,7 +10609,7 @@ async function fixMissingComponentExports(projectRoot) {
10555
10609
  }
10556
10610
  async function backfillPageAnalysis(projectRoot) {
10557
10611
  const configPath = join14(projectRoot, "design-system.config.ts");
10558
- if (!existsSync19(configPath)) return;
10612
+ if (!existsSync20(configPath)) return;
10559
10613
  try {
10560
10614
  const mgr = new DesignSystemManager8(configPath);
10561
10615
  const config2 = mgr.getConfig();
@@ -10572,8 +10626,8 @@ async function backfillPageAnalysis(projectRoot) {
10572
10626
  } else {
10573
10627
  filePath = join14(projectRoot, "app", route.slice(1), "page.tsx");
10574
10628
  }
10575
- if (!existsSync19(filePath)) continue;
10576
- const code = readFileSync14(filePath, "utf-8");
10629
+ if (!existsSync20(filePath)) continue;
10630
+ const code = readFileSync15(filePath, "utf-8");
10577
10631
  if (code.length < 50) continue;
10578
10632
  page.pageAnalysis = analyzePageCode(code);
10579
10633
  changed = true;
@@ -10723,12 +10777,12 @@ async function openBrowser(url) {
10723
10777
  }
10724
10778
  }
10725
10779
  function startDevServer(projectRoot) {
10726
- const packageJsonPath = resolve10(projectRoot, "package.json");
10727
- if (!existsSync19(packageJsonPath)) {
10780
+ const packageJsonPath = resolve11(projectRoot, "package.json");
10781
+ if (!existsSync20(packageJsonPath)) {
10728
10782
  throw new Error('package.json not found. Run "coherent init" first.');
10729
10783
  }
10730
- const hasPnpm = existsSync19(resolve10(projectRoot, "pnpm-lock.yaml"));
10731
- const hasNpm = existsSync19(resolve10(projectRoot, "package-lock.json"));
10784
+ const hasPnpm = existsSync20(resolve11(projectRoot, "pnpm-lock.yaml"));
10785
+ const hasNpm = existsSync20(resolve11(projectRoot, "package-lock.json"));
10732
10786
  const command = hasPnpm ? "pnpm" : hasNpm ? "npm" : "npx";
10733
10787
  const args = hasPnpm ? ["dev", "--turbo"] : hasNpm ? ["run", "dev", "--", "--turbo"] : ["next", "dev", "--turbo"];
10734
10788
  const child = spawn(command, args, {
@@ -10775,7 +10829,7 @@ async function previewCommand() {
10775
10829
  if (needsGlobalsFix(projectRoot)) {
10776
10830
  spinner.text = "Fixing globals.css...";
10777
10831
  try {
10778
- const dsm = new DesignSystemManager8(resolve10(projectRoot, "design-system.config.ts"));
10832
+ const dsm = new DesignSystemManager8(resolve11(projectRoot, "design-system.config.ts"));
10779
10833
  await dsm.load();
10780
10834
  const config2 = dsm.getConfig();
10781
10835
  fixGlobalsCss(projectRoot, config2);
@@ -10814,8 +10868,8 @@ async function previewCommand() {
10814
10868
  import chalk16 from "chalk";
10815
10869
  import ora4 from "ora";
10816
10870
  import { spawn as spawn2 } from "child_process";
10817
- import { existsSync as existsSync20, rmSync as rmSync4, readdirSync as readdirSync6 } from "fs";
10818
- import { resolve as resolve11, join as join15, dirname as dirname7 } from "path";
10871
+ import { existsSync as existsSync21, rmSync as rmSync4, readdirSync as readdirSync7 } from "fs";
10872
+ import { resolve as resolve12, join as join15, dirname as dirname7 } from "path";
10819
10873
  import { readdir as readdir3, readFile as readFile6, writeFile as writeFile5, mkdir as mkdir5, copyFile as copyFile2 } from "fs/promises";
10820
10874
  var COPY_EXCLUDE = /* @__PURE__ */ new Set([
10821
10875
  "node_modules",
@@ -10849,17 +10903,17 @@ async function copyDir(src, dest) {
10849
10903
  }
10850
10904
  }
10851
10905
  function checkProjectInitialized2(projectRoot) {
10852
- return existsSync20(resolve11(projectRoot, "design-system.config.ts")) && existsSync20(resolve11(projectRoot, "package.json"));
10906
+ return existsSync21(resolve12(projectRoot, "design-system.config.ts")) && existsSync21(resolve12(projectRoot, "package.json"));
10853
10907
  }
10854
10908
  function getPackageManager2(projectRoot) {
10855
- if (existsSync20(resolve11(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
10856
- if (existsSync20(resolve11(projectRoot, "package-lock.json"))) return "npm";
10909
+ if (existsSync21(resolve12(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
10910
+ if (existsSync21(resolve12(projectRoot, "package-lock.json"))) return "npm";
10857
10911
  return "npx";
10858
10912
  }
10859
10913
  async function patchNextConfigForExport(outRoot) {
10860
10914
  for (const name of ["next.config.ts", "next.config.mjs", "next.config.js"]) {
10861
10915
  const p = join15(outRoot, name);
10862
- if (!existsSync20(p)) continue;
10916
+ if (!existsSync21(p)) continue;
10863
10917
  let content = await readFile6(p, "utf-8");
10864
10918
  if (content.includes("ignoreDuringBuilds")) return;
10865
10919
  content = content.replace(
@@ -10874,9 +10928,9 @@ async function buildProduction(projectRoot) {
10874
10928
  const pm = getPackageManager2(projectRoot);
10875
10929
  const command = pm === "pnpm" ? "pnpm" : pm === "npm" ? "npm" : "npx";
10876
10930
  const args = pm === "npx" ? ["next", "build"] : ["run", "build"];
10877
- return new Promise((resolve16, reject) => {
10931
+ return new Promise((resolve17, reject) => {
10878
10932
  const child = spawn2(command, args, { cwd: projectRoot, stdio: "inherit", shell: true });
10879
- child.on("exit", (code) => code === 0 ? resolve16() : reject(new Error(`Build failed with exit code ${code}`)));
10933
+ child.on("exit", (code) => code === 0 ? resolve17() : reject(new Error(`Build failed with exit code ${code}`)));
10880
10934
  child.on("error", (error) => reject(new Error(`Failed to start build: ${error.message}`)));
10881
10935
  });
10882
10936
  }
@@ -10901,7 +10955,7 @@ EXPOSE 3000
10901
10955
  `;
10902
10956
  async function ensureReadmeDeploySection(outRoot) {
10903
10957
  const readmePath = join15(outRoot, "README.md");
10904
- if (!existsSync20(readmePath)) return;
10958
+ if (!existsSync21(readmePath)) return;
10905
10959
  try {
10906
10960
  let content = await readFile6(readmePath, "utf-8");
10907
10961
  if (/##\s+Deploy\b/m.test(content)) return;
@@ -10926,16 +10980,16 @@ async function countPages(outRoot) {
10926
10980
  }
10927
10981
  }
10928
10982
  const appDir = join15(outRoot, "app");
10929
- if (existsSync20(appDir)) await walk(appDir);
10983
+ if (existsSync21(appDir)) await walk(appDir);
10930
10984
  return n;
10931
10985
  }
10932
10986
  function countComponents(outRoot) {
10933
10987
  let n = 0;
10934
10988
  for (const sub of ["ui", "shared"]) {
10935
10989
  const dir = join15(outRoot, "components", sub);
10936
- if (!existsSync20(dir)) continue;
10990
+ if (!existsSync21(dir)) continue;
10937
10991
  try {
10938
- n += readdirSync6(dir).filter((f) => f.endsWith(".tsx") || f.endsWith(".jsx")).length;
10992
+ n += readdirSync7(dir).filter((f) => f.endsWith(".tsx") || f.endsWith(".jsx")).length;
10939
10993
  } catch {
10940
10994
  }
10941
10995
  }
@@ -10944,7 +10998,7 @@ function countComponents(outRoot) {
10944
10998
  var IMPORT_FROM_REGEX2 = /from\s+['"]([^'"]+)['"]/g;
10945
10999
  async function collectImportedPackages2(dir, extensions) {
10946
11000
  const packages = /* @__PURE__ */ new Set();
10947
- if (!existsSync20(dir)) return packages;
11001
+ if (!existsSync21(dir)) return packages;
10948
11002
  async function walk(d) {
10949
11003
  const entries = await readdir3(d, { withFileTypes: true });
10950
11004
  for (const e of entries) {
@@ -10972,7 +11026,7 @@ async function collectImportedPackages2(dir, extensions) {
10972
11026
  }
10973
11027
  async function findMissingDepsInExport(outRoot) {
10974
11028
  const pkgPath = join15(outRoot, "package.json");
10975
- if (!existsSync20(pkgPath)) return [];
11029
+ if (!existsSync21(pkgPath)) return [];
10976
11030
  let pkg;
10977
11031
  try {
10978
11032
  pkg = JSON.parse(await readFile6(pkgPath, "utf-8"));
@@ -10993,25 +11047,25 @@ async function stripCoherentArtifacts(outputDir) {
10993
11047
  const removed = [];
10994
11048
  for (const p of ["app/design-system", "app/api/design-system"]) {
10995
11049
  const full = join15(outputDir, p);
10996
- if (existsSync20(full)) {
11050
+ if (existsSync21(full)) {
10997
11051
  rmSync4(full, { recursive: true, force: true });
10998
11052
  removed.push(p);
10999
11053
  }
11000
11054
  }
11001
11055
  const appNavPath = join15(outputDir, "app", "AppNav.tsx");
11002
- if (existsSync20(appNavPath)) {
11056
+ if (existsSync21(appNavPath)) {
11003
11057
  rmSync4(appNavPath, { force: true });
11004
11058
  removed.push("app/AppNav.tsx");
11005
11059
  }
11006
11060
  const layoutPath = join15(outputDir, "app", "layout.tsx");
11007
- if (existsSync20(layoutPath)) {
11061
+ if (existsSync21(layoutPath)) {
11008
11062
  let layout = await readFile6(layoutPath, "utf-8");
11009
11063
  layout = layout.replace(/import\s*\{?\s*AppNav\s*\}?\s*from\s*['"][^'"]+['"]\s*\n?/g, "");
11010
11064
  layout = layout.replace(/\s*<AppNav\s*\/?\s*>\s*/g, "\n");
11011
11065
  await writeFile5(layoutPath, layout, "utf-8");
11012
11066
  }
11013
11067
  const sharedHeaderPath = join15(outputDir, "components", "shared", "header.tsx");
11014
- if (existsSync20(sharedHeaderPath)) {
11068
+ if (existsSync21(sharedHeaderPath)) {
11015
11069
  let header = await readFile6(sharedHeaderPath, "utf-8");
11016
11070
  header = header.replace(/<Link\s[^>]*href="\/design-system"[^>]*>[\s\S]*?<\/Link>/g, "");
11017
11071
  header = header.replace(/\n\s*<>\s*\n/, "\n");
@@ -11019,7 +11073,7 @@ async function stripCoherentArtifacts(outputDir) {
11019
11073
  await writeFile5(sharedHeaderPath, header, "utf-8");
11020
11074
  }
11021
11075
  const guardPath2 = join15(outputDir, "app", "ShowWhenNotAuthRoute.tsx");
11022
- if (existsSync20(guardPath2)) {
11076
+ if (existsSync21(guardPath2)) {
11023
11077
  let guard = await readFile6(guardPath2, "utf-8");
11024
11078
  guard = guard.replace(/['"],?\s*'\/design-system['"],?\s*/g, "");
11025
11079
  const pathsMatch = guard.match(/HIDDEN_PATHS\s*=\s*\[([^\]]*)\]/);
@@ -11027,7 +11081,7 @@ async function stripCoherentArtifacts(outputDir) {
11027
11081
  if (remaining.length === 0) {
11028
11082
  rmSync4(guardPath2, { force: true });
11029
11083
  removed.push("app/ShowWhenNotAuthRoute.tsx");
11030
- if (existsSync20(layoutPath)) {
11084
+ if (existsSync21(layoutPath)) {
11031
11085
  let layout = await readFile6(layoutPath, "utf-8");
11032
11086
  layout = layout.replace(/import\s+\w+\s+from\s*['"]\.\/ShowWhenNotAuthRoute['"]\s*\n?/g, "");
11033
11087
  layout = layout.replace(/\s*<ShowWhenNotAuthRoute>\s*\n?/g, "\n");
@@ -11048,14 +11102,14 @@ async function stripCoherentArtifacts(outputDir) {
11048
11102
  "recommendations.md"
11049
11103
  ]) {
11050
11104
  const full = join15(outputDir, name);
11051
- if (existsSync20(full)) {
11105
+ if (existsSync21(full)) {
11052
11106
  rmSync4(full, { force: true });
11053
11107
  removed.push(name);
11054
11108
  }
11055
11109
  }
11056
11110
  for (const dir of [".claude", ".coherent"]) {
11057
11111
  const full = join15(outputDir, dir);
11058
- if (existsSync20(full)) {
11112
+ if (existsSync21(full)) {
11059
11113
  rmSync4(full, { recursive: true, force: true });
11060
11114
  removed.push(dir + "/");
11061
11115
  }
@@ -11063,7 +11117,7 @@ async function stripCoherentArtifacts(outputDir) {
11063
11117
  return removed;
11064
11118
  }
11065
11119
  async function exportCommand(options = {}) {
11066
- const outputDir = resolve11(process.cwd(), options.output ?? "./export");
11120
+ const outputDir = resolve12(process.cwd(), options.output ?? "./export");
11067
11121
  const doBuild = options.build !== false;
11068
11122
  const keepDs = options.keepDs === true;
11069
11123
  const spinner = ora4("Preparing export...").start();
@@ -11079,7 +11133,7 @@ async function exportCommand(options = {}) {
11079
11133
  process.exit(1);
11080
11134
  }
11081
11135
  spinner.text = "Copying project...";
11082
- if (existsSync20(outputDir)) rmSync4(outputDir, { recursive: true, force: true });
11136
+ if (existsSync21(outputDir)) rmSync4(outputDir, { recursive: true, force: true });
11083
11137
  await copyDir(projectRoot, outputDir);
11084
11138
  spinner.succeed("Project copied");
11085
11139
  if (!keepDs) {
@@ -11254,8 +11308,8 @@ async function regenerateDocsCommand() {
11254
11308
 
11255
11309
  // src/commands/fix.ts
11256
11310
  import chalk19 from "chalk";
11257
- import { readdirSync as readdirSync7, readFileSync as readFileSync15, existsSync as existsSync21, writeFileSync as writeFileSync11, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
11258
- import { resolve as resolve12, join as join16 } from "path";
11311
+ import { readdirSync as readdirSync8, readFileSync as readFileSync16, existsSync as existsSync22, writeFileSync as writeFileSync11, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
11312
+ import { resolve as resolve13, join as join16 } from "path";
11259
11313
  import {
11260
11314
  DesignSystemManager as DesignSystemManager11,
11261
11315
  ComponentManager as ComponentManager6,
@@ -11279,7 +11333,7 @@ function extractComponentIdsFromCode2(code) {
11279
11333
  function listTsxFiles(dir) {
11280
11334
  const files = [];
11281
11335
  try {
11282
- const entries = readdirSync7(dir, { withFileTypes: true });
11336
+ const entries = readdirSync8(dir, { withFileTypes: true });
11283
11337
  for (const e of entries) {
11284
11338
  const full = join16(dir, e.name);
11285
11339
  if (e.isDirectory() && e.name !== "node_modules" && !e.name.startsWith(".")) {
@@ -11311,7 +11365,7 @@ async function fixCommand(opts = {}) {
11311
11365
  }
11312
11366
  if (!skipCache) {
11313
11367
  const nextDir = join16(projectRoot, ".next");
11314
- if (existsSync21(nextDir)) {
11368
+ if (existsSync22(nextDir)) {
11315
11369
  if (!dryRun) rmSync5(nextDir, { recursive: true, force: true });
11316
11370
  fixes.push("Cleared build cache");
11317
11371
  console.log(chalk19.green(" \u2714 Cleared build cache"));
@@ -11333,12 +11387,12 @@ async function fixCommand(opts = {}) {
11333
11387
  }
11334
11388
  }
11335
11389
  }
11336
- const appDir = resolve12(projectRoot, "app");
11390
+ const appDir = resolve13(projectRoot, "app");
11337
11391
  const allTsxFiles = listTsxFiles(appDir);
11338
- const componentsTsxFiles = listTsxFiles(resolve12(projectRoot, "components"));
11392
+ const componentsTsxFiles = listTsxFiles(resolve13(projectRoot, "components"));
11339
11393
  const allComponentIds = /* @__PURE__ */ new Set();
11340
11394
  for (const file of [...allTsxFiles, ...componentsTsxFiles]) {
11341
- const content = readFileSync15(file, "utf-8");
11395
+ const content = readFileSync16(file, "utf-8");
11342
11396
  extractComponentIdsFromCode2(content).forEach((id) => allComponentIds.add(id));
11343
11397
  }
11344
11398
  let dsm = null;
@@ -11357,8 +11411,8 @@ async function fixCommand(opts = {}) {
11357
11411
  missingComponents.push(id);
11358
11412
  } else {
11359
11413
  const fileName = toKebabCase(id) + ".tsx";
11360
- const filePath = resolve12(projectRoot, "components", "ui", fileName);
11361
- if (!existsSync21(filePath)) missingFiles.push(id);
11414
+ const filePath = resolve13(projectRoot, "components", "ui", fileName);
11415
+ if (!existsSync22(filePath)) missingFiles.push(id);
11362
11416
  }
11363
11417
  }
11364
11418
  const provider = getComponentProvider();
@@ -11387,8 +11441,8 @@ async function fixCommand(opts = {}) {
11387
11441
  const generator = new ComponentGenerator4(updatedConfig);
11388
11442
  const code = await generator.generate(component);
11389
11443
  const fileName = toKebabCase(component.name) + ".tsx";
11390
- const filePath = resolve12(projectRoot, "components", "ui", fileName);
11391
- mkdirSync7(resolve12(projectRoot, "components", "ui"), { recursive: true });
11444
+ const filePath = resolve13(projectRoot, "components", "ui", fileName);
11445
+ mkdirSync7(resolve13(projectRoot, "components", "ui"), { recursive: true });
11392
11446
  await writeFile(filePath, code);
11393
11447
  }
11394
11448
  }
@@ -11410,7 +11464,7 @@ async function fixCommand(opts = {}) {
11410
11464
  const userTsxFiles = allTsxFiles.filter((f) => !f.includes("/design-system/"));
11411
11465
  let syntaxFixed = 0;
11412
11466
  for (const file of userTsxFiles) {
11413
- const content = readFileSync15(file, "utf-8");
11467
+ const content = readFileSync16(file, "utf-8");
11414
11468
  const fixed = fixUnescapedLtInJsx(
11415
11469
  fixEscapedClosingQuotes(sanitizeMetadataStrings(ensureUseClientIfNeeded(content)))
11416
11470
  );
@@ -11428,7 +11482,7 @@ async function fixCommand(opts = {}) {
11428
11482
  let qualityFixCount = 0;
11429
11483
  const qualityFixDetails = [];
11430
11484
  for (const file of userTsxFiles) {
11431
- const content = readFileSync15(file, "utf-8");
11485
+ const content = readFileSync16(file, "utf-8");
11432
11486
  const { code: autoFixed, fixes: fileFixes } = await autoFixCode(content);
11433
11487
  if (autoFixed !== content) {
11434
11488
  if (!dryRun) writeFileSync11(file, autoFixed, "utf-8");
@@ -11447,7 +11501,7 @@ async function fixCommand(opts = {}) {
11447
11501
  let totalWarnings = 0;
11448
11502
  const fileIssues = [];
11449
11503
  for (const file of allTsxFiles) {
11450
- const code = dryRun ? readFileSync15(file, "utf-8") : readFileSync15(file, "utf-8");
11504
+ const code = dryRun ? readFileSync16(file, "utf-8") : readFileSync16(file, "utf-8");
11451
11505
  const relativePath = file.replace(projectRoot + "/", "");
11452
11506
  const baseName = file.split("/").pop() || "";
11453
11507
  const isAuthPage = relativePath.includes("(auth)");
@@ -11569,17 +11623,17 @@ async function fixCommand(opts = {}) {
11569
11623
 
11570
11624
  // src/commands/check.ts
11571
11625
  import chalk20 from "chalk";
11572
- import { resolve as resolve13 } from "path";
11573
- import { readdirSync as readdirSync8, readFileSync as readFileSync16, statSync as statSync2, existsSync as existsSync22 } from "fs";
11626
+ import { resolve as resolve14 } from "path";
11627
+ import { readdirSync as readdirSync9, readFileSync as readFileSync17, statSync as statSync3, existsSync as existsSync23 } from "fs";
11574
11628
  import { loadManifest as loadManifest11 } from "@getcoherent/core";
11575
11629
  var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", "design-system"]);
11576
11630
  function findTsxFiles(dir) {
11577
11631
  const results = [];
11578
11632
  try {
11579
- const entries = readdirSync8(dir);
11633
+ const entries = readdirSync9(dir);
11580
11634
  for (const entry of entries) {
11581
- const full = resolve13(dir, entry);
11582
- const stat = statSync2(full);
11635
+ const full = resolve14(dir, entry);
11636
+ const stat = statSync3(full);
11583
11637
  if (stat.isDirectory() && !entry.startsWith(".") && !EXCLUDED_DIRS.has(entry)) {
11584
11638
  results.push(...findTsxFiles(full));
11585
11639
  } else if (entry.endsWith(".tsx")) {
@@ -11613,7 +11667,7 @@ async function checkCommand(opts = {}) {
11613
11667
  } catch {
11614
11668
  }
11615
11669
  if (!skipPages) {
11616
- const appDir = resolve13(projectRoot, "app");
11670
+ const appDir = resolve14(projectRoot, "app");
11617
11671
  const files = findTsxFiles(appDir);
11618
11672
  result.pages.total = files.length;
11619
11673
  if (!opts.json) console.log(chalk20.cyan("\n \u{1F4C4} Pages") + chalk20.dim(` (${files.length} scanned)
@@ -11627,7 +11681,7 @@ async function checkCommand(opts = {}) {
11627
11681
  "NATIVE_TABLE"
11628
11682
  ]);
11629
11683
  for (const file of files) {
11630
- const code = readFileSync16(file, "utf-8");
11684
+ const code = readFileSync17(file, "utf-8");
11631
11685
  const relativePath = file.replace(projectRoot + "/", "");
11632
11686
  const baseName = file.split("/").pop() || "";
11633
11687
  const isAuthPage = relativePath.includes("(auth)");
@@ -11669,7 +11723,7 @@ async function checkCommand(opts = {}) {
11669
11723
  routeSet.add("/");
11670
11724
  routeSet.add("#");
11671
11725
  for (const file of files) {
11672
- const code = readFileSync16(file, "utf-8");
11726
+ const code = readFileSync17(file, "utf-8");
11673
11727
  const relativePath = file.replace(projectRoot + "/", "");
11674
11728
  const lines = code.split("\n");
11675
11729
  const linkHrefRe = /href\s*=\s*["'](\/[a-z0-9/-]*)["']/gi;
@@ -11701,8 +11755,8 @@ async function checkCommand(opts = {}) {
11701
11755
  const manifest = await loadManifest11(project.root);
11702
11756
  if (manifest.shared.length > 0) {
11703
11757
  for (const entry of manifest.shared) {
11704
- const fullPath = resolve13(project.root, entry.file);
11705
- if (!existsSync22(fullPath)) {
11758
+ const fullPath = resolve14(project.root, entry.file);
11759
+ if (!existsSync23(fullPath)) {
11706
11760
  result.pages.withErrors++;
11707
11761
  if (!opts.json) console.log(chalk20.red(`
11708
11762
  \u2717 Missing shared component file: ${entry.id} (${entry.file})`));
@@ -11726,8 +11780,8 @@ async function checkCommand(opts = {}) {
11726
11780
  let _staleUsedIn = 0;
11727
11781
  let _nameMismatch = 0;
11728
11782
  for (const entry of manifest.shared) {
11729
- const filePath = resolve13(projectRoot, entry.file);
11730
- const fileExists = existsSync22(filePath);
11783
+ const filePath = resolve14(projectRoot, entry.file);
11784
+ const fileExists = existsSync23(filePath);
11731
11785
  if (!fileExists) {
11732
11786
  _orphaned++;
11733
11787
  if (!opts.json) {
@@ -11737,7 +11791,7 @@ async function checkCommand(opts = {}) {
11737
11791
  continue;
11738
11792
  }
11739
11793
  try {
11740
- const code = readFileSync16(filePath, "utf-8");
11794
+ const code = readFileSync17(filePath, "utf-8");
11741
11795
  const actualExports = extractExportedComponentNames(code);
11742
11796
  if (actualExports.length > 0 && !actualExports.includes(entry.name)) {
11743
11797
  _nameMismatch++;
@@ -11805,7 +11859,7 @@ async function checkCommand(opts = {}) {
11805
11859
  id: e.id,
11806
11860
  name: e.name,
11807
11861
  type: e.type,
11808
- status: existsSync22(resolve13(projectRoot, e.file)) ? "ok" : "unused",
11862
+ status: existsSync23(resolve14(projectRoot, e.file)) ? "ok" : "unused",
11809
11863
  message: "",
11810
11864
  suggestions: void 0
11811
11865
  }))
@@ -11900,8 +11954,8 @@ import {
11900
11954
  generateSharedComponent as generateSharedComponent5,
11901
11955
  integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout3
11902
11956
  } from "@getcoherent/core";
11903
- import { existsSync as existsSync23 } from "fs";
11904
- import { resolve as resolve14 } from "path";
11957
+ import { existsSync as existsSync24 } from "fs";
11958
+ import { resolve as resolve15 } from "path";
11905
11959
 
11906
11960
  // src/utils/ds-files.ts
11907
11961
  import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
@@ -12031,8 +12085,8 @@ function createComponentsCommand() {
12031
12085
  const updated = await integrateSharedLayoutIntoRootLayout3(project.root);
12032
12086
  if (updated) console.log(chalk26.cyan(" Updated app/layout.tsx to use shared layout components.\n"));
12033
12087
  }
12034
- const sharedPagePath = resolve14(project.root, "app/design-system/shared/page.tsx");
12035
- if (!existsSync23(sharedPagePath)) {
12088
+ const sharedPagePath = resolve15(project.root, "app/design-system/shared/page.tsx");
12089
+ if (!existsSync24(sharedPagePath)) {
12036
12090
  try {
12037
12091
  const dsm = new DesignSystemManager12(project.configPath);
12038
12092
  await dsm.load();
@@ -12058,8 +12112,8 @@ function createComponentsCommand() {
12058
12112
  import chalk27 from "chalk";
12059
12113
  import ora6 from "ora";
12060
12114
  import { writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
12061
- import { resolve as resolve15, join as join18, dirname as dirname9 } from "path";
12062
- import { existsSync as existsSync24 } from "fs";
12115
+ import { resolve as resolve16, join as join18, dirname as dirname9 } from "path";
12116
+ import { existsSync as existsSync25 } from "fs";
12063
12117
  import {
12064
12118
  FigmaClient,
12065
12119
  parseFigmaFileResponse,
@@ -12283,7 +12337,7 @@ async function importFigmaAction(urlOrKey, opts) {
12283
12337
  if (dryRun) stats.filesWritten.push(FIGMA_COMPONENT_MAP_FILENAME);
12284
12338
  else
12285
12339
  await writeFile7(
12286
- resolve15(projectRoot, FIGMA_COMPONENT_MAP_FILENAME),
12340
+ resolve16(projectRoot, FIGMA_COMPONENT_MAP_FILENAME),
12287
12341
  JSON.stringify(componentMapObj, null, 2),
12288
12342
  "utf-8"
12289
12343
  );
@@ -12306,9 +12360,9 @@ async function importFigmaAction(urlOrKey, opts) {
12306
12360
  const fullConfig = buildFigmaImportConfig(mergedConfig, pageDefs, intermediate.fileName);
12307
12361
  if (!dryRun) {
12308
12362
  spinner.start("Updating design-system.config.ts...");
12309
- const configPath = resolve15(projectRoot, DESIGN_SYSTEM_CONFIG_PATH);
12363
+ const configPath = resolve16(projectRoot, DESIGN_SYSTEM_CONFIG_PATH);
12310
12364
  const dsm = new DesignSystemManager13(configPath);
12311
- if (existsSync24(configPath)) {
12365
+ if (existsSync25(configPath)) {
12312
12366
  await dsm.load();
12313
12367
  const existing = dsm.getConfig();
12314
12368
  dsm.updateConfig({
@@ -12338,7 +12392,7 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
12338
12392
  spinner.succeed("design-system.config.ts updated");
12339
12393
  spinner.start("Ensuring root layout...");
12340
12394
  const layoutPath = join18(projectRoot, "app/layout.tsx");
12341
- if (!existsSync24(layoutPath)) {
12395
+ if (!existsSync25(layoutPath)) {
12342
12396
  await mkdir7(dirname9(layoutPath), { recursive: true });
12343
12397
  await writeFile7(layoutPath, MINIMAL_ROOT_LAYOUT, "utf-8");
12344
12398
  stats.filesWritten.push("app/layout.tsx");
@@ -12428,7 +12482,7 @@ async function dsRegenerateCommand() {
12428
12482
  // src/commands/update.ts
12429
12483
  import chalk29 from "chalk";
12430
12484
  import ora8 from "ora";
12431
- import { readFileSync as readFileSync17, existsSync as existsSync25 } from "fs";
12485
+ import { readFileSync as readFileSync18, existsSync as existsSync26 } from "fs";
12432
12486
  import { join as join19 } from "path";
12433
12487
  import { DesignSystemManager as DesignSystemManager15, CLI_VERSION as CLI_VERSION4 } from "@getcoherent/core";
12434
12488
 
@@ -12599,9 +12653,9 @@ var EXPECTED_CSS_VARS = [
12599
12653
  ];
12600
12654
  function checkMissingCssVars(projectRoot) {
12601
12655
  const globalsPath = join19(projectRoot, "app", "globals.css");
12602
- if (!existsSync25(globalsPath)) return [];
12656
+ if (!existsSync26(globalsPath)) return [];
12603
12657
  try {
12604
- const content = readFileSync17(globalsPath, "utf-8");
12658
+ const content = readFileSync18(globalsPath, "utf-8");
12605
12659
  return EXPECTED_CSS_VARS.filter((v) => !content.includes(v));
12606
12660
  } catch {
12607
12661
  return [];
@@ -12609,9 +12663,9 @@ function checkMissingCssVars(projectRoot) {
12609
12663
  }
12610
12664
  function patchGlobalsCss(projectRoot, missingVars) {
12611
12665
  const globalsPath = join19(projectRoot, "app", "globals.css");
12612
- if (!existsSync25(globalsPath) || missingVars.length === 0) return;
12666
+ if (!existsSync26(globalsPath) || missingVars.length === 0) return;
12613
12667
  const { writeFileSync: writeFileSync14 } = __require("fs");
12614
- let content = readFileSync17(globalsPath, "utf-8");
12668
+ let content = readFileSync18(globalsPath, "utf-8");
12615
12669
  const defaultValues = {
12616
12670
  "--chart-1": "220 70% 50%",
12617
12671
  "--chart-2": "160 60% 45%",
@@ -12689,7 +12743,7 @@ async function undoCommand(options) {
12689
12743
  // src/commands/sync.ts
12690
12744
  import chalk31 from "chalk";
12691
12745
  import ora9 from "ora";
12692
- import { existsSync as existsSync26, readFileSync as readFileSync18 } from "fs";
12746
+ import { existsSync as existsSync27, readFileSync as readFileSync19 } from "fs";
12693
12747
  import { join as join20, relative as relative5, dirname as dirname10 } from "path";
12694
12748
  import { readdir as readdir4, readFile as readFile7 } from "fs/promises";
12695
12749
  import { DesignSystemManager as DesignSystemManager16 } from "@getcoherent/core";
@@ -12698,8 +12752,8 @@ function extractTokensFromProject(projectRoot) {
12698
12752
  const lightColors = {};
12699
12753
  const darkColors = {};
12700
12754
  const globalsPath = join20(projectRoot, "app", "globals.css");
12701
- if (existsSync26(globalsPath)) {
12702
- const css = readFileSync18(globalsPath, "utf-8");
12755
+ if (existsSync27(globalsPath)) {
12756
+ const css = readFileSync19(globalsPath, "utf-8");
12703
12757
  const rootMatch = css.match(/:root\s*\{([^}]+)\}/s);
12704
12758
  if (rootMatch) parseVarsInto(rootMatch[1], lightColors);
12705
12759
  const darkMatch = css.match(/\.dark\s*\{([^}]+)\}/s);
@@ -12707,8 +12761,8 @@ function extractTokensFromProject(projectRoot) {
12707
12761
  }
12708
12762
  const layoutPath = join20(projectRoot, "app", "layout.tsx");
12709
12763
  let layoutCode = "";
12710
- if (existsSync26(layoutPath)) {
12711
- layoutCode = readFileSync18(layoutPath, "utf-8");
12764
+ if (existsSync27(layoutPath)) {
12765
+ layoutCode = readFileSync19(layoutPath, "utf-8");
12712
12766
  const rootInline = layoutCode.match(/:root\s*\{([^}]+)\}/s);
12713
12767
  if (rootInline && Object.keys(lightColors).length === 0) {
12714
12768
  parseVarsInto(rootInline[1], lightColors);
@@ -12726,7 +12780,7 @@ function extractTokensFromProject(projectRoot) {
12726
12780
  defaultMode = "dark";
12727
12781
  }
12728
12782
  let radius;
12729
- const allCss = [existsSync26(globalsPath) ? readFileSync18(globalsPath, "utf-8") : "", layoutCode].join("\n");
12783
+ const allCss = [existsSync27(globalsPath) ? readFileSync19(globalsPath, "utf-8") : "", layoutCode].join("\n");
12730
12784
  const radiusMatch = allCss.match(/--radius:\s*([^;]+);/);
12731
12785
  if (radiusMatch) radius = radiusMatch[1].trim();
12732
12786
  return {
@@ -12750,7 +12804,7 @@ function parseVarsInto(block, target) {
12750
12804
  async function detectCustomComponents(projectRoot, allPageCode) {
12751
12805
  const results = [];
12752
12806
  const componentsDir = join20(projectRoot, "components");
12753
- if (!existsSync26(componentsDir)) return results;
12807
+ if (!existsSync27(componentsDir)) return results;
12754
12808
  const files = [];
12755
12809
  await walkForTsx(componentsDir, files, ["ui"]);
12756
12810
  const fileResults = await Promise.all(
@@ -12929,7 +12983,7 @@ async function syncCommand(options = {}) {
12929
12983
  const spinner = ora9("Scanning project files...").start();
12930
12984
  try {
12931
12985
  const appDir = join20(project.root, "app");
12932
- if (!existsSync26(appDir)) {
12986
+ if (!existsSync27(appDir)) {
12933
12987
  spinner.fail("No app/ directory found");
12934
12988
  process.exit(1);
12935
12989
  }
@@ -13156,7 +13210,7 @@ async function syncCommand(options = {}) {
13156
13210
  // src/commands/migrate.ts
13157
13211
  import chalk32 from "chalk";
13158
13212
  import ora10 from "ora";
13159
- import { existsSync as existsSync27, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync12, readFileSync as readFileSync19, readdirSync as readdirSync9 } from "fs";
13213
+ import { existsSync as existsSync28, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync12, readFileSync as readFileSync20, readdirSync as readdirSync10 } from "fs";
13160
13214
  import { join as join21 } from "path";
13161
13215
  function backupDir(projectRoot) {
13162
13216
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -13169,11 +13223,11 @@ function createBackup2(projectRoot) {
13169
13223
  const uiDir = join21(projectRoot, "components", "ui");
13170
13224
  const dest = backupDir(projectRoot);
13171
13225
  mkdirSync8(dest, { recursive: true });
13172
- if (existsSync27(uiDir)) {
13226
+ if (existsSync28(uiDir)) {
13173
13227
  cpSync(uiDir, join21(dest, "components-ui"), { recursive: true });
13174
13228
  }
13175
13229
  const configPath = join21(projectRoot, "design-system.config.ts");
13176
- if (existsSync27(configPath)) {
13230
+ if (existsSync28(configPath)) {
13177
13231
  cpSync(configPath, join21(dest, "design-system.config.ts"));
13178
13232
  }
13179
13233
  return dest;
@@ -13185,24 +13239,24 @@ function setGuard(projectRoot, backupPath) {
13185
13239
  }
13186
13240
  function clearGuard(projectRoot) {
13187
13241
  const guard = guardPath(projectRoot);
13188
- if (existsSync27(guard)) rmSync6(guard);
13242
+ if (existsSync28(guard)) rmSync6(guard);
13189
13243
  }
13190
13244
  function rollback(projectRoot) {
13191
13245
  const guard = guardPath(projectRoot);
13192
- if (!existsSync27(guard)) return false;
13246
+ if (!existsSync28(guard)) return false;
13193
13247
  try {
13194
- const data = JSON.parse(readFileSync19(guard, "utf-8"));
13248
+ const data = JSON.parse(readFileSync20(guard, "utf-8"));
13195
13249
  const backup = data.backup;
13196
- if (!existsSync27(backup)) return false;
13250
+ if (!existsSync28(backup)) return false;
13197
13251
  const uiBackup = join21(backup, "components-ui");
13198
13252
  const uiDir = join21(projectRoot, "components", "ui");
13199
- if (existsSync27(uiBackup)) {
13200
- if (existsSync27(uiDir)) rmSync6(uiDir, { recursive: true });
13253
+ if (existsSync28(uiBackup)) {
13254
+ if (existsSync28(uiDir)) rmSync6(uiDir, { recursive: true });
13201
13255
  cpSync(uiBackup, uiDir, { recursive: true });
13202
13256
  }
13203
13257
  const configBackup = join21(backup, "design-system.config.ts");
13204
13258
  const configDest = join21(projectRoot, "design-system.config.ts");
13205
- if (existsSync27(configBackup)) {
13259
+ if (existsSync28(configBackup)) {
13206
13260
  cpSync(configBackup, configDest);
13207
13261
  }
13208
13262
  clearGuard(projectRoot);
@@ -13230,19 +13284,19 @@ async function migrateAction(options) {
13230
13284
  return;
13231
13285
  }
13232
13286
  const guard = guardPath(projectRoot);
13233
- if (existsSync27(guard)) {
13287
+ if (existsSync28(guard)) {
13234
13288
  console.log(chalk32.yellow("A migration is already in progress."));
13235
13289
  console.log(chalk32.dim("Run `coherent migrate --rollback` to undo, or delete .coherent/migration-in-progress"));
13236
13290
  return;
13237
13291
  }
13238
13292
  const uiDir = join21(projectRoot, "components", "ui");
13239
- if (!existsSync27(uiDir)) {
13293
+ if (!existsSync28(uiDir)) {
13240
13294
  console.log(chalk32.yellow("No components/ui directory found. Nothing to migrate."));
13241
13295
  return;
13242
13296
  }
13243
13297
  const provider = getComponentProvider();
13244
13298
  const managedIds = new Set(provider.listNames());
13245
- const files = readdirSync9(uiDir).filter((f) => f.endsWith(".tsx"));
13299
+ const files = readdirSync10(uiDir).filter((f) => f.endsWith(".tsx"));
13246
13300
  const migratable = files.map((f) => f.replace(".tsx", "")).filter((id) => managedIds.has(id));
13247
13301
  if (migratable.length === 0) {
13248
13302
  console.log(chalk32.green("All components are already up to date."));
@@ -13263,7 +13317,7 @@ Found ${migratable.length} component(s) to migrate:`));
13263
13317
  try {
13264
13318
  for (const id of migratable) {
13265
13319
  const filePath = join21(uiDir, `${id}.tsx`);
13266
- if (existsSync27(filePath)) rmSync6(filePath);
13320
+ if (existsSync28(filePath)) rmSync6(filePath);
13267
13321
  }
13268
13322
  const results = await provider.installBatch(migratable, projectRoot, { force: true });
13269
13323
  let migrated = 0;
@@ -13285,7 +13339,7 @@ Found ${migratable.length} component(s) to migrate:`));
13285
13339
  }
13286
13340
 
13287
13341
  // src/utils/update-notifier.ts
13288
- import { existsSync as existsSync28, mkdirSync as mkdirSync9, readFileSync as readFileSync20, writeFileSync as writeFileSync13 } from "fs";
13342
+ import { existsSync as existsSync29, mkdirSync as mkdirSync9, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "fs";
13289
13343
  import { join as join22 } from "path";
13290
13344
  import { homedir } from "os";
13291
13345
  import chalk33 from "chalk";
@@ -13297,8 +13351,8 @@ var CACHE_FILE = join22(CACHE_DIR, "update-check.json");
13297
13351
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
13298
13352
  function readCache() {
13299
13353
  try {
13300
- if (!existsSync28(CACHE_FILE)) return null;
13301
- const raw = readFileSync20(CACHE_FILE, "utf-8");
13354
+ if (!existsSync29(CACHE_FILE)) return null;
13355
+ const raw = readFileSync21(CACHE_FILE, "utf-8");
13302
13356
  return JSON.parse(raw);
13303
13357
  } catch (e) {
13304
13358
  if (DEBUG5) console.error("Failed to read update cache:", e);
@@ -13307,7 +13361,7 @@ function readCache() {
13307
13361
  }
13308
13362
  function writeCache(data) {
13309
13363
  try {
13310
- if (!existsSync28(CACHE_DIR)) mkdirSync9(CACHE_DIR, { recursive: true });
13364
+ if (!existsSync29(CACHE_DIR)) mkdirSync9(CACHE_DIR, { recursive: true });
13311
13365
  writeFileSync13(CACHE_FILE, JSON.stringify(data), "utf-8");
13312
13366
  } catch (e) {
13313
13367
  if (DEBUG5) console.error("Failed to write update cache:", e);