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