@getcoherent/cli 0.6.25 → 0.6.26

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
@@ -2,21 +2,24 @@ import {
2
2
  createAIProvider
3
3
  } from "./chunk-SPQZBQYY.js";
4
4
  import {
5
- autoFixCode,
6
- checkDesignConsistency,
7
- formatIssues,
8
- validatePageQuality,
9
- verifyIncrementalEdit
10
- } from "./chunk-H644LLXJ.js";
11
- import {
5
+ COHERENT_REQUIRED_PACKAGES,
6
+ ensureUseClientIfNeeded,
7
+ extractNpmPackagesFromCode,
8
+ findMissingPackages,
9
+ findMissingPackagesInCode,
10
+ fixEscapedClosingQuotes,
11
+ fixUnescapedLtInJsx,
12
12
  generateArchitecturePlan,
13
+ getInstalledPackages,
13
14
  getPageGroup,
14
15
  getPageType,
16
+ installPackages,
15
17
  loadPlan,
16
18
  routeToKey,
19
+ sanitizeMetadataStrings,
17
20
  savePlan,
18
21
  updateArchitecturePlan
19
- } from "./chunk-IYLHC4RC.js";
22
+ } from "./chunk-CC3ARMGS.js";
20
23
  import {
21
24
  CORE_CONSTRAINTS,
22
25
  DESIGN_QUALITY,
@@ -28,6 +31,13 @@ import {
28
31
  inferPageTypeFromRoute,
29
32
  selectContextualRules
30
33
  } from "./chunk-5AHG4NNX.js";
34
+ import {
35
+ autoFixCode,
36
+ checkDesignConsistency,
37
+ formatIssues,
38
+ validatePageQuality,
39
+ verifyIncrementalEdit
40
+ } from "./chunk-H644LLXJ.js";
31
41
  import {
32
42
  __require
33
43
  } from "./chunk-3RG5ZIWI.js";
@@ -41,9 +51,9 @@ import { CLI_VERSION as CLI_VERSION6 } from "@getcoherent/core";
41
51
  import chalk4 from "chalk";
42
52
  import ora from "ora";
43
53
  import prompts2 from "prompts";
44
- import { existsSync as existsSync8, readFileSync as readFileSync5, mkdirSync as mkdirSync3, rmSync, writeFileSync as writeFileSync5 } from "fs";
45
- import { join as join6 } from "path";
46
- import { execSync as execSync2 } from "child_process";
54
+ import { existsSync as existsSync7, readFileSync as readFileSync4, mkdirSync as mkdirSync3, rmSync, writeFileSync as writeFileSync5 } from "fs";
55
+ import { join as join5 } from "path";
56
+ import { execSync } from "child_process";
47
57
 
48
58
  // src/utils/find-config.ts
49
59
  import { existsSync } from "fs";
@@ -1803,222 +1813,6 @@ function formatTimeAgo(iso) {
1803
1813
  return date.toLocaleDateString();
1804
1814
  }
1805
1815
 
1806
- // src/utils/self-heal.ts
1807
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
1808
- import { join as join3 } from "path";
1809
- import { readdir, readFile as readFile2 } from "fs/promises";
1810
- import { execSync } from "child_process";
1811
- var COHERENT_REQUIRED_PACKAGES = [
1812
- "lucide-react",
1813
- "class-variance-authority",
1814
- "clsx",
1815
- "tailwind-merge",
1816
- "@radix-ui/react-slot"
1817
- ];
1818
- var IMPORT_FROM_REGEX = /from\s+['"]([^'"]+)['"]/g;
1819
- var NODE_BUILTINS = /* @__PURE__ */ new Set([
1820
- "assert",
1821
- "async_hooks",
1822
- "buffer",
1823
- "child_process",
1824
- "cluster",
1825
- "console",
1826
- "constants",
1827
- "crypto",
1828
- "dgram",
1829
- "diagnostics_channel",
1830
- "dns",
1831
- "domain",
1832
- "events",
1833
- "fs",
1834
- "http",
1835
- "http2",
1836
- "https",
1837
- "inspector",
1838
- "module",
1839
- "net",
1840
- "os",
1841
- "path",
1842
- "perf_hooks",
1843
- "process",
1844
- "punycode",
1845
- "querystring",
1846
- "readline",
1847
- "repl",
1848
- "stream",
1849
- "string_decoder",
1850
- "sys",
1851
- "test",
1852
- "timers",
1853
- "tls",
1854
- "trace_events",
1855
- "tty",
1856
- "url",
1857
- "util",
1858
- "v8",
1859
- "vm",
1860
- "wasi",
1861
- "worker_threads",
1862
- "zlib",
1863
- "fs/promises",
1864
- "path/posix",
1865
- "path/win32",
1866
- "stream/promises",
1867
- "stream/web",
1868
- "timers/promises",
1869
- "util/types"
1870
- ]);
1871
- function extractNpmPackagesFromCode(code) {
1872
- if (typeof code !== "string") return /* @__PURE__ */ new Set();
1873
- const pkgs = /* @__PURE__ */ new Set();
1874
- let m;
1875
- IMPORT_FROM_REGEX.lastIndex = 0;
1876
- while ((m = IMPORT_FROM_REGEX.exec(code)) !== null) {
1877
- const spec = m[1];
1878
- if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("@/") || spec === "next") continue;
1879
- if (spec.startsWith("node:") || NODE_BUILTINS.has(spec)) continue;
1880
- const pkg = spec.startsWith("@") ? spec.split("/").slice(0, 2).join("/") : spec.split("/")[0];
1881
- if (pkg && !NODE_BUILTINS.has(pkg)) pkgs.add(pkg);
1882
- }
1883
- return pkgs;
1884
- }
1885
- function getInstalledPackages(projectRoot) {
1886
- const pkgPath = join3(projectRoot, "package.json");
1887
- if (!existsSync4(pkgPath)) return /* @__PURE__ */ new Set();
1888
- try {
1889
- const json = JSON.parse(readFileSync3(pkgPath, "utf-8"));
1890
- const deps = { ...json.dependencies ?? {}, ...json.devDependencies ?? {} };
1891
- return new Set(Object.keys(deps));
1892
- } catch (e) {
1893
- if (process.env.COHERENT_DEBUG === "1") console.error("Failed to read package.json:", e);
1894
- return /* @__PURE__ */ new Set();
1895
- }
1896
- }
1897
- async function collectImportedPackages(dir, extensions) {
1898
- const packages = /* @__PURE__ */ new Set();
1899
- if (!existsSync4(dir)) return packages;
1900
- async function walk(d) {
1901
- let entries;
1902
- try {
1903
- entries = await readdir(d, { withFileTypes: true });
1904
- } catch {
1905
- return;
1906
- }
1907
- for (const e of entries) {
1908
- const full = join3(d, e.name);
1909
- if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules") {
1910
- await walk(full);
1911
- continue;
1912
- }
1913
- if (!e.isFile()) continue;
1914
- const ext = e.name.replace(/^.*\./, "");
1915
- if (!extensions.has(ext)) continue;
1916
- const content = await readFile2(full, "utf-8").catch(() => "");
1917
- extractNpmPackagesFromCode(content).forEach((p) => packages.add(p));
1918
- }
1919
- }
1920
- await walk(dir);
1921
- return packages;
1922
- }
1923
- async function findMissingPackages(projectRoot, dirs = ["app", "components"]) {
1924
- const installed = getInstalledPackages(projectRoot);
1925
- const required = new Set(COHERENT_REQUIRED_PACKAGES);
1926
- const imported = /* @__PURE__ */ new Set();
1927
- const extensions = /* @__PURE__ */ new Set(["ts", "tsx", "js", "jsx"]);
1928
- for (const d of dirs) {
1929
- const abs = join3(projectRoot, d);
1930
- const pkgs = await collectImportedPackages(abs, extensions);
1931
- pkgs.forEach((p) => imported.add(p));
1932
- }
1933
- const needed = /* @__PURE__ */ new Set([...required, ...imported]);
1934
- return [...needed].filter((p) => !installed.has(p)).sort();
1935
- }
1936
- function findMissingPackagesInCode(code, projectRoot) {
1937
- const installed = getInstalledPackages(projectRoot);
1938
- const required = new Set(COHERENT_REQUIRED_PACKAGES);
1939
- const fromCode = extractNpmPackagesFromCode(code);
1940
- const needed = /* @__PURE__ */ new Set([...required, ...fromCode]);
1941
- return [...needed].filter((p) => !installed.has(p)).sort();
1942
- }
1943
- var SAFE_PKG_NAME = /^(@[a-z0-9._-]+\/)?[a-z0-9._-]+$/;
1944
- function installPackages(projectRoot, packages) {
1945
- if (packages.length === 0) return Promise.resolve(true);
1946
- const safe = packages.filter((p) => SAFE_PKG_NAME.test(p));
1947
- if (safe.length === 0) return Promise.resolve(true);
1948
- return new Promise((resolve17) => {
1949
- try {
1950
- const hasPnpm = existsSync4(join3(projectRoot, "pnpm-lock.yaml"));
1951
- if (hasPnpm) {
1952
- execSync(`pnpm add ${safe.join(" ")}`, { cwd: projectRoot, stdio: "pipe" });
1953
- } else {
1954
- execSync(`npm install --legacy-peer-deps ${safe.join(" ")}`, {
1955
- cwd: projectRoot,
1956
- stdio: "pipe"
1957
- });
1958
- }
1959
- resolve17(true);
1960
- } catch (e) {
1961
- if (process.env.COHERENT_DEBUG === "1") console.error("Failed to install packages:", e);
1962
- resolve17(false);
1963
- }
1964
- });
1965
- }
1966
- var CLIENT_HOOKS = /\b(useState|useEffect|useRef|useContext|useReducer|useCallback|useMemo|useId|useTransition|useDeferredValue)\s*\(/;
1967
- var CLIENT_EVENTS = /\b(onClick|onChange|onSubmit|onBlur|onFocus|onKeyDown|onKeyUp|onMouseEnter|onMouseLeave|onScroll|onInput)\s*[={]/;
1968
- function stripMetadataFromCode(code) {
1969
- const match = code.match(/\bexport\s+const\s+metadata\s*:\s*Metadata\s*=\s*\{/);
1970
- if (!match) return code;
1971
- const start = code.indexOf(match[0]);
1972
- const open = code.indexOf("{", start);
1973
- if (open === -1) return code;
1974
- let depth = 1;
1975
- let i = open + 1;
1976
- while (i < code.length && depth > 0) {
1977
- const c = code[i];
1978
- if (c === "{") depth++;
1979
- else if (c === "}") depth--;
1980
- i++;
1981
- }
1982
- const end = i;
1983
- const tail = code.slice(end);
1984
- const semicolon = tail.match(/^\s*;/);
1985
- const removeEnd = semicolon ? end + (semicolon.index + semicolon[0].length) : end;
1986
- return (code.slice(0, start) + code.slice(removeEnd)).replace(/\n{3,}/g, "\n\n").trim();
1987
- }
1988
- function ensureUseClientIfNeeded(code) {
1989
- const trimmed = code.trimStart();
1990
- const hasUseClient = trimmed.startsWith("'use client'") || trimmed.startsWith('"use client"');
1991
- const needsUseClient = CLIENT_HOOKS.test(code) || CLIENT_EVENTS.test(code);
1992
- let out = code;
1993
- if (hasUseClient || needsUseClient) {
1994
- out = stripMetadataFromCode(out);
1995
- if (needsUseClient && !hasUseClient) out = `'use client'
1996
-
1997
- ${out}`;
1998
- }
1999
- return out;
2000
- }
2001
- function sanitizeMetadataStrings(code) {
2002
- let out = code.replace(/\\'(\s*[}\],])/g, "'$1");
2003
- out = out.replace(/(:\s*'.+)\\'(\s*)$/gm, "$1'$2");
2004
- for (const key of ["description", "title"]) {
2005
- const re = new RegExp(`\\b${key}:\\s*'((?:[^'\\\\]|'(?![,}]))*)'`, "gs");
2006
- out = out.replace(re, (_, inner) => `${key}: '${inner.replace(/'/g, "\\'")}'`);
2007
- }
2008
- return out;
2009
- }
2010
- function fixEscapedClosingQuotes(code) {
2011
- let out = code.replace(/\\'(\s*[}\],])/g, "'$1");
2012
- out = out.replace(/(:\s*'.+)\\'(\s*)$/gm, "$1'$2");
2013
- return out;
2014
- }
2015
- function fixUnescapedLtInJsx(code) {
2016
- let out = code;
2017
- out = out.replace(/>([^<\n]*)<(\d)/g, ">$1&lt;$2");
2018
- out = out.replace(/>([^<\n]*)<([^/a-zA-Z!{>\n])/g, ">$1&lt;$2");
2019
- return out;
2020
- }
2021
-
2022
1816
  // src/utils/welcome-content.ts
2023
1817
  import fs from "fs";
2024
1818
  import path2 from "path";
@@ -2453,14 +2247,14 @@ function hasApiKey() {
2453
2247
  }
2454
2248
 
2455
2249
  // src/utils/cursor-rules.ts
2456
- import { writeFileSync as writeFileSync4, existsSync as existsSync6 } from "fs";
2457
- import { join as join5 } from "path";
2250
+ import { writeFileSync as writeFileSync4, existsSync as existsSync5 } from "fs";
2251
+ import { join as join4 } from "path";
2458
2252
  import { loadManifest as loadManifest2 } from "@getcoherent/core";
2459
2253
  import { DesignSystemManager as DesignSystemManager2 } from "@getcoherent/core";
2460
2254
 
2461
2255
  // src/utils/claude-code.ts
2462
- import { writeFileSync as writeFileSync3, existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
2463
- import { join as join4 } from "path";
2256
+ import { writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync2 } from "fs";
2257
+ import { join as join3 } from "path";
2464
2258
  import { loadManifest } from "@getcoherent/core";
2465
2259
  import { DesignSystemManager } from "@getcoherent/core";
2466
2260
  function buildSharedComponentsListForClaude(manifest) {
@@ -2905,28 +2699,28 @@ var SETTINGS_JSON = `{
2905
2699
  `;
2906
2700
  function writeClaudeMd(projectRoot, manifest, config2) {
2907
2701
  const content = buildClaudeMdContent(manifest, config2);
2908
- const outPath = join4(projectRoot, "CLAUDE.md");
2702
+ const outPath = join3(projectRoot, "CLAUDE.md");
2909
2703
  writeFileSync3(outPath, content, "utf-8");
2910
2704
  }
2911
2705
  function writeClaudeCommands(projectRoot) {
2912
- const dir = join4(projectRoot, ".claude", "commands");
2706
+ const dir = join3(projectRoot, ".claude", "commands");
2913
2707
  ensureDir(dir);
2914
2708
  for (const [name, body] of Object.entries(COMMANDS)) {
2915
- writeFileSync3(join4(dir, name), body, "utf-8");
2709
+ writeFileSync3(join3(dir, name), body, "utf-8");
2916
2710
  }
2917
2711
  }
2918
2712
  function writeClaudeSkills(projectRoot) {
2919
- const dirCoherent = join4(projectRoot, ".claude", "skills", "coherent-project");
2920
- const dirFrontend = join4(projectRoot, ".claude", "skills", "frontend-ux");
2713
+ const dirCoherent = join3(projectRoot, ".claude", "skills", "coherent-project");
2714
+ const dirFrontend = join3(projectRoot, ".claude", "skills", "frontend-ux");
2921
2715
  ensureDir(dirCoherent);
2922
2716
  ensureDir(dirFrontend);
2923
- writeFileSync3(join4(dirCoherent, "SKILL.md"), SKILL_COHERENT, "utf-8");
2924
- writeFileSync3(join4(dirFrontend, "SKILL.md"), SKILL_FRONTEND_UX, "utf-8");
2717
+ writeFileSync3(join3(dirCoherent, "SKILL.md"), SKILL_COHERENT, "utf-8");
2718
+ writeFileSync3(join3(dirFrontend, "SKILL.md"), SKILL_FRONTEND_UX, "utf-8");
2925
2719
  }
2926
2720
  function writeClaudeSettings(projectRoot) {
2927
- const dir = join4(projectRoot, ".claude");
2721
+ const dir = join3(projectRoot, ".claude");
2928
2722
  ensureDir(dir);
2929
- writeFileSync3(join4(dir, "settings.json"), SETTINGS_JSON.trim(), "utf-8");
2723
+ writeFileSync3(join3(dir, "settings.json"), SETTINGS_JSON.trim(), "utf-8");
2930
2724
  }
2931
2725
  async function loadManifestAndConfig(projectRoot) {
2932
2726
  let manifest;
@@ -2936,8 +2730,8 @@ async function loadManifestAndConfig(projectRoot) {
2936
2730
  manifest = { shared: [], nextId: 1 };
2937
2731
  }
2938
2732
  let config2 = null;
2939
- const configPath = join4(projectRoot, "design-system.config.ts");
2940
- if (existsSync5(configPath)) {
2733
+ const configPath = join3(projectRoot, "design-system.config.ts");
2734
+ if (existsSync4(configPath)) {
2941
2735
  try {
2942
2736
  const dsm = new DesignSystemManager(configPath);
2943
2737
  await dsm.load();
@@ -3316,8 +3110,8 @@ async function writeCursorRules(projectRoot) {
3316
3110
  manifest = { shared: [], nextId: 1 };
3317
3111
  }
3318
3112
  let config2 = null;
3319
- const configPath = join5(projectRoot, "design-system.config.ts");
3320
- if (existsSync6(configPath)) {
3113
+ const configPath = join4(projectRoot, "design-system.config.ts");
3114
+ if (existsSync5(configPath)) {
3321
3115
  try {
3322
3116
  const dsm = new DesignSystemManager2(configPath);
3323
3117
  await dsm.load();
@@ -3326,7 +3120,7 @@ async function writeCursorRules(projectRoot) {
3326
3120
  }
3327
3121
  }
3328
3122
  const content = buildCursorRules(manifest, config2);
3329
- const outPath = join5(projectRoot, ".cursorrules");
3123
+ const outPath = join4(projectRoot, ".cursorrules");
3330
3124
  writeFileSync4(outPath, content, "utf-8");
3331
3125
  writeClaudeMd(projectRoot, manifest, config2);
3332
3126
  const tokenKeys = config2?.tokens ? [
@@ -3350,13 +3144,13 @@ async function regenerateCursorRules() {
3350
3144
  }
3351
3145
 
3352
3146
  // src/utils/tailwind-version.ts
3353
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
3147
+ import { existsSync as existsSync6, readFileSync as readFileSync3 } from "fs";
3354
3148
  import { resolve as resolve3 } from "path";
3355
3149
  function isTailwindV4(projectRoot) {
3356
3150
  const pkgPath = resolve3(projectRoot, "package.json");
3357
- if (existsSync7(pkgPath)) {
3151
+ if (existsSync6(pkgPath)) {
3358
3152
  try {
3359
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
3153
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
3360
3154
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
3361
3155
  if (allDeps["@tailwindcss/postcss"]) return true;
3362
3156
  const twVersion = allDeps["tailwindcss"] || "";
@@ -3365,8 +3159,8 @@ function isTailwindV4(projectRoot) {
3365
3159
  }
3366
3160
  }
3367
3161
  const globalsPath = resolve3(projectRoot, "app", "globals.css");
3368
- if (existsSync7(globalsPath)) {
3369
- const content = readFileSync4(globalsPath, "utf-8");
3162
+ if (existsSync6(globalsPath)) {
3163
+ const content = readFileSync3(globalsPath, "utf-8");
3370
3164
  if (content.includes('@import "tailwindcss"') || content.includes("@import 'tailwindcss'")) return true;
3371
3165
  }
3372
3166
  return false;
@@ -3550,10 +3344,10 @@ function toKebabCase(str) {
3550
3344
 
3551
3345
  // src/commands/init.ts
3552
3346
  function hasNextInPackageJson(projectPath) {
3553
- const pkgPath = join6(projectPath, "package.json");
3554
- if (!existsSync8(pkgPath)) return false;
3347
+ const pkgPath = join5(projectPath, "package.json");
3348
+ if (!existsSync7(pkgPath)) return false;
3555
3349
  try {
3556
- const json = JSON.parse(readFileSync5(pkgPath, "utf-8"));
3350
+ const json = JSON.parse(readFileSync4(pkgPath, "utf-8"));
3557
3351
  const deps = { ...json.dependencies, ...json.devDependencies };
3558
3352
  return typeof deps?.next === "string";
3559
3353
  } catch {
@@ -3563,30 +3357,30 @@ function hasNextInPackageJson(projectPath) {
3563
3357
  function cleanConflictingFiles(projectPath) {
3564
3358
  const conflicts = [".next", ".coherent", ".cursorrules", ".eslintrc.json", "CLAUDE.md", ".claude", ".vscode"];
3565
3359
  for (const name of conflicts) {
3566
- const fullPath = join6(projectPath, name);
3567
- if (existsSync8(fullPath)) {
3360
+ const fullPath = join5(projectPath, name);
3361
+ if (existsSync7(fullPath)) {
3568
3362
  rmSync(fullPath, { recursive: true, force: true });
3569
3363
  }
3570
3364
  }
3571
3365
  }
3572
3366
  function runCreateNextApp(projectPath) {
3573
3367
  cleanConflictingFiles(projectPath);
3574
- const envPath = join6(projectPath, ".env");
3575
- const envBackup = existsSync8(envPath) ? readFileSync5(envPath, "utf-8") : null;
3368
+ const envPath = join5(projectPath, ".env");
3369
+ const envBackup = existsSync7(envPath) ? readFileSync4(envPath, "utf-8") : null;
3576
3370
  if (envBackup !== null) rmSync(envPath, { force: true });
3577
3371
  const cmd = "npx --yes create-next-app@15.2.4 . --typescript --tailwind --eslint --app --no-src-dir --no-turbopack --yes";
3578
- execSync2(cmd, { cwd: projectPath, stdio: "inherit" });
3372
+ execSync(cmd, { cwd: projectPath, stdio: "inherit" });
3579
3373
  if (envBackup !== null) {
3580
- const existing = existsSync8(envPath) ? readFileSync5(envPath, "utf-8") : "";
3374
+ const existing = existsSync7(envPath) ? readFileSync4(envPath, "utf-8") : "";
3581
3375
  writeFileSync5(envPath, existing ? existing + "\n" + envBackup : envBackup, "utf-8");
3582
3376
  }
3583
3377
  }
3584
3378
  async function ensureCoherentPrerequisites(projectPath) {
3585
- const libPath = join6(projectPath, "lib");
3586
- const utilsPath = join6(projectPath, "lib", "utils.ts");
3587
- const componentsUiPath = join6(projectPath, "components", "ui");
3588
- if (!existsSync8(utilsPath)) {
3589
- if (!existsSync8(libPath)) mkdirSync3(libPath, { recursive: true });
3379
+ const libPath = join5(projectPath, "lib");
3380
+ const utilsPath = join5(projectPath, "lib", "utils.ts");
3381
+ const componentsUiPath = join5(projectPath, "components", "ui");
3382
+ if (!existsSync7(utilsPath)) {
3383
+ if (!existsSync7(libPath)) mkdirSync3(libPath, { recursive: true });
3590
3384
  const cnContent = `import { type ClassValue, clsx } from 'clsx'
3591
3385
  import { twMerge } from 'tailwind-merge'
3592
3386
 
@@ -3596,20 +3390,20 @@ export function cn(...inputs: ClassValue[]) {
3596
3390
  `;
3597
3391
  await writeFile(utilsPath, cnContent);
3598
3392
  }
3599
- if (!existsSync8(componentsUiPath)) mkdirSync3(componentsUiPath, { recursive: true });
3393
+ if (!existsSync7(componentsUiPath)) mkdirSync3(componentsUiPath, { recursive: true });
3600
3394
  }
3601
3395
  async function ensureRegistryComponents(config2, projectPath) {
3602
3396
  const provider = getComponentProvider();
3603
3397
  const baseComponents = ["button", "card", "input", "label", "switch"];
3604
3398
  await provider.installBatch(baseComponents, projectPath);
3605
3399
  const generator = new ComponentGenerator(config2);
3606
- const uiDir = join6(projectPath, "components", "ui");
3607
- if (!existsSync8(uiDir)) mkdirSync3(uiDir, { recursive: true });
3400
+ const uiDir = join5(projectPath, "components", "ui");
3401
+ if (!existsSync7(uiDir)) mkdirSync3(uiDir, { recursive: true });
3608
3402
  for (const comp of config2.components) {
3609
3403
  if (comp.source === "shadcn") continue;
3610
3404
  const fileName = toKebabCase(comp.name) + ".tsx";
3611
- const filePath = join6(uiDir, fileName);
3612
- if (existsSync8(filePath)) continue;
3405
+ const filePath = join5(uiDir, fileName);
3406
+ if (existsSync7(filePath)) continue;
3613
3407
  const code = await generator.generate(comp);
3614
3408
  await writeFile(filePath, code);
3615
3409
  }
@@ -3637,8 +3431,8 @@ async function initCommand(name) {
3637
3431
  );
3638
3432
  process.exit(1);
3639
3433
  }
3640
- const targetDir = join6(cwd2(), name);
3641
- if (!existsSync8(targetDir)) {
3434
+ const targetDir = join5(cwd2(), name);
3435
+ if (!existsSync7(targetDir)) {
3642
3436
  mkdirSync3(targetDir, { recursive: true });
3643
3437
  }
3644
3438
  process.chdir(targetDir);
@@ -3646,7 +3440,7 @@ async function initCommand(name) {
3646
3440
  let projectPath;
3647
3441
  try {
3648
3442
  projectPath = cwd2();
3649
- if (!existsSync8(projectPath)) {
3443
+ if (!existsSync7(projectPath)) {
3650
3444
  throw new Error("ENOENT");
3651
3445
  }
3652
3446
  } catch (err) {
@@ -3717,7 +3511,7 @@ async function initCommand(name) {
3717
3511
  await ensureCoherentPrerequisites(projectPath);
3718
3512
  const depsSpinner = ora("Installing component dependencies...").start();
3719
3513
  try {
3720
- execSync2(`npm install --legacy-peer-deps ${COHERENT_REQUIRED_PACKAGES.join(" ")}`, {
3514
+ execSync(`npm install --legacy-peer-deps ${COHERENT_REQUIRED_PACKAGES.join(" ")}`, {
3721
3515
  cwd: projectPath,
3722
3516
  stdio: "pipe"
3723
3517
  });
@@ -3730,7 +3524,7 @@ async function initCommand(name) {
3730
3524
  const usesV4 = isTailwindV4(projectPath);
3731
3525
  if (usesV4) {
3732
3526
  const v4Css = generateV4GlobalsCss(config2);
3733
- await writeFile(join6(projectPath, "app", "globals.css"), v4Css);
3527
+ await writeFile(join5(projectPath, "app", "globals.css"), v4Css);
3734
3528
  } else {
3735
3529
  await scaffolder.generateGlobalsCss();
3736
3530
  await scaffolder.generateTailwindConfigTs();
@@ -3744,14 +3538,14 @@ const config = {
3744
3538
 
3745
3539
  export default config
3746
3540
  `;
3747
- await writeFile(join6(projectPath, "postcss.config.mjs"), postcssContent);
3541
+ await writeFile(join5(projectPath, "postcss.config.mjs"), postcssContent);
3748
3542
  }
3749
3543
  await scaffolder.generateRootLayout();
3750
3544
  await configureNextImages(projectPath);
3751
3545
  await createAppRouteGroupLayout(projectPath);
3752
3546
  const welcomeMarkdown = getWelcomeMarkdown();
3753
3547
  const homePageContent = generateWelcomeComponent(welcomeMarkdown);
3754
- await writeFile(join6(projectPath, "app", "page.tsx"), homePageContent);
3548
+ await writeFile(join5(projectPath, "app", "page.tsx"), homePageContent);
3755
3549
  const designSystemSpinner = ora("Creating design system pages...").start();
3756
3550
  await scaffolder.generateDesignSystemPages();
3757
3551
  designSystemSpinner.succeed("Design system pages created");
@@ -3766,7 +3560,7 @@ export default config
3766
3560
  scaffoldSpinner.succeed("Project structure created");
3767
3561
  const depsSpinner = ora("Installing component dependencies...").start();
3768
3562
  try {
3769
- execSync2(`npm install --legacy-peer-deps ${COHERENT_REQUIRED_PACKAGES.join(" ")}`, {
3563
+ execSync(`npm install --legacy-peer-deps ${COHERENT_REQUIRED_PACKAGES.join(" ")}`, {
3770
3564
  cwd: projectPath,
3771
3565
  stdio: "pipe"
3772
3566
  });
@@ -3804,13 +3598,13 @@ export default config
3804
3598
  }
3805
3599
  }
3806
3600
  async function configureNextImages(projectPath) {
3807
- const tsPath = join6(projectPath, "next.config.ts");
3808
- const jsPath = join6(projectPath, "next.config.js");
3809
- const mjsPath = join6(projectPath, "next.config.mjs");
3601
+ const tsPath = join5(projectPath, "next.config.ts");
3602
+ const jsPath = join5(projectPath, "next.config.js");
3603
+ const mjsPath = join5(projectPath, "next.config.mjs");
3810
3604
  let configPath = "";
3811
- if (existsSync8(tsPath)) configPath = tsPath;
3812
- else if (existsSync8(mjsPath)) configPath = mjsPath;
3813
- else if (existsSync8(jsPath)) configPath = jsPath;
3605
+ if (existsSync7(tsPath)) configPath = tsPath;
3606
+ else if (existsSync7(mjsPath)) configPath = mjsPath;
3607
+ else if (existsSync7(jsPath)) configPath = jsPath;
3814
3608
  else return;
3815
3609
  const content = `import type { NextConfig } from "next";
3816
3610
 
@@ -3829,7 +3623,7 @@ export default nextConfig;
3829
3623
  await writeFile(configPath, content);
3830
3624
  }
3831
3625
  async function createAppRouteGroupLayout(projectPath) {
3832
- const dir = join6(projectPath, "app", "(app)");
3626
+ const dir = join5(projectPath, "app", "(app)");
3833
3627
  mkdirSync3(dir, { recursive: true });
3834
3628
  const layoutCode = `export default function AppLayout({
3835
3629
  children,
@@ -3843,14 +3637,14 @@ async function createAppRouteGroupLayout(projectPath) {
3843
3637
  )
3844
3638
  }
3845
3639
  `;
3846
- await writeFile(join6(dir, "layout.tsx"), layoutCode);
3640
+ await writeFile(join5(dir, "layout.tsx"), layoutCode);
3847
3641
  }
3848
3642
 
3849
3643
  // src/commands/chat.ts
3850
3644
  import chalk13 from "chalk";
3851
3645
  import ora2 from "ora";
3852
- import { resolve as resolve10, relative as relative2, join as join11 } from "path";
3853
- import { existsSync as existsSync17, readFileSync as readFileSync12, mkdirSync as mkdirSync6, readdirSync as readdirSync4 } from "fs";
3646
+ import { resolve as resolve10, relative as relative2, join as join10 } from "path";
3647
+ import { existsSync as existsSync16, readFileSync as readFileSync11, mkdirSync as mkdirSync6, readdirSync as readdirSync4 } from "fs";
3854
3648
  import {
3855
3649
  DesignSystemManager as DesignSystemManager7,
3856
3650
  ComponentManager as ComponentManager5,
@@ -4612,9 +4406,9 @@ function extractComponentSpec(changes) {
4612
4406
  }
4613
4407
 
4614
4408
  // src/utils/auth-route-group.ts
4615
- import { join as join7 } from "path";
4616
- import { readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
4617
- import { existsSync as existsSync9 } from "fs";
4409
+ import { join as join6 } from "path";
4410
+ import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
4411
+ import { existsSync as existsSync8 } from "fs";
4618
4412
  var AUTH_LAYOUT = `export default function AuthLayout({
4619
4413
  children,
4620
4414
  }: {
@@ -4646,20 +4440,20 @@ export default function ShowWhenNotAuthRoute({
4646
4440
  }
4647
4441
  `;
4648
4442
  async function ensureAuthRouteGroup(projectRoot) {
4649
- const authLayoutPath = join7(projectRoot, "app", "(auth)", "layout.tsx");
4650
- const guardPath2 = join7(projectRoot, "app", "ShowWhenNotAuthRoute.tsx");
4651
- const rootLayoutPath = join7(projectRoot, "app", "layout.tsx");
4652
- if (!existsSync9(authLayoutPath)) {
4443
+ const authLayoutPath = join6(projectRoot, "app", "(auth)", "layout.tsx");
4444
+ const guardPath2 = join6(projectRoot, "app", "ShowWhenNotAuthRoute.tsx");
4445
+ const rootLayoutPath = join6(projectRoot, "app", "layout.tsx");
4446
+ if (!existsSync8(authLayoutPath)) {
4653
4447
  const { mkdir: mkdir8 } = await import("fs/promises");
4654
- await mkdir8(join7(projectRoot, "app", "(auth)"), { recursive: true });
4448
+ await mkdir8(join6(projectRoot, "app", "(auth)"), { recursive: true });
4655
4449
  await writeFile2(authLayoutPath, AUTH_LAYOUT, "utf-8");
4656
4450
  }
4657
- if (!existsSync9(guardPath2)) {
4451
+ if (!existsSync8(guardPath2)) {
4658
4452
  await writeFile2(guardPath2, SHOW_WHEN_NOT_AUTH, "utf-8");
4659
4453
  }
4660
4454
  let layoutContent;
4661
4455
  try {
4662
- layoutContent = await readFile3(rootLayoutPath, "utf-8");
4456
+ layoutContent = await readFile2(rootLayoutPath, "utf-8");
4663
4457
  } catch {
4664
4458
  return;
4665
4459
  }
@@ -4688,9 +4482,9 @@ async function ensureAuthRouteGroup(projectRoot) {
4688
4482
  }
4689
4483
 
4690
4484
  // src/utils/dark-mode.ts
4691
- import { readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
4692
- import { join as join8 } from "path";
4693
- import { existsSync as existsSync10 } from "fs";
4485
+ import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
4486
+ import { join as join7 } from "path";
4487
+ import { existsSync as existsSync9 } from "fs";
4694
4488
  import { generateSharedComponent, loadManifest as loadManifest3, integrateSharedLayoutIntoRootLayout } from "@getcoherent/core";
4695
4489
  var THEME_TOGGLE_CODE = `'use client'
4696
4490
 
@@ -4716,9 +4510,9 @@ export function ThemeToggle() {
4716
4510
  }
4717
4511
  `;
4718
4512
  async function setDefaultDarkTheme(projectRoot) {
4719
- const layoutPath = join8(projectRoot, "app", "layout.tsx");
4720
- if (!existsSync10(layoutPath)) return false;
4721
- let content = await readFile4(layoutPath, "utf-8");
4513
+ const layoutPath = join7(projectRoot, "app", "layout.tsx");
4514
+ if (!existsSync9(layoutPath)) return false;
4515
+ let content = await readFile3(layoutPath, "utf-8");
4722
4516
  if (content.includes('<html className="dark"') || content.includes("<html className='dark'")) return true;
4723
4517
  content = content.replace(/<html(\s|>)/, '<html className="dark"$1');
4724
4518
  await writeFile3(layoutPath, content, "utf-8");
@@ -4745,8 +4539,8 @@ async function ensureThemeToggle(projectRoot) {
4745
4539
  import { appendFile } from "fs/promises";
4746
4540
 
4747
4541
  // src/utils/backup.ts
4748
- import { existsSync as existsSync11, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync6, readdirSync, rmSync as rmSync2, statSync } from "fs";
4749
- import { join as join9, relative, dirname as dirname4 } from "path";
4542
+ import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync6, readdirSync, rmSync as rmSync2, statSync } from "fs";
4543
+ import { join as join8, relative, dirname as dirname4 } from "path";
4750
4544
  import chalk6 from "chalk";
4751
4545
  var DEBUG = process.env.COHERENT_DEBUG === "1";
4752
4546
  var BACKUP_DIR = ".coherent/backups";
@@ -4761,28 +4555,28 @@ var CRITICAL_FILES = [
4761
4555
  var CRITICAL_DIRS = ["app", "components"];
4762
4556
  function createBackup(projectRoot) {
4763
4557
  try {
4764
- const backupBase = join9(projectRoot, BACKUP_DIR);
4558
+ const backupBase = join8(projectRoot, BACKUP_DIR);
4765
4559
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
4766
- const backupPath = join9(backupBase, timestamp);
4560
+ const backupPath = join8(backupBase, timestamp);
4767
4561
  mkdirSync4(backupPath, { recursive: true });
4768
4562
  let fileCount = 0;
4769
4563
  for (const file of CRITICAL_FILES) {
4770
- const src = join9(projectRoot, file);
4771
- if (existsSync11(src)) {
4772
- const dest = join9(backupPath, file);
4564
+ const src = join8(projectRoot, file);
4565
+ if (existsSync10(src)) {
4566
+ const dest = join8(backupPath, file);
4773
4567
  mkdirSync4(dirname4(dest), { recursive: true });
4774
- writeFileSync6(dest, readFileSync6(src));
4568
+ writeFileSync6(dest, readFileSync5(src));
4775
4569
  fileCount++;
4776
4570
  }
4777
4571
  }
4778
4572
  for (const dir of CRITICAL_DIRS) {
4779
- const srcDir = join9(projectRoot, dir);
4780
- if (!existsSync11(srcDir)) continue;
4573
+ const srcDir = join8(projectRoot, dir);
4574
+ if (!existsSync10(srcDir)) continue;
4781
4575
  backupDirectory(srcDir, projectRoot, backupPath);
4782
4576
  fileCount += countFiles(srcDir);
4783
4577
  }
4784
4578
  writeFileSync6(
4785
- join9(backupPath, ".backup-meta.json"),
4579
+ join8(backupPath, ".backup-meta.json"),
4786
4580
  JSON.stringify(
4787
4581
  {
4788
4582
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -4803,15 +4597,15 @@ function backupDirectory(srcDir, projectRoot, backupPath) {
4803
4597
  const entries = readdirSync(srcDir, { withFileTypes: true });
4804
4598
  for (const entry of entries) {
4805
4599
  if (entry.name === "node_modules" || entry.name === ".next" || entry.name === ".git") continue;
4806
- const fullPath = join9(srcDir, entry.name);
4600
+ const fullPath = join8(srcDir, entry.name);
4807
4601
  const relPath = relative(projectRoot, fullPath);
4808
- const destPath = join9(backupPath, relPath);
4602
+ const destPath = join8(backupPath, relPath);
4809
4603
  if (entry.isDirectory()) {
4810
4604
  mkdirSync4(destPath, { recursive: true });
4811
4605
  backupDirectory(fullPath, projectRoot, backupPath);
4812
4606
  } else if (entry.isFile()) {
4813
4607
  mkdirSync4(dirname4(destPath), { recursive: true });
4814
- writeFileSync6(destPath, readFileSync6(fullPath));
4608
+ writeFileSync6(destPath, readFileSync5(fullPath));
4815
4609
  }
4816
4610
  }
4817
4611
  }
@@ -4821,7 +4615,7 @@ function countFiles(dir) {
4821
4615
  const entries = readdirSync(dir, { withFileTypes: true });
4822
4616
  for (const entry of entries) {
4823
4617
  if (entry.name === "node_modules" || entry.name === ".next") continue;
4824
- const fullPath = join9(dir, entry.name);
4618
+ const fullPath = join8(dir, entry.name);
4825
4619
  if (entry.isDirectory()) {
4826
4620
  count += countFiles(fullPath);
4827
4621
  } else if (entry.isFile()) {
@@ -4835,24 +4629,24 @@ function countFiles(dir) {
4835
4629
  }
4836
4630
  function pruneOldBackups(backupBase) {
4837
4631
  try {
4838
- const entries = readdirSync(backupBase).filter((e) => e !== ".gitkeep" && !e.startsWith(".")).map((name) => ({ name, time: statSync(join9(backupBase, name)).mtimeMs })).sort((a, b) => b.time - a.time);
4632
+ const entries = readdirSync(backupBase).filter((e) => e !== ".gitkeep" && !e.startsWith(".")).map((name) => ({ name, time: statSync(join8(backupBase, name)).mtimeMs })).sort((a, b) => b.time - a.time);
4839
4633
  for (const old of entries.slice(MAX_BACKUPS)) {
4840
- rmSync2(join9(backupBase, old.name), { recursive: true, force: true });
4634
+ rmSync2(join8(backupBase, old.name), { recursive: true, force: true });
4841
4635
  }
4842
4636
  } catch (e) {
4843
4637
  if (DEBUG) console.error("Failed to prune old backups:", e);
4844
4638
  }
4845
4639
  }
4846
4640
  function listBackups(projectRoot) {
4847
- const backupBase = join9(projectRoot, BACKUP_DIR);
4848
- if (!existsSync11(backupBase)) return [];
4641
+ const backupBase = join8(projectRoot, BACKUP_DIR);
4642
+ if (!existsSync10(backupBase)) return [];
4849
4643
  try {
4850
4644
  return readdirSync(backupBase).filter((e) => !e.startsWith(".")).map((name) => {
4851
- const metaPath = join9(backupBase, name, ".backup-meta.json");
4645
+ const metaPath = join8(backupBase, name, ".backup-meta.json");
4852
4646
  let meta = { timestamp: name, files: 0 };
4853
- if (existsSync11(metaPath)) {
4647
+ if (existsSync10(metaPath)) {
4854
4648
  try {
4855
- meta = JSON.parse(readFileSync6(metaPath, "utf-8"));
4649
+ meta = JSON.parse(readFileSync5(metaPath, "utf-8"));
4856
4650
  } catch (e) {
4857
4651
  if (DEBUG) console.error("Bad backup meta:", metaPath, e);
4858
4652
  }
@@ -4865,8 +4659,8 @@ function listBackups(projectRoot) {
4865
4659
  }
4866
4660
  }
4867
4661
  function restoreBackup(projectRoot, backupName) {
4868
- const backupPath = join9(projectRoot, BACKUP_DIR, backupName);
4869
- if (!existsSync11(backupPath)) return false;
4662
+ const backupPath = join8(projectRoot, BACKUP_DIR, backupName);
4663
+ if (!existsSync10(backupPath)) return false;
4870
4664
  try {
4871
4665
  restoreDirectory(backupPath, backupPath, projectRoot);
4872
4666
  return true;
@@ -4879,15 +4673,15 @@ function restoreDirectory(currentDir, backupRoot, projectRoot) {
4879
4673
  const entries = readdirSync(currentDir, { withFileTypes: true });
4880
4674
  for (const entry of entries) {
4881
4675
  if (entry.name === ".backup-meta.json") continue;
4882
- const fullPath = join9(currentDir, entry.name);
4676
+ const fullPath = join8(currentDir, entry.name);
4883
4677
  const relPath = relative(backupRoot, fullPath);
4884
- const destPath = join9(projectRoot, relPath);
4678
+ const destPath = join8(projectRoot, relPath);
4885
4679
  if (entry.isDirectory()) {
4886
4680
  mkdirSync4(destPath, { recursive: true });
4887
4681
  restoreDirectory(fullPath, backupRoot, projectRoot);
4888
4682
  } else if (entry.isFile()) {
4889
4683
  mkdirSync4(dirname4(destPath), { recursive: true });
4890
- writeFileSync6(destPath, readFileSync6(fullPath));
4684
+ writeFileSync6(destPath, readFileSync5(fullPath));
4891
4685
  }
4892
4686
  }
4893
4687
  }
@@ -4899,15 +4693,15 @@ function logBackupCreated(backupPath) {
4899
4693
  }
4900
4694
 
4901
4695
  // src/utils/fix-globals-css.ts
4902
- import { existsSync as existsSync12, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "fs";
4696
+ import { existsSync as existsSync11, readFileSync as readFileSync6, writeFileSync as writeFileSync7 } from "fs";
4903
4697
  import { resolve as resolve4 } from "path";
4904
4698
  import { buildCssVariables as buildCssVariables2 } from "@getcoherent/core";
4905
4699
  function needsGlobalsFix(projectRoot) {
4906
4700
  const globalsPath = resolve4(projectRoot, "app", "globals.css");
4907
- if (!existsSync12(globalsPath)) {
4701
+ if (!existsSync11(globalsPath)) {
4908
4702
  return false;
4909
4703
  }
4910
- const content = readFileSync7(globalsPath, "utf-8");
4704
+ const content = readFileSync6(globalsPath, "utf-8");
4911
4705
  if (isTailwindV4(projectRoot)) {
4912
4706
  if (!content.includes("@theme inline")) return true;
4913
4707
  if (content.includes("@tailwind base")) return true;
@@ -4932,7 +4726,7 @@ function needsGlobalsFix(projectRoot) {
4932
4726
  function fixGlobalsCss(projectRoot, config2) {
4933
4727
  const globalsPath = resolve4(projectRoot, "app", "globals.css");
4934
4728
  const layoutPath = resolve4(projectRoot, "app", "layout.tsx");
4935
- if (!existsSync12(globalsPath)) {
4729
+ if (!existsSync11(globalsPath)) {
4936
4730
  return;
4937
4731
  }
4938
4732
  if (isTailwindV4(projectRoot)) {
@@ -4955,10 +4749,10 @@ function fixGlobalsCss(projectRoot, config2) {
4955
4749
  }
4956
4750
  `;
4957
4751
  writeFileSync7(globalsPath, minimalCss, "utf-8");
4958
- if (!existsSync12(layoutPath)) {
4752
+ if (!existsSync11(layoutPath)) {
4959
4753
  return;
4960
4754
  }
4961
- let layoutContent = readFileSync7(layoutPath, "utf-8");
4755
+ let layoutContent = readFileSync6(layoutPath, "utf-8");
4962
4756
  if (layoutContent.includes("dangerouslySetInnerHTML")) {
4963
4757
  return;
4964
4758
  }
@@ -4972,7 +4766,7 @@ function fixGlobalsCss(projectRoot, config2) {
4972
4766
 
4973
4767
  // src/commands/chat/utils.ts
4974
4768
  import { resolve as resolve5 } from "path";
4975
- import { existsSync as existsSync13, readFileSync as readFileSync8 } from "fs";
4769
+ import { existsSync as existsSync12, readFileSync as readFileSync7 } from "fs";
4976
4770
  import { DesignSystemManager as DesignSystemManager3, loadManifest as loadManifest4 } from "@getcoherent/core";
4977
4771
  import chalk7 from "chalk";
4978
4772
  var MARKETING_ROUTES = /* @__PURE__ */ new Set(["", "landing", "pricing", "about", "contact", "blog", "features"]);
@@ -4994,10 +4788,10 @@ function inferRouteUsesAuthSegment(route) {
4994
4788
  function readAnchorPageCodeFromDisk(projectRoot, route) {
4995
4789
  const useAuthSegment = inferRouteUsesAuthSegment(route);
4996
4790
  const abs = routeToFsPath(projectRoot, route, useAuthSegment);
4997
- if (!existsSync13(abs)) return null;
4791
+ if (!existsSync12(abs)) return null;
4998
4792
  let code;
4999
4793
  try {
5000
- code = readFileSync8(abs, "utf-8");
4794
+ code = readFileSync7(abs, "utf-8");
5001
4795
  } catch {
5002
4796
  return null;
5003
4797
  }
@@ -5013,11 +4807,11 @@ function routeToFsPath(projectRoot, route, isAuthOrPlan) {
5013
4807
  const isAuth = typeof isAuthOrPlan === "boolean" ? isAuthOrPlan : false;
5014
4808
  const slug = route.replace(/^\//, "");
5015
4809
  if (!slug) return resolve5(projectRoot, "app", "page.tsx");
4810
+ if (isAuth || isAuthRoute(route)) return resolve5(projectRoot, "app", "(auth)", slug || "login", "page.tsx");
5016
4811
  if (plan) {
5017
4812
  const group = getPageGroup(route, plan);
5018
4813
  if (group) return resolve5(projectRoot, "app", `(${group.id})`, slug, "page.tsx");
5019
4814
  }
5020
- if (isAuth) return resolve5(projectRoot, "app", "(auth)", slug || "login", "page.tsx");
5021
4815
  if (isMarketingRoute(route)) return resolve5(projectRoot, "app", slug, "page.tsx");
5022
4816
  return resolve5(projectRoot, "app", "(app)", slug, "page.tsx");
5023
4817
  }
@@ -5026,11 +4820,11 @@ function routeToRelPath(route, isAuthOrPlan) {
5026
4820
  const isAuth = typeof isAuthOrPlan === "boolean" ? isAuthOrPlan : false;
5027
4821
  const slug = route.replace(/^\//, "");
5028
4822
  if (!slug) return "app/page.tsx";
4823
+ if (isAuth || isAuthRoute(route)) return `app/(auth)/${slug || "login"}/page.tsx`;
5029
4824
  if (plan) {
5030
4825
  const group = getPageGroup(route, plan);
5031
4826
  if (group) return `app/(${group.id})/${slug}/page.tsx`;
5032
4827
  }
5033
- if (isAuth) return `app/(auth)/${slug || "login"}/page.tsx`;
5034
4828
  if (isMarketingRoute(route)) return `app/${slug}/page.tsx`;
5035
4829
  return `app/(app)/${slug}/page.tsx`;
5036
4830
  }
@@ -5115,7 +4909,7 @@ async function warnInlineDuplicates(projectRoot, pageName, route, pageCode, mani
5115
4909
  }
5116
4910
  }
5117
4911
  async function loadConfig(configPath) {
5118
- if (!existsSync13(configPath)) {
4912
+ if (!existsSync12(configPath)) {
5119
4913
  throw new Error(
5120
4914
  `Design system config not found at ${configPath}
5121
4915
  Run "coherent init" first to create a project.`
@@ -5143,8 +4937,8 @@ async function resolveTargetFlags(message, options, config2, projectRoot) {
5143
4937
  if (entry) {
5144
4938
  const filePath = resolve5(projectRoot, entry.file);
5145
4939
  let currentCode = "";
5146
- if (existsSync13(filePath)) {
5147
- currentCode = readFileSync8(filePath, "utf-8");
4940
+ if (existsSync12(filePath)) {
4941
+ currentCode = readFileSync7(filePath, "utf-8");
5148
4942
  }
5149
4943
  const codeSnippet = currentCode ? `
5150
4944
 
@@ -5168,8 +4962,8 @@ ${currentCode}
5168
4962
  const relPath = page.route === "/" ? "app/page.tsx" : `app${page.route}/page.tsx`;
5169
4963
  const filePath = resolve5(projectRoot, relPath);
5170
4964
  let currentCode = "";
5171
- if (existsSync13(filePath)) {
5172
- currentCode = readFileSync8(filePath, "utf-8");
4965
+ if (existsSync12(filePath)) {
4966
+ currentCode = readFileSync7(filePath, "utf-8");
5173
4967
  }
5174
4968
  const codeSnippet = currentCode ? `
5175
4969
 
@@ -5624,7 +5418,7 @@ function applyDefaults(request) {
5624
5418
  }
5625
5419
 
5626
5420
  // src/commands/chat/split-generator.ts
5627
- import { existsSync as existsSync14, readFileSync as readFileSync9, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
5421
+ import { existsSync as existsSync13, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
5628
5422
  import { resolve as resolve6 } from "path";
5629
5423
  import { z } from "zod";
5630
5424
  import {
@@ -6075,8 +5869,8 @@ function readExistingAppPageForReference(projectRoot, plan) {
6075
5869
  for (const group of ["(app)", "(admin)", "(dashboard)"]) {
6076
5870
  const filePath = resolve6(projectRoot, "app", group, key, "page.tsx");
6077
5871
  try {
6078
- if (existsSync14(filePath)) {
6079
- const code = readFileSync9(filePath, "utf-8");
5872
+ if (existsSync13(filePath)) {
5873
+ const code = readFileSync8(filePath, "utf-8");
6080
5874
  const lines = code.split("\n");
6081
5875
  return lines.slice(0, 60).join("\n");
6082
5876
  }
@@ -6087,7 +5881,7 @@ function readExistingAppPageForReference(projectRoot, plan) {
6087
5881
  }
6088
5882
  }
6089
5883
  const appDir = resolve6(projectRoot, "app");
6090
- if (!existsSync14(appDir)) return null;
5884
+ if (!existsSync13(appDir)) return null;
6091
5885
  try {
6092
5886
  const entries = readdirSync2(appDir);
6093
5887
  for (const entry of entries) {
@@ -6097,8 +5891,8 @@ function readExistingAppPageForReference(projectRoot, plan) {
6097
5891
  const subDirs = readdirSync2(groupDir);
6098
5892
  for (const sub of subDirs) {
6099
5893
  const pagePath = resolve6(groupDir, sub, "page.tsx");
6100
- if (existsSync14(pagePath)) {
6101
- const code = readFileSync9(pagePath, "utf-8");
5894
+ if (existsSync13(pagePath)) {
5895
+ const code = readFileSync8(pagePath, "utf-8");
6102
5896
  const lines = code.split("\n");
6103
5897
  return lines.slice(0, 60).join("\n");
6104
5898
  }
@@ -6315,7 +6109,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
6315
6109
  if (plan && plan.sharedComponents.length > 0) {
6316
6110
  spinner.start(`Phase 4.5/6 \u2014 Generating ${plan.sharedComponents.length} shared components from plan...`);
6317
6111
  try {
6318
- const { generateSharedComponentsFromPlan } = await import("./plan-generator-BHDEJGMY.js");
6112
+ const { generateSharedComponentsFromPlan } = await import("./plan-generator-WPYWUA7U.js");
6319
6113
  const generated = await generateSharedComponentsFromPlan(
6320
6114
  plan,
6321
6115
  styleContext,
@@ -6372,13 +6166,13 @@ ${existingAppPageCode}
6372
6166
  const existingPageCode = {};
6373
6167
  if (projectRoot) {
6374
6168
  const appDir = resolve6(projectRoot, "app");
6375
- if (existsSync14(appDir)) {
6169
+ if (existsSync13(appDir)) {
6376
6170
  const pageFiles = readdirSync2(appDir, { recursive: true }).filter(
6377
6171
  (f) => typeof f === "string" && f.endsWith("page.tsx")
6378
6172
  );
6379
6173
  for (const pf of pageFiles) {
6380
6174
  try {
6381
- const code = readFileSync9(resolve6(appDir, pf), "utf-8");
6175
+ const code = readFileSync8(resolve6(appDir, pf), "utf-8");
6382
6176
  const route = "/" + pf.replace(/\/page\.tsx$/, "").replace(/\(.*?\)\//g, "");
6383
6177
  existingPageCode[route === "/" ? "/" : route] = code;
6384
6178
  } catch {
@@ -6673,7 +6467,7 @@ import {
6673
6467
 
6674
6468
  // src/commands/chat/code-generator.ts
6675
6469
  import { resolve as resolve7 } from "path";
6676
- import { existsSync as existsSync15, readdirSync as readdirSync3, readFileSync as readFileSync10 } from "fs";
6470
+ import { existsSync as existsSync14, readdirSync as readdirSync3, readFileSync as readFileSync9 } from "fs";
6677
6471
  import { mkdir as mkdir3 } from "fs/promises";
6678
6472
  import { dirname as dirname5 } from "path";
6679
6473
  import {
@@ -6686,25 +6480,25 @@ import chalk9 from "chalk";
6686
6480
 
6687
6481
  // src/utils/file-hashes.ts
6688
6482
  import { createHash } from "crypto";
6689
- import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir2 } from "fs/promises";
6690
- import { join as join10 } from "path";
6483
+ import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir2 } from "fs/promises";
6484
+ import { join as join9 } from "path";
6691
6485
  var HASHES_FILE = ".coherent/file-hashes.json";
6692
6486
  async function computeFileHash(filePath) {
6693
- const content = await readFile5(filePath, "utf-8");
6487
+ const content = await readFile4(filePath, "utf-8");
6694
6488
  return createHash("sha256").update(content).digest("hex");
6695
6489
  }
6696
6490
  async function loadHashes(projectRoot) {
6697
6491
  try {
6698
- const raw = await readFile5(join10(projectRoot, HASHES_FILE), "utf-8");
6492
+ const raw = await readFile4(join9(projectRoot, HASHES_FILE), "utf-8");
6699
6493
  return JSON.parse(raw);
6700
6494
  } catch {
6701
6495
  return {};
6702
6496
  }
6703
6497
  }
6704
6498
  async function saveHashes(projectRoot, hashes) {
6705
- const dir = join10(projectRoot, ".coherent");
6499
+ const dir = join9(projectRoot, ".coherent");
6706
6500
  await mkdir2(dir, { recursive: true });
6707
- await writeFile4(join10(projectRoot, HASHES_FILE), JSON.stringify(hashes, null, 2) + "\n");
6501
+ await writeFile4(join9(projectRoot, HASHES_FILE), JSON.stringify(hashes, null, 2) + "\n");
6708
6502
  }
6709
6503
  async function isManuallyEdited(filePath, storedHash) {
6710
6504
  try {
@@ -6739,7 +6533,7 @@ async function ensureComponentsInstalled(componentIds, cm, dsm, pm, projectRoot)
6739
6533
  const isRegistered = !!cm.read(componentId);
6740
6534
  const fileName = toKebabCase(componentId) + ".tsx";
6741
6535
  const filePath = resolve7(projectRoot, "components", "ui", fileName);
6742
- const fileExists = existsSync15(filePath);
6536
+ const fileExists = existsSync14(filePath);
6743
6537
  if (isRegistered && fileExists) continue;
6744
6538
  const result = await provider.installComponent(componentId, projectRoot);
6745
6539
  if (result.success && result.componentDef) {
@@ -6775,7 +6569,7 @@ async function regeneratePage(pageId, config2, projectRoot) {
6775
6569
  const code = await generator.generate(page, appType);
6776
6570
  const route = page.route || "/";
6777
6571
  const isAuth = isAuthRoute(route) || isAuthRoute(page.name || page.id || "");
6778
- const { loadPlan: loadPlanForPath } = await import("./plan-generator-BHDEJGMY.js");
6572
+ const { loadPlan: loadPlanForPath } = await import("./plan-generator-WPYWUA7U.js");
6779
6573
  const planForPath = loadPlanForPath(projectRoot);
6780
6574
  const filePath = routeToFsPath(projectRoot, route, planForPath || isAuth);
6781
6575
  await mkdir3(dirname5(filePath), { recursive: true });
@@ -6783,7 +6577,7 @@ async function regeneratePage(pageId, config2, projectRoot) {
6783
6577
  }
6784
6578
  async function canOverwriteShared(projectRoot, componentFile, storedHashes) {
6785
6579
  const filePath = resolve7(projectRoot, componentFile);
6786
- if (!existsSync15(filePath)) return true;
6580
+ if (!existsSync14(filePath)) return true;
6787
6581
  const storedHash = storedHashes[componentFile];
6788
6582
  if (!storedHash) return true;
6789
6583
  const edited = await isManuallyEdited(filePath, storedHash);
@@ -6859,16 +6653,16 @@ async function regenerateLayout(config2, projectRoot, options = {
6859
6653
  }
6860
6654
  async function scanAndInstallSharedDeps(projectRoot) {
6861
6655
  const sharedDir = resolve7(projectRoot, "components", "shared");
6862
- if (!existsSync15(sharedDir)) return [];
6656
+ if (!existsSync14(sharedDir)) return [];
6863
6657
  const files = readdirSync3(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts"));
6864
6658
  const installed = [];
6865
6659
  const provider = getComponentProvider();
6866
6660
  for (const file of files) {
6867
- const code = readFileSync10(resolve7(sharedDir, file), "utf-8");
6661
+ const code = readFileSync9(resolve7(sharedDir, file), "utf-8");
6868
6662
  const importMatches = [...code.matchAll(/@\/components\/ui\/([a-z0-9-]+)/g)];
6869
6663
  for (const [, componentId] of importMatches) {
6870
6664
  const uiPath = resolve7(projectRoot, "components", "ui", `${componentId}.tsx`);
6871
- if (!existsSync15(uiPath) && provider.has(componentId)) {
6665
+ if (!existsSync14(uiPath) && provider.has(componentId)) {
6872
6666
  try {
6873
6667
  await provider.installComponent(componentId, projectRoot);
6874
6668
  installed.push(componentId);
@@ -6882,7 +6676,7 @@ async function scanAndInstallSharedDeps(projectRoot) {
6882
6676
  async function ensureAppRouteGroupLayout(projectRoot, navType, forceUpdate = false, groupLayouts) {
6883
6677
  const effectiveNavType = groupLayouts?.["app"] || navType;
6884
6678
  const layoutPath = resolve7(projectRoot, "app", "(app)", "layout.tsx");
6885
- if (existsSync15(layoutPath) && !forceUpdate) return;
6679
+ if (existsSync14(layoutPath) && !forceUpdate) return;
6886
6680
  const { mkdir: mkdirAsync } = await import("fs/promises");
6887
6681
  await mkdirAsync(resolve7(projectRoot, "app", "(app)"), { recursive: true });
6888
6682
  const code = buildAppLayoutCode(effectiveNavType);
@@ -6983,8 +6777,8 @@ async function ensurePlanGroupLayouts(projectRoot, plan, storedHashes = {}, conf
6983
6777
  await mkdirAsync(groupDir, { recursive: true });
6984
6778
  const layoutPath = resolve7(groupDir, "layout.tsx");
6985
6779
  const relPath = `app/(${group.id})/layout.tsx`;
6986
- if (existsSync15(layoutPath)) {
6987
- const currentContent = readFileSync10(layoutPath, "utf-8");
6780
+ if (existsSync14(layoutPath)) {
6781
+ const currentContent = readFileSync9(layoutPath, "utf-8");
6988
6782
  const currentHash = createHash2("md5").update(currentContent).digest("hex");
6989
6783
  const storedHash = storedHashes[relPath];
6990
6784
  if (storedHash && storedHash !== currentHash) {
@@ -7026,9 +6820,9 @@ async function regenerateFiles(modified, config2, projectRoot, options = { navCh
7026
6820
  const twGen = new TailwindConfigGenerator(config2);
7027
6821
  const twPath = resolve7(projectRoot, "tailwind.config.ts");
7028
6822
  const twCjsPath = resolve7(projectRoot, "tailwind.config.cjs");
7029
- if (existsSync15(twPath)) {
6823
+ if (existsSync14(twPath)) {
7030
6824
  await writeFile(twPath, await twGen.generate());
7031
- } else if (existsSync15(twCjsPath)) {
6825
+ } else if (existsSync14(twCjsPath)) {
7032
6826
  await writeFile(twCjsPath, await twGen.generateCjs());
7033
6827
  }
7034
6828
  }
@@ -8291,7 +8085,7 @@ function hasNavChanged(before, after) {
8291
8085
  // src/commands/chat/interactive.ts
8292
8086
  import chalk12 from "chalk";
8293
8087
  import { resolve as resolve9 } from "path";
8294
- import { existsSync as existsSync16, readFileSync as readFileSync11, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
8088
+ import { existsSync as existsSync15, readFileSync as readFileSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
8295
8089
  import { DesignSystemManager as DesignSystemManager6, ComponentManager as ComponentManager4, loadManifest as loadManifest7 } from "@getcoherent/core";
8296
8090
  var DEBUG3 = process.env.COHERENT_DEBUG === "1";
8297
8091
  async function interactiveChat(options, chatCommandFn) {
@@ -8316,8 +8110,8 @@ async function interactiveChat(options, chatCommandFn) {
8316
8110
  let history = [];
8317
8111
  try {
8318
8112
  mkdirSync5(historyDir, { recursive: true });
8319
- if (existsSync16(historyFile)) {
8320
- history = readFileSync11(historyFile, "utf-8").split("\n").filter(Boolean).slice(-200);
8113
+ if (existsSync15(historyFile)) {
8114
+ history = readFileSync10(historyFile, "utf-8").split("\n").filter(Boolean).slice(-200);
8321
8115
  }
8322
8116
  } catch (e) {
8323
8117
  if (DEBUG3) console.error("Failed to load REPL history:", e);
@@ -8495,8 +8289,8 @@ async function chatCommand(message, options) {
8495
8289
  const project = requireProject();
8496
8290
  const projectRoot = project.root;
8497
8291
  const configPath = project.configPath;
8498
- const migrationGuard = join11(projectRoot, ".coherent", "migration-in-progress");
8499
- if (existsSync17(migrationGuard)) {
8292
+ const migrationGuard = join10(projectRoot, ".coherent", "migration-in-progress");
8293
+ if (existsSync16(migrationGuard)) {
8500
8294
  spinner.fail("Migration in progress");
8501
8295
  console.error(chalk13.red("\n\u274C A migration is in progress. Run `coherent migrate --rollback` to undo first."));
8502
8296
  bail("Migration in progress");
@@ -8654,7 +8448,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
8654
8448
  let manifest = await loadManifest8(project.root);
8655
8449
  const validShared = manifest.shared.filter((s) => {
8656
8450
  const fp = resolve10(project.root, s.file);
8657
- return existsSync17(fp);
8451
+ return existsSync16(fp);
8658
8452
  });
8659
8453
  if (validShared.length !== manifest.shared.length) {
8660
8454
  const cleaned = manifest.shared.length - validShared.length;
@@ -8875,8 +8669,8 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
8875
8669
  for (const entry of manifest.shared) {
8876
8670
  try {
8877
8671
  const sharedPath = resolve10(projectRoot, entry.file);
8878
- if (existsSync17(sharedPath)) {
8879
- const sharedCode = readFileSync12(sharedPath, "utf-8");
8672
+ if (existsSync16(sharedPath)) {
8673
+ const sharedCode = readFileSync11(sharedPath, "utf-8");
8880
8674
  const sharedImports = sharedCode.matchAll(/@\/components\/ui\/([a-z0-9-]+)/g);
8881
8675
  for (const m of sharedImports) {
8882
8676
  if (m[1]) allNeededComponentIds.add(m[1]);
@@ -8896,8 +8690,8 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
8896
8690
  const missingComponents = [];
8897
8691
  for (const componentId of allNeededComponentIds) {
8898
8692
  const isRegistered = !!cm.read(componentId);
8899
- const filePath = join11(projectRoot, "components", "ui", `${componentId}.tsx`);
8900
- const fileExists = existsSync17(filePath);
8693
+ const filePath = join10(projectRoot, "components", "ui", `${componentId}.tsx`);
8694
+ const fileExists = existsSync16(filePath);
8901
8695
  if (DEBUG4) console.log(chalk13.gray(` Checking ${componentId}: registered=${isRegistered} file=${fileExists}`));
8902
8696
  if (!isRegistered || !fileExists) {
8903
8697
  missingComponents.push(componentId);
@@ -9045,9 +8839,9 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9045
8839
  const route = page.route || `/${page.id || "page"}`;
9046
8840
  const pageFilePath = routeToFsPath(projectRoot, route, false);
9047
8841
  let pageCode = "";
9048
- if (existsSync17(pageFilePath)) {
8842
+ if (existsSync16(pageFilePath)) {
9049
8843
  try {
9050
- pageCode = readFileSync12(pageFilePath, "utf-8");
8844
+ pageCode = readFileSync11(pageFilePath, "utf-8");
9051
8845
  } catch {
9052
8846
  }
9053
8847
  }
@@ -9067,8 +8861,8 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9067
8861
  }
9068
8862
  const missingRoutes = [...allLinkedRoutes].filter((route) => {
9069
8863
  if (expandedExisting.has(route)) return false;
9070
- if (existsSync17(routeToFsPath(projectRoot, route, false))) return false;
9071
- if (existsSync17(routeToFsPath(projectRoot, route, true))) return false;
8864
+ if (existsSync16(routeToFsPath(projectRoot, route, false))) return false;
8865
+ if (existsSync16(routeToFsPath(projectRoot, route, true))) return false;
9072
8866
  return true;
9073
8867
  });
9074
8868
  const SCAFFOLD_AI_LIMIT = 10;
@@ -9133,7 +8927,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9133
8927
  const filePath = routeToFsPath(projectRoot, linkedRoute, isAuth);
9134
8928
  if (isAuth) await ensureAuthRouteGroup(projectRoot);
9135
8929
  const dir = resolve10(filePath, "..");
9136
- if (!existsSync17(dir)) {
8930
+ if (!existsSync16(dir)) {
9137
8931
  mkdirSync6(dir, { recursive: true });
9138
8932
  }
9139
8933
  const placeholderCode = `export default function ${pageName.replace(/\s/g, "")}Page() {
@@ -9166,7 +8960,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9166
8960
  for (const mod of result.modified) {
9167
8961
  if (mod.startsWith("app/") && mod.endsWith("/page.tsx")) {
9168
8962
  try {
9169
- const code = readFileSync12(resolve10(projectRoot, mod), "utf-8");
8963
+ const code = readFileSync11(resolve10(projectRoot, mod), "utf-8");
9170
8964
  const issues = validatePageQuality(code, allRoutes).filter(
9171
8965
  (i) => i.type === "BROKEN_INTERNAL_LINK"
9172
8966
  );
@@ -9249,13 +9043,13 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9249
9043
  const sharedDir = resolve10(projectRoot, "components", "shared");
9250
9044
  const layoutFile = resolve10(projectRoot, "app", "layout.tsx");
9251
9045
  const filesToHash = [layoutFile];
9252
- if (existsSync17(sharedDir)) {
9046
+ if (existsSync16(sharedDir)) {
9253
9047
  for (const f of readdirSync4(sharedDir)) {
9254
9048
  if (f.endsWith(".tsx")) filesToHash.push(resolve10(sharedDir, f));
9255
9049
  }
9256
9050
  }
9257
9051
  for (const filePath of filesToHash) {
9258
- if (existsSync17(filePath)) {
9052
+ if (existsSync16(filePath)) {
9259
9053
  const rel = relative2(projectRoot, filePath);
9260
9054
  updatedHashes[rel] = await computeFileHash(filePath);
9261
9055
  }
@@ -9270,8 +9064,8 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9270
9064
  let manifestChanged = false;
9271
9065
  for (const entry of currentManifest.shared) {
9272
9066
  const fullPath = resolve10(projectRoot, entry.file);
9273
- if (!existsSync17(fullPath)) continue;
9274
- const code = readFileSync12(fullPath, "utf-8");
9067
+ if (!existsSync16(fullPath)) continue;
9068
+ const code = readFileSync11(fullPath, "utf-8");
9275
9069
  const props = extractPropsInterface(code);
9276
9070
  const deps = extractDependencies(code);
9277
9071
  if (props && props !== entry.propsInterface || deps.length !== (entry.dependencies?.length ?? 0)) {
@@ -9285,8 +9079,8 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9285
9079
  const pageFiles = Array.from(allModified).filter((f) => f.startsWith("app/") && f.endsWith("page.tsx"));
9286
9080
  for (const pageFile of pageFiles) {
9287
9081
  const fullPath = resolve10(projectRoot, pageFile);
9288
- if (!existsSync17(fullPath)) continue;
9289
- const pageCode = readFileSync12(fullPath, "utf-8");
9082
+ if (!existsSync16(fullPath)) continue;
9083
+ const pageCode = readFileSync11(fullPath, "utf-8");
9290
9084
  for (const entry of currentManifest.shared) {
9291
9085
  const isUsed = pageCode.includes(`from '@/components/shared/`) && (pageCode.includes(`{ ${entry.name} }`) || pageCode.includes(`{ ${entry.name},`));
9292
9086
  if (isUsed && !entry.usedIn.includes(pageFile)) {
@@ -9343,7 +9137,7 @@ Return JSON: { "requests": [{ "type": "add-page", "changes": { "name": "${compon
9343
9137
  ${uxRecommendations}
9344
9138
  `;
9345
9139
  try {
9346
- if (!existsSync17(recPath)) {
9140
+ if (!existsSync16(recPath)) {
9347
9141
  await writeFile(
9348
9142
  recPath,
9349
9143
  "# UX/UI Recommendations\n\nRecommendations are added here when you use `coherent chat` and the AI suggests improvements.\n"
@@ -9417,9 +9211,9 @@ ${uxRecommendations}
9417
9211
  import chalk14 from "chalk";
9418
9212
  import ora3 from "ora";
9419
9213
  import { spawn } from "child_process";
9420
- import { existsSync as existsSync20, rmSync as rmSync3, readFileSync as readFileSync15, writeFileSync as writeFileSync10, readdirSync as readdirSync6 } from "fs";
9421
- import { resolve as resolve11, join as join14 } from "path";
9422
- import { readdir as readdir2 } from "fs/promises";
9214
+ import { existsSync as existsSync19, rmSync as rmSync3, readFileSync as readFileSync14, writeFileSync as writeFileSync10, readdirSync as readdirSync6 } from "fs";
9215
+ import { resolve as resolve11, join as join13 } from "path";
9216
+ import { readdir } from "fs/promises";
9423
9217
 
9424
9218
  // src/utils/css-validator.ts
9425
9219
  var REQUIRED_THEME_TOKENS = [
@@ -9473,13 +9267,13 @@ function validateV4GlobalsCss(css) {
9473
9267
  import { DesignSystemManager as DesignSystemManager8, ComponentGenerator as ComponentGenerator3 } from "@getcoherent/core";
9474
9268
 
9475
9269
  // src/utils/file-watcher.ts
9476
- import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, existsSync as existsSync19 } from "fs";
9477
- import { relative as relative4, join as join13 } from "path";
9270
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, existsSync as existsSync18 } from "fs";
9271
+ import { relative as relative4, join as join12 } from "path";
9478
9272
  import { loadManifest as loadManifest9, saveManifest as saveManifest4 } from "@getcoherent/core";
9479
9273
 
9480
9274
  // src/utils/component-integrity.ts
9481
- import { existsSync as existsSync18, readFileSync as readFileSync13, readdirSync as readdirSync5 } from "fs";
9482
- import { join as join12, relative as relative3 } from "path";
9275
+ import { existsSync as existsSync17, readFileSync as readFileSync12, readdirSync as readdirSync5 } from "fs";
9276
+ import { join as join11, relative as relative3 } from "path";
9483
9277
  function extractExportedComponentNames(code) {
9484
9278
  const names = [];
9485
9279
  let m;
@@ -9511,14 +9305,14 @@ function arraysEqual(a, b) {
9511
9305
  }
9512
9306
  function findPagesImporting(projectRoot, componentName, componentFile) {
9513
9307
  const results = [];
9514
- const appDir = join12(projectRoot, "app");
9515
- if (!existsSync18(appDir)) return results;
9308
+ const appDir = join11(projectRoot, "app");
9309
+ if (!existsSync17(appDir)) return results;
9516
9310
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
9517
9311
  const componentImportPath = componentFile.replace(/\.tsx$/, "").replace(/\.jsx$/, "");
9518
9312
  for (const absPath of pageFiles) {
9519
9313
  if (absPath.includes("design-system")) continue;
9520
9314
  try {
9521
- const code = readFileSync13(absPath, "utf-8");
9315
+ const code = readFileSync12(absPath, "utf-8");
9522
9316
  const hasNamedImport = new RegExp(`import\\s+\\{[^}]*\\b${componentName}\\b[^}]*\\}\\s+from\\s+['"]`).test(code);
9523
9317
  const hasDefaultImport = new RegExp(`import\\s+${componentName}\\s+from\\s+['"]`).test(code);
9524
9318
  const hasPathImport = code.includes(`@/${componentImportPath}`);
@@ -9531,10 +9325,10 @@ function findPagesImporting(projectRoot, componentName, componentFile) {
9531
9325
  return results;
9532
9326
  }
9533
9327
  function isUsedInLayout(projectRoot, componentName) {
9534
- const layoutPath = join12(projectRoot, "app", "layout.tsx");
9535
- if (!existsSync18(layoutPath)) return false;
9328
+ const layoutPath = join11(projectRoot, "app", "layout.tsx");
9329
+ if (!existsSync17(layoutPath)) return false;
9536
9330
  try {
9537
- const code = readFileSync13(layoutPath, "utf-8");
9331
+ const code = readFileSync12(layoutPath, "utf-8");
9538
9332
  return code.includes(componentName);
9539
9333
  } catch {
9540
9334
  return false;
@@ -9542,8 +9336,8 @@ function isUsedInLayout(projectRoot, componentName) {
9542
9336
  }
9543
9337
  function findUnregisteredComponents(projectRoot, manifest) {
9544
9338
  const results = [];
9545
- const componentsDir = join12(projectRoot, "components");
9546
- if (!existsSync18(componentsDir)) return results;
9339
+ const componentsDir = join11(projectRoot, "components");
9340
+ if (!existsSync17(componentsDir)) return results;
9547
9341
  const registeredFiles = new Set(manifest.shared.map((s) => s.file));
9548
9342
  const registeredNames = new Set(manifest.shared.map((s) => s.name));
9549
9343
  const files = collectFiles(
@@ -9555,7 +9349,7 @@ function findUnregisteredComponents(projectRoot, manifest) {
9555
9349
  const relFile = relative3(projectRoot, absPath);
9556
9350
  if (registeredFiles.has(relFile)) continue;
9557
9351
  try {
9558
- const code = readFileSync13(absPath, "utf-8");
9352
+ const code = readFileSync12(absPath, "utf-8");
9559
9353
  const exports = extractExportedComponentNames(code);
9560
9354
  for (const name of exports) {
9561
9355
  if (registeredNames.has(name)) continue;
@@ -9570,14 +9364,14 @@ function findUnregisteredComponents(projectRoot, manifest) {
9570
9364
  }
9571
9365
  function findInlineDuplicates(projectRoot, manifest) {
9572
9366
  const results = [];
9573
- const appDir = join12(projectRoot, "app");
9574
- if (!existsSync18(appDir)) return results;
9367
+ const appDir = join11(projectRoot, "app");
9368
+ if (!existsSync17(appDir)) return results;
9575
9369
  const pageFiles = collectFiles(appDir, (name) => name === "page.tsx" || name === "page.jsx");
9576
9370
  for (const absPath of pageFiles) {
9577
9371
  if (absPath.includes("design-system")) continue;
9578
9372
  let code;
9579
9373
  try {
9580
- code = readFileSync13(absPath, "utf-8");
9374
+ code = readFileSync12(absPath, "utf-8");
9581
9375
  } catch {
9582
9376
  continue;
9583
9377
  }
@@ -9600,8 +9394,8 @@ function findInlineDuplicates(projectRoot, manifest) {
9600
9394
  return results;
9601
9395
  }
9602
9396
  function findComponentFileByExportName(projectRoot, componentName) {
9603
- const componentsDir = join12(projectRoot, "components");
9604
- if (!existsSync18(componentsDir)) return null;
9397
+ const componentsDir = join11(projectRoot, "components");
9398
+ if (!existsSync17(componentsDir)) return null;
9605
9399
  const files = collectFiles(
9606
9400
  componentsDir,
9607
9401
  (name) => (name.endsWith(".tsx") || name.endsWith(".jsx")) && !name.startsWith("."),
@@ -9609,7 +9403,7 @@ function findComponentFileByExportName(projectRoot, componentName) {
9609
9403
  );
9610
9404
  for (const absPath of files) {
9611
9405
  try {
9612
- const code = readFileSync13(absPath, "utf-8");
9406
+ const code = readFileSync12(absPath, "utf-8");
9613
9407
  const exports = extractExportedComponentNames(code);
9614
9408
  if (exports.includes(componentName)) {
9615
9409
  return relative3(projectRoot, absPath);
@@ -9622,8 +9416,8 @@ function findComponentFileByExportName(projectRoot, componentName) {
9622
9416
  function removeOrphanedEntries(projectRoot, manifest) {
9623
9417
  const removed = [];
9624
9418
  const valid = manifest.shared.filter((entry) => {
9625
- const filePath = join12(projectRoot, entry.file);
9626
- if (existsSync18(filePath)) return true;
9419
+ const filePath = join11(projectRoot, entry.file);
9420
+ if (existsSync17(filePath)) return true;
9627
9421
  removed.push({ id: entry.id, name: entry.name });
9628
9422
  return false;
9629
9423
  });
@@ -9641,8 +9435,8 @@ function reconcileComponents(projectRoot, manifest) {
9641
9435
  };
9642
9436
  const m = { ...manifest, shared: [...manifest.shared], nextId: manifest.nextId };
9643
9437
  m.shared = m.shared.filter((entry) => {
9644
- const filePath = join12(projectRoot, entry.file);
9645
- if (!existsSync18(filePath)) {
9438
+ const filePath = join11(projectRoot, entry.file);
9439
+ if (!existsSync17(filePath)) {
9646
9440
  const newPath = findComponentFileByExportName(projectRoot, entry.name);
9647
9441
  if (newPath) {
9648
9442
  result.updated.push({ id: entry.id, field: "file", from: entry.file, to: newPath });
@@ -9654,7 +9448,7 @@ function reconcileComponents(projectRoot, manifest) {
9654
9448
  }
9655
9449
  let code;
9656
9450
  try {
9657
- code = readFileSync13(join12(projectRoot, entry.file), "utf-8");
9451
+ code = readFileSync12(join11(projectRoot, entry.file), "utf-8");
9658
9452
  } catch {
9659
9453
  return true;
9660
9454
  }
@@ -9738,7 +9532,7 @@ function collectFiles(dir, filter, skipDirs = []) {
9738
9532
  return;
9739
9533
  }
9740
9534
  for (const e of entries) {
9741
- const full = join12(d, e.name);
9535
+ const full = join11(d, e.name);
9742
9536
  if (e.isDirectory()) {
9743
9537
  if (skipDirs.includes(e.name) || e.name.startsWith(".")) continue;
9744
9538
  walk(full);
@@ -9777,9 +9571,9 @@ function findInlineDuplicatesOfShared(content, manifest) {
9777
9571
  }
9778
9572
  function getWatcherConfig(projectRoot) {
9779
9573
  try {
9780
- const pkgPath = join13(projectRoot, "package.json");
9781
- if (!existsSync19(pkgPath)) return defaultWatcherConfig();
9782
- const pkg = JSON.parse(readFileSync14(pkgPath, "utf-8"));
9574
+ const pkgPath = join12(projectRoot, "package.json");
9575
+ if (!existsSync18(pkgPath)) return defaultWatcherConfig();
9576
+ const pkg = JSON.parse(readFileSync13(pkgPath, "utf-8"));
9783
9577
  const c = pkg?.coherent?.watcher ?? {};
9784
9578
  return {
9785
9579
  enabled: c.enabled !== false,
@@ -9807,7 +9601,7 @@ async function handleFileChange(projectRoot, filePath) {
9807
9601
  if (relativePath.includes("node_modules") || relativePath.includes(".next")) return;
9808
9602
  let content;
9809
9603
  try {
9810
- content = readFileSync14(filePath, "utf-8");
9604
+ content = readFileSync13(filePath, "utf-8");
9811
9605
  } catch {
9812
9606
  return;
9813
9607
  }
@@ -9880,7 +9674,7 @@ async function detectNewComponent(projectRoot, filePath) {
9880
9674
  const manifest = await loadManifest9(projectRoot);
9881
9675
  const alreadyRegistered = manifest.shared.some((s) => s.file === relativePath);
9882
9676
  if (alreadyRegistered) return;
9883
- const code = readFileSync14(filePath, "utf-8");
9677
+ const code = readFileSync13(filePath, "utf-8");
9884
9678
  const exports = extractExportedComponentNames(code);
9885
9679
  if (exports.length > 0) {
9886
9680
  const alreadyByName = exports.every((n) => manifest.shared.some((s) => s.name === n));
@@ -9906,8 +9700,8 @@ function startFileWatcher(projectRoot) {
9906
9700
  let watcher = null;
9907
9701
  let manifestWatcher = null;
9908
9702
  import("chokidar").then((chokidar) => {
9909
- const appGlob = join13(projectRoot, "app", "**", "*.tsx");
9910
- const compGlob = join13(projectRoot, "components", "**", "*.tsx");
9703
+ const appGlob = join12(projectRoot, "app", "**", "*.tsx");
9704
+ const compGlob = join12(projectRoot, "components", "**", "*.tsx");
9911
9705
  watcher = chokidar.default.watch([appGlob, compGlob], {
9912
9706
  ignoreInitial: true,
9913
9707
  awaitWriteFinish: { stabilityThreshold: 500 }
@@ -9919,8 +9713,8 @@ function startFileWatcher(projectRoot) {
9919
9713
  });
9920
9714
  watcher.on("unlink", (fp) => handleFileDelete(projectRoot, fp));
9921
9715
  });
9922
- const manifestPath = join13(projectRoot, "coherent.components.json");
9923
- if (existsSync19(manifestPath)) {
9716
+ const manifestPath = join12(projectRoot, "coherent.components.json");
9717
+ if (existsSync18(manifestPath)) {
9924
9718
  import("chokidar").then((chokidar) => {
9925
9719
  manifestWatcher = chokidar.default.watch(manifestPath, { ignoreInitial: true });
9926
9720
  manifestWatcher.on("change", () => handleManifestChange(projectRoot));
@@ -9934,7 +9728,7 @@ function startFileWatcher(projectRoot) {
9934
9728
 
9935
9729
  // src/commands/preview.ts
9936
9730
  function getPackageManager(projectRoot) {
9937
- const hasPnpm = existsSync20(resolve11(projectRoot, "pnpm-lock.yaml"));
9731
+ const hasPnpm = existsSync19(resolve11(projectRoot, "pnpm-lock.yaml"));
9938
9732
  return hasPnpm ? "pnpm" : "npm";
9939
9733
  }
9940
9734
  function runInstall(projectRoot) {
@@ -9958,21 +9752,21 @@ function runInstall(projectRoot) {
9958
9752
  function checkProjectInitialized(projectRoot) {
9959
9753
  const configPath = resolve11(projectRoot, "design-system.config.ts");
9960
9754
  const packageJsonPath = resolve11(projectRoot, "package.json");
9961
- if (!existsSync20(configPath)) {
9755
+ if (!existsSync19(configPath)) {
9962
9756
  return false;
9963
9757
  }
9964
- if (!existsSync20(packageJsonPath)) {
9758
+ if (!existsSync19(packageJsonPath)) {
9965
9759
  return false;
9966
9760
  }
9967
9761
  return true;
9968
9762
  }
9969
9763
  function checkDependenciesInstalled(projectRoot) {
9970
9764
  const nodeModulesPath = resolve11(projectRoot, "node_modules");
9971
- return existsSync20(nodeModulesPath);
9765
+ return existsSync19(nodeModulesPath);
9972
9766
  }
9973
9767
  function clearStaleCache(projectRoot) {
9974
- const nextDir = join14(projectRoot, ".next");
9975
- if (existsSync20(nextDir)) {
9768
+ const nextDir = join13(projectRoot, ".next");
9769
+ if (existsSync19(nextDir)) {
9976
9770
  rmSync3(nextDir, { recursive: true, force: true });
9977
9771
  console.log(chalk14.dim(" \u2714 Cleared stale build cache"));
9978
9772
  }
@@ -9988,11 +9782,11 @@ async function preflightDependencyCheck(projectRoot) {
9988
9782
  }
9989
9783
  async function listPageFiles(appDir) {
9990
9784
  const out = [];
9991
- if (!existsSync20(appDir)) return out;
9785
+ if (!existsSync19(appDir)) return out;
9992
9786
  async function walk(dir) {
9993
- const entries = await readdir2(dir, { withFileTypes: true });
9787
+ const entries = await readdir(dir, { withFileTypes: true });
9994
9788
  for (const e of entries) {
9995
- const full = join14(dir, e.name);
9789
+ const full = join13(dir, e.name);
9996
9790
  if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "api" && e.name !== "design-system") await walk(full);
9997
9791
  else if (e.isFile() && e.name === "page.tsx") out.push(full);
9998
9792
  }
@@ -10001,10 +9795,10 @@ async function listPageFiles(appDir) {
10001
9795
  return out;
10002
9796
  }
10003
9797
  async function validateSyntax(projectRoot) {
10004
- const appDir = join14(projectRoot, "app");
9798
+ const appDir = join13(projectRoot, "app");
10005
9799
  const pages = await listPageFiles(appDir);
10006
9800
  for (const file of pages) {
10007
- const content = readFileSync15(file, "utf-8");
9801
+ const content = readFileSync14(file, "utf-8");
10008
9802
  const fixed = fixUnescapedLtInJsx(sanitizeMetadataStrings(ensureUseClientIfNeeded(content)));
10009
9803
  if (fixed !== content) {
10010
9804
  writeFileSync10(file, fixed, "utf-8");
@@ -10013,18 +9807,18 @@ async function validateSyntax(projectRoot) {
10013
9807
  }
10014
9808
  }
10015
9809
  async function fixMissingComponentExports(projectRoot) {
10016
- const appDir = join14(projectRoot, "app");
10017
- const uiDir = join14(projectRoot, "components", "ui");
10018
- if (!existsSync20(appDir) || !existsSync20(uiDir)) return;
9810
+ const appDir = join13(projectRoot, "app");
9811
+ const uiDir = join13(projectRoot, "components", "ui");
9812
+ if (!existsSync19(appDir) || !existsSync19(uiDir)) return;
10019
9813
  const pages = await listPageFiles(appDir);
10020
- const sharedDir = join14(projectRoot, "components", "shared");
10021
- if (existsSync20(sharedDir)) {
10022
- const sharedFiles = readdirSync6(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => join14(sharedDir, f));
9814
+ const sharedDir = join13(projectRoot, "components", "shared");
9815
+ if (existsSync19(sharedDir)) {
9816
+ const sharedFiles = readdirSync6(sharedDir).filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => join13(sharedDir, f));
10023
9817
  pages.push(...sharedFiles);
10024
9818
  }
10025
9819
  const neededExports = /* @__PURE__ */ new Map();
10026
9820
  for (const file of pages) {
10027
- const content = readFileSync15(file, "utf-8");
9821
+ const content = readFileSync14(file, "utf-8");
10028
9822
  const importRe = /import\s*\{([^}]+)\}\s*from\s*['"]@\/components\/ui\/([^'"]+)['"]/g;
10029
9823
  let m;
10030
9824
  while ((m = importRe.exec(content)) !== null) {
@@ -10034,7 +9828,7 @@ async function fixMissingComponentExports(projectRoot) {
10034
9828
  for (const name of names) neededExports.get(componentId).add(name);
10035
9829
  }
10036
9830
  }
10037
- const configPath = join14(projectRoot, "design-system.config.ts");
9831
+ const configPath = join13(projectRoot, "design-system.config.ts");
10038
9832
  let config2 = null;
10039
9833
  try {
10040
9834
  const mgr = new DesignSystemManager8(configPath);
@@ -10044,8 +9838,8 @@ async function fixMissingComponentExports(projectRoot) {
10044
9838
  const generator = new ComponentGenerator3(config2 || { components: [], pages: [], tokens: {} });
10045
9839
  const provider = getComponentProvider();
10046
9840
  for (const [componentId, needed] of neededExports) {
10047
- const componentFile = join14(uiDir, `${componentId}.tsx`);
10048
- if (!existsSync20(componentFile)) {
9841
+ const componentFile = join13(uiDir, `${componentId}.tsx`);
9842
+ if (!existsSync19(componentFile)) {
10049
9843
  if (provider.has(componentId)) {
10050
9844
  try {
10051
9845
  const result = await provider.installComponent(componentId, projectRoot);
@@ -10068,7 +9862,7 @@ async function fixMissingComponentExports(projectRoot) {
10068
9862
  }
10069
9863
  continue;
10070
9864
  }
10071
- const content = readFileSync15(componentFile, "utf-8");
9865
+ const content = readFileSync14(componentFile, "utf-8");
10072
9866
  const exportRe = /export\s+(?:const|function|class)\s+(\w+)|export\s*\{([^}]+)\}/g;
10073
9867
  const existingExports = /* @__PURE__ */ new Set();
10074
9868
  let em;
@@ -10102,7 +9896,7 @@ async function fixMissingComponentExports(projectRoot) {
10102
9896
  }
10103
9897
  const neededSharedExports = /* @__PURE__ */ new Map();
10104
9898
  for (const file of pages) {
10105
- const content = readFileSync15(file, "utf-8");
9899
+ const content = readFileSync14(file, "utf-8");
10106
9900
  const sharedImportRe = /import\s*\{([^}]+)\}\s*from\s*['"]@\/components\/shared\/([^'"]+)['"]/g;
10107
9901
  let sm;
10108
9902
  while ((sm = sharedImportRe.exec(content)) !== null) {
@@ -10113,9 +9907,9 @@ async function fixMissingComponentExports(projectRoot) {
10113
9907
  }
10114
9908
  }
10115
9909
  for (const [componentId, needed] of neededSharedExports) {
10116
- const componentFile = join14(sharedDir, `${componentId}.tsx`);
10117
- if (!existsSync20(componentFile)) continue;
10118
- let content = readFileSync15(componentFile, "utf-8");
9910
+ const componentFile = join13(sharedDir, `${componentId}.tsx`);
9911
+ if (!existsSync19(componentFile)) continue;
9912
+ let content = readFileSync14(componentFile, "utf-8");
10119
9913
  const exportRe = /export\s+(?:const|function|class)\s+(\w+)|export\s*\{([^}]+)\}/g;
10120
9914
  const existingExports = /* @__PURE__ */ new Set();
10121
9915
  let em;
@@ -10137,8 +9931,8 @@ async function fixMissingComponentExports(projectRoot) {
10137
9931
  }
10138
9932
  }
10139
9933
  async function backfillPageAnalysis(projectRoot) {
10140
- const configPath = join14(projectRoot, "design-system.config.ts");
10141
- if (!existsSync20(configPath)) return;
9934
+ const configPath = join13(projectRoot, "design-system.config.ts");
9935
+ if (!existsSync19(configPath)) return;
10142
9936
  try {
10143
9937
  const mgr = new DesignSystemManager8(configPath);
10144
9938
  const config2 = mgr.getConfig();
@@ -10149,14 +9943,14 @@ async function backfillPageAnalysis(projectRoot) {
10149
9943
  const isAuth = route.includes("login") || route.includes("register") || route.includes("signup") || route.includes("sign-up");
10150
9944
  let filePath;
10151
9945
  if (route === "/") {
10152
- filePath = join14(projectRoot, "app", "page.tsx");
9946
+ filePath = join13(projectRoot, "app", "page.tsx");
10153
9947
  } else if (isAuth) {
10154
- filePath = join14(projectRoot, "app", "(auth)", route.slice(1), "page.tsx");
9948
+ filePath = join13(projectRoot, "app", "(auth)", route.slice(1), "page.tsx");
10155
9949
  } else {
10156
- filePath = join14(projectRoot, "app", route.slice(1), "page.tsx");
9950
+ filePath = join13(projectRoot, "app", route.slice(1), "page.tsx");
10157
9951
  }
10158
- if (!existsSync20(filePath)) continue;
10159
- const code = readFileSync15(filePath, "utf-8");
9952
+ if (!existsSync19(filePath)) continue;
9953
+ const code = readFileSync14(filePath, "utf-8");
10160
9954
  if (code.length < 50) continue;
10161
9955
  page.pageAnalysis = analyzePageCode(code);
10162
9956
  changed = true;
@@ -10307,11 +10101,11 @@ async function openBrowser(url) {
10307
10101
  }
10308
10102
  function startDevServer(projectRoot) {
10309
10103
  const packageJsonPath = resolve11(projectRoot, "package.json");
10310
- if (!existsSync20(packageJsonPath)) {
10104
+ if (!existsSync19(packageJsonPath)) {
10311
10105
  throw new Error('package.json not found. Run "coherent init" first.');
10312
10106
  }
10313
- const hasPnpm = existsSync20(resolve11(projectRoot, "pnpm-lock.yaml"));
10314
- const hasNpm = existsSync20(resolve11(projectRoot, "package-lock.json"));
10107
+ const hasPnpm = existsSync19(resolve11(projectRoot, "pnpm-lock.yaml"));
10108
+ const hasNpm = existsSync19(resolve11(projectRoot, "package-lock.json"));
10315
10109
  const command = hasPnpm ? "pnpm" : hasNpm ? "npm" : "npx";
10316
10110
  const args = hasPnpm ? ["dev", "--turbo"] : hasNpm ? ["run", "dev", "--", "--turbo"] : ["next", "dev", "--turbo"];
10317
10111
  const child = spawn(command, args, {
@@ -10369,8 +10163,8 @@ async function previewCommand() {
10369
10163
  }
10370
10164
  if (isTailwindV4(projectRoot)) {
10371
10165
  const globalsPath = resolve11(projectRoot, "app", "globals.css");
10372
- if (existsSync20(globalsPath)) {
10373
- const globalsContent = readFileSync15(globalsPath, "utf-8");
10166
+ if (existsSync19(globalsPath)) {
10167
+ const globalsContent = readFileSync14(globalsPath, "utf-8");
10374
10168
  const cssIssues = validateV4GlobalsCss(globalsContent);
10375
10169
  if (cssIssues.length > 0) {
10376
10170
  console.log(chalk14.yellow("\n\u26A0\uFE0F globals.css validation warnings:"));
@@ -10411,9 +10205,9 @@ async function previewCommand() {
10411
10205
  import chalk15 from "chalk";
10412
10206
  import ora4 from "ora";
10413
10207
  import { spawn as spawn2 } from "child_process";
10414
- import { existsSync as existsSync21, rmSync as rmSync4, readdirSync as readdirSync7 } from "fs";
10415
- import { resolve as resolve12, join as join15, dirname as dirname7 } from "path";
10416
- import { readdir as readdir3, readFile as readFile6, writeFile as writeFile5, mkdir as mkdir5, copyFile as copyFile2 } from "fs/promises";
10208
+ import { existsSync as existsSync20, rmSync as rmSync4, readdirSync as readdirSync7 } from "fs";
10209
+ import { resolve as resolve12, join as join14, dirname as dirname7 } from "path";
10210
+ import { readdir as readdir2, readFile as readFile5, writeFile as writeFile5, mkdir as mkdir5, copyFile as copyFile2 } from "fs/promises";
10417
10211
  var COPY_EXCLUDE = /* @__PURE__ */ new Set([
10418
10212
  "node_modules",
10419
10213
  ".next",
@@ -10432,10 +10226,10 @@ var COPY_EXCLUDE = /* @__PURE__ */ new Set([
10432
10226
  ]);
10433
10227
  async function copyDir(src, dest) {
10434
10228
  await mkdir5(dest, { recursive: true });
10435
- const entries = await readdir3(src, { withFileTypes: true });
10229
+ const entries = await readdir2(src, { withFileTypes: true });
10436
10230
  for (const e of entries) {
10437
- const srcPath = join15(src, e.name);
10438
- const destPath = join15(dest, e.name);
10231
+ const srcPath = join14(src, e.name);
10232
+ const destPath = join14(dest, e.name);
10439
10233
  if (COPY_EXCLUDE.has(e.name)) continue;
10440
10234
  if (e.isDirectory()) {
10441
10235
  await copyDir(srcPath, destPath);
@@ -10446,18 +10240,18 @@ async function copyDir(src, dest) {
10446
10240
  }
10447
10241
  }
10448
10242
  function checkProjectInitialized2(projectRoot) {
10449
- return existsSync21(resolve12(projectRoot, "design-system.config.ts")) && existsSync21(resolve12(projectRoot, "package.json"));
10243
+ return existsSync20(resolve12(projectRoot, "design-system.config.ts")) && existsSync20(resolve12(projectRoot, "package.json"));
10450
10244
  }
10451
10245
  function getPackageManager2(projectRoot) {
10452
- if (existsSync21(resolve12(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
10453
- if (existsSync21(resolve12(projectRoot, "package-lock.json"))) return "npm";
10246
+ if (existsSync20(resolve12(projectRoot, "pnpm-lock.yaml"))) return "pnpm";
10247
+ if (existsSync20(resolve12(projectRoot, "package-lock.json"))) return "npm";
10454
10248
  return "npx";
10455
10249
  }
10456
10250
  async function patchNextConfigForExport(outRoot) {
10457
10251
  for (const name of ["next.config.ts", "next.config.mjs", "next.config.js"]) {
10458
- const p = join15(outRoot, name);
10459
- if (!existsSync21(p)) continue;
10460
- let content = await readFile6(p, "utf-8");
10252
+ const p = join14(outRoot, name);
10253
+ if (!existsSync20(p)) continue;
10254
+ let content = await readFile5(p, "utf-8");
10461
10255
  if (content.includes("ignoreDuringBuilds")) return;
10462
10256
  content = content.replace(
10463
10257
  /(const\s+nextConfig\s*(?::\s*\w+)?\s*=\s*\{)/,
@@ -10497,10 +10291,10 @@ EXPOSE 3000
10497
10291
  \`\`\`
10498
10292
  `;
10499
10293
  async function ensureReadmeDeploySection(outRoot) {
10500
- const readmePath = join15(outRoot, "README.md");
10501
- if (!existsSync21(readmePath)) return;
10294
+ const readmePath = join14(outRoot, "README.md");
10295
+ if (!existsSync20(readmePath)) return;
10502
10296
  try {
10503
- let content = await readFile6(readmePath, "utf-8");
10297
+ let content = await readFile5(readmePath, "utf-8");
10504
10298
  if (/##\s+Deploy\b/m.test(content)) return;
10505
10299
  content = content.trimEnd() + DEPLOY_SECTION + "\n";
10506
10300
  await writeFile5(readmePath, content);
@@ -10512,25 +10306,25 @@ async function countPages(outRoot) {
10512
10306
  async function walk(dir) {
10513
10307
  let entries;
10514
10308
  try {
10515
- entries = await readdir3(dir, { withFileTypes: true });
10309
+ entries = await readdir2(dir, { withFileTypes: true });
10516
10310
  } catch {
10517
10311
  return;
10518
10312
  }
10519
10313
  for (const e of entries) {
10520
- const full = join15(dir, e.name);
10314
+ const full = join14(dir, e.name);
10521
10315
  if (e.isFile() && e.name === "page.tsx") n++;
10522
10316
  else if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "api") await walk(full);
10523
10317
  }
10524
10318
  }
10525
- const appDir = join15(outRoot, "app");
10526
- if (existsSync21(appDir)) await walk(appDir);
10319
+ const appDir = join14(outRoot, "app");
10320
+ if (existsSync20(appDir)) await walk(appDir);
10527
10321
  return n;
10528
10322
  }
10529
10323
  function countComponents(outRoot) {
10530
10324
  let n = 0;
10531
10325
  for (const sub of ["ui", "shared"]) {
10532
- const dir = join15(outRoot, "components", sub);
10533
- if (!existsSync21(dir)) continue;
10326
+ const dir = join14(outRoot, "components", sub);
10327
+ if (!existsSync20(dir)) continue;
10534
10328
  try {
10535
10329
  n += readdirSync7(dir).filter((f) => f.endsWith(".tsx") || f.endsWith(".jsx")).length;
10536
10330
  } catch {
@@ -10538,14 +10332,14 @@ function countComponents(outRoot) {
10538
10332
  }
10539
10333
  return n;
10540
10334
  }
10541
- var IMPORT_FROM_REGEX2 = /from\s+['"]([^'"]+)['"]/g;
10542
- async function collectImportedPackages2(dir, extensions) {
10335
+ var IMPORT_FROM_REGEX = /from\s+['"]([^'"]+)['"]/g;
10336
+ async function collectImportedPackages(dir, extensions) {
10543
10337
  const packages = /* @__PURE__ */ new Set();
10544
- if (!existsSync21(dir)) return packages;
10338
+ if (!existsSync20(dir)) return packages;
10545
10339
  async function walk(d) {
10546
- const entries = await readdir3(d, { withFileTypes: true });
10340
+ const entries = await readdir2(d, { withFileTypes: true });
10547
10341
  for (const e of entries) {
10548
- const full = join15(d, e.name);
10342
+ const full = join14(d, e.name);
10549
10343
  if (e.isDirectory() && !e.name.startsWith(".") && e.name !== "node_modules") {
10550
10344
  await walk(full);
10551
10345
  continue;
@@ -10553,10 +10347,10 @@ async function collectImportedPackages2(dir, extensions) {
10553
10347
  if (!e.isFile()) continue;
10554
10348
  const ext = e.name.replace(/^.*\./, "");
10555
10349
  if (!extensions.has(ext)) continue;
10556
- const content = await readFile6(full, "utf-8").catch(() => "");
10350
+ const content = await readFile5(full, "utf-8").catch(() => "");
10557
10351
  let m;
10558
- IMPORT_FROM_REGEX2.lastIndex = 0;
10559
- while ((m = IMPORT_FROM_REGEX2.exec(content)) !== null) {
10352
+ IMPORT_FROM_REGEX.lastIndex = 0;
10353
+ while ((m = IMPORT_FROM_REGEX.exec(content)) !== null) {
10560
10354
  const spec = m[1];
10561
10355
  if (spec.startsWith(".") || spec.startsWith("/") || spec.startsWith("@/")) continue;
10562
10356
  const pkg = spec.startsWith("@") ? spec.split("/").slice(0, 2).join("/") : spec.split("/")[0];
@@ -10568,64 +10362,64 @@ async function collectImportedPackages2(dir, extensions) {
10568
10362
  return packages;
10569
10363
  }
10570
10364
  async function findMissingDepsInExport(outRoot) {
10571
- const pkgPath = join15(outRoot, "package.json");
10572
- if (!existsSync21(pkgPath)) return [];
10365
+ const pkgPath = join14(outRoot, "package.json");
10366
+ if (!existsSync20(pkgPath)) return [];
10573
10367
  let pkg;
10574
10368
  try {
10575
- pkg = JSON.parse(await readFile6(pkgPath, "utf-8"));
10369
+ pkg = JSON.parse(await readFile5(pkgPath, "utf-8"));
10576
10370
  } catch {
10577
10371
  return [];
10578
10372
  }
10579
10373
  const inDeps = /* @__PURE__ */ new Set([...Object.keys(pkg.dependencies ?? {}), ...Object.keys(pkg.devDependencies ?? {})]);
10580
- const codeDirs = [join15(outRoot, "app"), join15(outRoot, "components")];
10374
+ const codeDirs = [join14(outRoot, "app"), join14(outRoot, "components")];
10581
10375
  const extensions = /* @__PURE__ */ new Set(["ts", "tsx", "js", "jsx"]);
10582
10376
  const imported = /* @__PURE__ */ new Set();
10583
10377
  for (const dir of codeDirs) {
10584
10378
  ;
10585
- (await collectImportedPackages2(dir, extensions)).forEach((p) => imported.add(p));
10379
+ (await collectImportedPackages(dir, extensions)).forEach((p) => imported.add(p));
10586
10380
  }
10587
10381
  return [...imported].filter((p) => !inDeps.has(p)).sort();
10588
10382
  }
10589
10383
  async function stripCoherentArtifacts(outputDir) {
10590
10384
  const removed = [];
10591
10385
  for (const p of ["app/design-system", "app/api/design-system"]) {
10592
- const full = join15(outputDir, p);
10593
- if (existsSync21(full)) {
10386
+ const full = join14(outputDir, p);
10387
+ if (existsSync20(full)) {
10594
10388
  rmSync4(full, { recursive: true, force: true });
10595
10389
  removed.push(p);
10596
10390
  }
10597
10391
  }
10598
- const appNavPath = join15(outputDir, "app", "AppNav.tsx");
10599
- if (existsSync21(appNavPath)) {
10392
+ const appNavPath = join14(outputDir, "app", "AppNav.tsx");
10393
+ if (existsSync20(appNavPath)) {
10600
10394
  rmSync4(appNavPath, { force: true });
10601
10395
  removed.push("app/AppNav.tsx");
10602
10396
  }
10603
- const layoutPath = join15(outputDir, "app", "layout.tsx");
10604
- if (existsSync21(layoutPath)) {
10605
- let layout = await readFile6(layoutPath, "utf-8");
10397
+ const layoutPath = join14(outputDir, "app", "layout.tsx");
10398
+ if (existsSync20(layoutPath)) {
10399
+ let layout = await readFile5(layoutPath, "utf-8");
10606
10400
  layout = layout.replace(/import\s*\{?\s*AppNav\s*\}?\s*from\s*['"][^'"]+['"]\s*\n?/g, "");
10607
10401
  layout = layout.replace(/\s*<AppNav\s*\/?\s*>\s*/g, "\n");
10608
10402
  await writeFile5(layoutPath, layout, "utf-8");
10609
10403
  }
10610
- const sharedHeaderPath = join15(outputDir, "components", "shared", "header.tsx");
10611
- if (existsSync21(sharedHeaderPath)) {
10612
- let header = await readFile6(sharedHeaderPath, "utf-8");
10404
+ const sharedHeaderPath = join14(outputDir, "components", "shared", "header.tsx");
10405
+ if (existsSync20(sharedHeaderPath)) {
10406
+ let header = await readFile5(sharedHeaderPath, "utf-8");
10613
10407
  header = header.replace(/<Link\s[^>]*href="\/design-system"[^>]*>[\s\S]*?<\/Link>/g, "");
10614
10408
  header = header.replace(/\n\s*<>\s*\n/, "\n");
10615
10409
  header = header.replace(/\n\s*<\/>\s*\n/, "\n");
10616
10410
  await writeFile5(sharedHeaderPath, header, "utf-8");
10617
10411
  }
10618
- const guardPath2 = join15(outputDir, "app", "ShowWhenNotAuthRoute.tsx");
10619
- if (existsSync21(guardPath2)) {
10620
- let guard = await readFile6(guardPath2, "utf-8");
10412
+ const guardPath2 = join14(outputDir, "app", "ShowWhenNotAuthRoute.tsx");
10413
+ if (existsSync20(guardPath2)) {
10414
+ let guard = await readFile5(guardPath2, "utf-8");
10621
10415
  guard = guard.replace(/['"],?\s*'\/design-system['"],?\s*/g, "");
10622
10416
  const pathsMatch = guard.match(/HIDDEN_PATHS\s*=\s*\[([^\]]*)\]/);
10623
10417
  const remaining = pathsMatch ? pathsMatch[1].replace(/['"]/g, "").split(",").map((s) => s.trim()).filter(Boolean) : [];
10624
10418
  if (remaining.length === 0) {
10625
10419
  rmSync4(guardPath2, { force: true });
10626
10420
  removed.push("app/ShowWhenNotAuthRoute.tsx");
10627
- if (existsSync21(layoutPath)) {
10628
- let layout = await readFile6(layoutPath, "utf-8");
10421
+ if (existsSync20(layoutPath)) {
10422
+ let layout = await readFile5(layoutPath, "utf-8");
10629
10423
  layout = layout.replace(/import\s+\w+\s+from\s*['"]\.\/ShowWhenNotAuthRoute['"]\s*\n?/g, "");
10630
10424
  layout = layout.replace(/\s*<ShowWhenNotAuthRoute>\s*\n?/g, "\n");
10631
10425
  layout = layout.replace(/\s*<\/ShowWhenNotAuthRoute>\s*\n?/g, "\n");
@@ -10644,15 +10438,15 @@ async function stripCoherentArtifacts(outputDir) {
10644
10438
  ".env.local",
10645
10439
  "recommendations.md"
10646
10440
  ]) {
10647
- const full = join15(outputDir, name);
10648
- if (existsSync21(full)) {
10441
+ const full = join14(outputDir, name);
10442
+ if (existsSync20(full)) {
10649
10443
  rmSync4(full, { force: true });
10650
10444
  removed.push(name);
10651
10445
  }
10652
10446
  }
10653
10447
  for (const dir of [".claude", ".coherent"]) {
10654
- const full = join15(outputDir, dir);
10655
- if (existsSync21(full)) {
10448
+ const full = join14(outputDir, dir);
10449
+ if (existsSync20(full)) {
10656
10450
  rmSync4(full, { recursive: true, force: true });
10657
10451
  removed.push(dir + "/");
10658
10452
  }
@@ -10676,7 +10470,7 @@ async function exportCommand(options = {}) {
10676
10470
  process.exit(1);
10677
10471
  }
10678
10472
  spinner.text = "Copying project...";
10679
- if (existsSync21(outputDir)) rmSync4(outputDir, { recursive: true, force: true });
10473
+ if (existsSync20(outputDir)) rmSync4(outputDir, { recursive: true, force: true });
10680
10474
  await copyDir(projectRoot, outputDir);
10681
10475
  spinner.succeed("Project copied");
10682
10476
  if (!keepDs) {
@@ -10851,8 +10645,8 @@ async function regenerateDocsCommand() {
10851
10645
 
10852
10646
  // src/commands/fix.ts
10853
10647
  import chalk18 from "chalk";
10854
- import { readdirSync as readdirSync8, readFileSync as readFileSync16, existsSync as existsSync22, writeFileSync as writeFileSync11, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
10855
- import { resolve as resolve13, join as join16 } from "path";
10648
+ import { readdirSync as readdirSync8, readFileSync as readFileSync15, existsSync as existsSync21, writeFileSync as writeFileSync11, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
10649
+ import { resolve as resolve13, join as join15 } from "path";
10856
10650
  import {
10857
10651
  DesignSystemManager as DesignSystemManager11,
10858
10652
  ComponentManager as ComponentManager6,
@@ -10878,7 +10672,7 @@ function listTsxFiles(dir) {
10878
10672
  try {
10879
10673
  const entries = readdirSync8(dir, { withFileTypes: true });
10880
10674
  for (const e of entries) {
10881
- const full = join16(dir, e.name);
10675
+ const full = join15(dir, e.name);
10882
10676
  if (e.isDirectory() && e.name !== "node_modules" && !e.name.startsWith(".")) {
10883
10677
  files.push(...listTsxFiles(full));
10884
10678
  } else if (e.isFile() && e.name.endsWith(".tsx")) {
@@ -10907,8 +10701,8 @@ async function fixCommand(opts = {}) {
10907
10701
  console.log(chalk18.cyan("\ncoherent fix\n"));
10908
10702
  }
10909
10703
  if (!skipCache) {
10910
- const nextDir = join16(projectRoot, ".next");
10911
- if (existsSync22(nextDir)) {
10704
+ const nextDir = join15(projectRoot, ".next");
10705
+ if (existsSync21(nextDir)) {
10912
10706
  if (!dryRun) rmSync5(nextDir, { recursive: true, force: true });
10913
10707
  fixes.push("Cleared build cache");
10914
10708
  console.log(chalk18.green(" \u2714 Cleared build cache"));
@@ -10935,7 +10729,7 @@ async function fixCommand(opts = {}) {
10935
10729
  const componentsTsxFiles = listTsxFiles(resolve13(projectRoot, "components"));
10936
10730
  const allComponentIds = /* @__PURE__ */ new Set();
10937
10731
  for (const file of [...allTsxFiles, ...componentsTsxFiles]) {
10938
- const content = readFileSync16(file, "utf-8");
10732
+ const content = readFileSync15(file, "utf-8");
10939
10733
  extractComponentIdsFromCode2(content).forEach((id) => allComponentIds.add(id));
10940
10734
  }
10941
10735
  let dsm = null;
@@ -10955,7 +10749,7 @@ async function fixCommand(opts = {}) {
10955
10749
  } else {
10956
10750
  const fileName = toKebabCase(id) + ".tsx";
10957
10751
  const filePath = resolve13(projectRoot, "components", "ui", fileName);
10958
- if (!existsSync22(filePath)) missingFiles.push(id);
10752
+ if (!existsSync21(filePath)) missingFiles.push(id);
10959
10753
  }
10960
10754
  }
10961
10755
  const provider = getComponentProvider();
@@ -11007,7 +10801,7 @@ async function fixCommand(opts = {}) {
11007
10801
  const userTsxFiles = allTsxFiles.filter((f) => !f.includes("/design-system/"));
11008
10802
  let syntaxFixed = 0;
11009
10803
  for (const file of userTsxFiles) {
11010
- const content = readFileSync16(file, "utf-8");
10804
+ const content = readFileSync15(file, "utf-8");
11011
10805
  const fixed = fixUnescapedLtInJsx(
11012
10806
  fixEscapedClosingQuotes(sanitizeMetadataStrings(ensureUseClientIfNeeded(content)))
11013
10807
  );
@@ -11025,7 +10819,7 @@ async function fixCommand(opts = {}) {
11025
10819
  let qualityFixCount = 0;
11026
10820
  const qualityFixDetails = [];
11027
10821
  for (const file of userTsxFiles) {
11028
- const content = readFileSync16(file, "utf-8");
10822
+ const content = readFileSync15(file, "utf-8");
11029
10823
  const { code: autoFixed, fixes: fileFixes } = await autoFixCode(content);
11030
10824
  if (autoFixed !== content) {
11031
10825
  if (!dryRun) writeFileSync11(file, autoFixed, "utf-8");
@@ -11044,7 +10838,7 @@ async function fixCommand(opts = {}) {
11044
10838
  let totalWarnings = 0;
11045
10839
  const fileIssues = [];
11046
10840
  for (const file of allTsxFiles) {
11047
- const code = dryRun ? readFileSync16(file, "utf-8") : readFileSync16(file, "utf-8");
10841
+ const code = dryRun ? readFileSync15(file, "utf-8") : readFileSync15(file, "utf-8");
11048
10842
  const relativePath = file.replace(projectRoot + "/", "");
11049
10843
  const baseName = file.split("/").pop() || "";
11050
10844
  const isAuthPage = relativePath.includes("(auth)");
@@ -11169,7 +10963,7 @@ async function fixCommand(opts = {}) {
11169
10963
  // src/commands/check.ts
11170
10964
  import chalk19 from "chalk";
11171
10965
  import { resolve as resolve14 } from "path";
11172
- import { readdirSync as readdirSync9, readFileSync as readFileSync17, statSync as statSync3, existsSync as existsSync23 } from "fs";
10966
+ import { readdirSync as readdirSync9, readFileSync as readFileSync16, statSync as statSync3, existsSync as existsSync22 } from "fs";
11173
10967
  import { loadManifest as loadManifest11 } from "@getcoherent/core";
11174
10968
  var EXCLUDED_DIRS = /* @__PURE__ */ new Set(["node_modules", "design-system"]);
11175
10969
  function findTsxFiles(dir) {
@@ -11226,7 +11020,7 @@ async function checkCommand(opts = {}) {
11226
11020
  "NATIVE_TABLE"
11227
11021
  ]);
11228
11022
  for (const file of files) {
11229
- const code = readFileSync17(file, "utf-8");
11023
+ const code = readFileSync16(file, "utf-8");
11230
11024
  const relativePath = file.replace(projectRoot + "/", "");
11231
11025
  const baseName = file.split("/").pop() || "";
11232
11026
  const isAuthPage = relativePath.includes("(auth)");
@@ -11268,7 +11062,7 @@ async function checkCommand(opts = {}) {
11268
11062
  routeSet.add("/");
11269
11063
  routeSet.add("#");
11270
11064
  for (const file of files) {
11271
- const code = readFileSync17(file, "utf-8");
11065
+ const code = readFileSync16(file, "utf-8");
11272
11066
  const relativePath = file.replace(projectRoot + "/", "");
11273
11067
  const lines = code.split("\n");
11274
11068
  const linkHrefRe = /href\s*=\s*["'](\/[a-z0-9/-]*)["']/gi;
@@ -11301,7 +11095,7 @@ async function checkCommand(opts = {}) {
11301
11095
  if (manifest.shared.length > 0) {
11302
11096
  for (const entry of manifest.shared) {
11303
11097
  const fullPath = resolve14(project.root, entry.file);
11304
- if (!existsSync23(fullPath)) {
11098
+ if (!existsSync22(fullPath)) {
11305
11099
  result.pages.withErrors++;
11306
11100
  if (!opts.json) console.log(chalk19.red(`
11307
11101
  \u2717 Missing shared component file: ${entry.id} (${entry.file})`));
@@ -11326,7 +11120,7 @@ async function checkCommand(opts = {}) {
11326
11120
  let _nameMismatch = 0;
11327
11121
  for (const entry of manifest.shared) {
11328
11122
  const filePath = resolve14(projectRoot, entry.file);
11329
- const fileExists = existsSync23(filePath);
11123
+ const fileExists = existsSync22(filePath);
11330
11124
  if (!fileExists) {
11331
11125
  _orphaned++;
11332
11126
  if (!opts.json) {
@@ -11336,7 +11130,7 @@ async function checkCommand(opts = {}) {
11336
11130
  continue;
11337
11131
  }
11338
11132
  try {
11339
- const code = readFileSync17(filePath, "utf-8");
11133
+ const code = readFileSync16(filePath, "utf-8");
11340
11134
  const actualExports = extractExportedComponentNames(code);
11341
11135
  if (actualExports.length > 0 && !actualExports.includes(entry.name)) {
11342
11136
  _nameMismatch++;
@@ -11404,7 +11198,7 @@ async function checkCommand(opts = {}) {
11404
11198
  id: e.id,
11405
11199
  name: e.name,
11406
11200
  type: e.type,
11407
- status: existsSync23(resolve14(projectRoot, e.file)) ? "ok" : "unused",
11201
+ status: existsSync22(resolve14(projectRoot, e.file)) ? "ok" : "unused",
11408
11202
  message: "",
11409
11203
  suggestions: void 0
11410
11204
  }))
@@ -11418,11 +11212,11 @@ async function checkCommand(opts = {}) {
11418
11212
  const { inferPageTypeFromRoute: inferPageTypeFromRoute2 } = await import("./design-constraints-EIP2XM7T.js");
11419
11213
  const manifest = await loadManifest11(projectRoot);
11420
11214
  const appDir = resolve14(projectRoot, "app");
11421
- const pageFiles = existsSync23(appDir) ? findTsxFiles(appDir) : [];
11215
+ const pageFiles = existsSync22(appDir) ? findTsxFiles(appDir) : [];
11422
11216
  if (manifest.shared.length > 0 && pageFiles.length > 0) {
11423
11217
  const reuseWarnings = [];
11424
11218
  for (const file of pageFiles) {
11425
- const code = readFileSync17(file, "utf-8");
11219
+ const code = readFileSync16(file, "utf-8");
11426
11220
  const relativePath = file.replace(projectRoot + "/", "");
11427
11221
  const route = "/" + relativePath.replace(/^app\//, "").replace(/\/page\.tsx$/, "").replace(/^\(.*?\)\//, "");
11428
11222
  const pageType = inferPageTypeFromRoute2(route);
@@ -11533,12 +11327,12 @@ import {
11533
11327
  generateSharedComponent as generateSharedComponent5,
11534
11328
  integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout3
11535
11329
  } from "@getcoherent/core";
11536
- import { existsSync as existsSync24 } from "fs";
11330
+ import { existsSync as existsSync23 } from "fs";
11537
11331
  import { resolve as resolve15 } from "path";
11538
11332
 
11539
11333
  // src/utils/ds-files.ts
11540
11334
  import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
11541
- import { join as join17, dirname as dirname8 } from "path";
11335
+ import { join as join16, dirname as dirname8 } from "path";
11542
11336
  import { DesignSystemGenerator } from "@getcoherent/core";
11543
11337
  var SHARED_DS_KEYS = [
11544
11338
  "app/design-system/shared/page.tsx",
@@ -11552,7 +11346,7 @@ async function writeDesignSystemFiles(projectRoot, config2, options) {
11552
11346
  const toWrite = options?.sharedOnly ? new Map([...files].filter(([path4]) => SHARED_DS_KEYS.includes(path4))) : files;
11553
11347
  const written = [];
11554
11348
  for (const [relativePath, content] of toWrite) {
11555
- const fullPath = join17(projectRoot, relativePath);
11349
+ const fullPath = join16(projectRoot, relativePath);
11556
11350
  await mkdir6(dirname8(fullPath), { recursive: true });
11557
11351
  await writeFile6(fullPath, content, "utf-8");
11558
11352
  written.push(relativePath);
@@ -11688,7 +11482,7 @@ function createComponentsCommand() {
11688
11482
  if (updated) console.log(chalk25.cyan(" Updated app/layout.tsx to use shared layout components.\n"));
11689
11483
  }
11690
11484
  const sharedPagePath = resolve15(project.root, "app/design-system/shared/page.tsx");
11691
- if (!existsSync24(sharedPagePath)) {
11485
+ if (!existsSync23(sharedPagePath)) {
11692
11486
  try {
11693
11487
  const dsm = new DesignSystemManager12(project.configPath);
11694
11488
  await dsm.load();
@@ -11714,8 +11508,8 @@ function createComponentsCommand() {
11714
11508
  import chalk26 from "chalk";
11715
11509
  import ora6 from "ora";
11716
11510
  import { writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
11717
- import { resolve as resolve16, join as join18, dirname as dirname9 } from "path";
11718
- import { existsSync as existsSync25 } from "fs";
11511
+ import { resolve as resolve16, join as join17, dirname as dirname9 } from "path";
11512
+ import { existsSync as existsSync24 } from "fs";
11719
11513
  import {
11720
11514
  FigmaClient,
11721
11515
  parseFigmaFileResponse,
@@ -11862,7 +11656,7 @@ async function importFigmaAction(urlOrKey, opts) {
11862
11656
  stats.filesWritten.push(filePath);
11863
11657
  return;
11864
11658
  }
11865
- const fullPath = join18(projectRoot, filePath);
11659
+ const fullPath = join17(projectRoot, filePath);
11866
11660
  await mkdir7(dirname9(fullPath), { recursive: true });
11867
11661
  await writeFile7(fullPath, content, "utf-8");
11868
11662
  stats.filesWritten.push(filePath);
@@ -11964,7 +11758,7 @@ async function importFigmaAction(urlOrKey, opts) {
11964
11758
  spinner.start("Updating design-system.config.ts...");
11965
11759
  const configPath = resolve16(projectRoot, DESIGN_SYSTEM_CONFIG_PATH);
11966
11760
  const dsm = new DesignSystemManager13(configPath);
11967
- if (existsSync25(configPath)) {
11761
+ if (existsSync24(configPath)) {
11968
11762
  await dsm.load();
11969
11763
  const existing = dsm.getConfig();
11970
11764
  dsm.updateConfig({
@@ -11993,8 +11787,8 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
11993
11787
  stats.configUpdated = true;
11994
11788
  spinner.succeed("design-system.config.ts updated");
11995
11789
  spinner.start("Ensuring root layout...");
11996
- const layoutPath = join18(projectRoot, "app/layout.tsx");
11997
- if (!existsSync25(layoutPath)) {
11790
+ const layoutPath = join17(projectRoot, "app/layout.tsx");
11791
+ if (!existsSync24(layoutPath)) {
11998
11792
  await mkdir7(dirname9(layoutPath), { recursive: true });
11999
11793
  await writeFile7(layoutPath, MINIMAL_ROOT_LAYOUT, "utf-8");
12000
11794
  stats.filesWritten.push("app/layout.tsx");
@@ -12084,8 +11878,8 @@ async function dsRegenerateCommand() {
12084
11878
  // src/commands/update.ts
12085
11879
  import chalk28 from "chalk";
12086
11880
  import ora8 from "ora";
12087
- import { readFileSync as readFileSync18, existsSync as existsSync26 } from "fs";
12088
- import { join as join19 } from "path";
11881
+ import { readFileSync as readFileSync17, existsSync as existsSync25 } from "fs";
11882
+ import { join as join18 } from "path";
12089
11883
  import { DesignSystemManager as DesignSystemManager15, CLI_VERSION as CLI_VERSION4 } from "@getcoherent/core";
12090
11884
 
12091
11885
  // src/utils/migrations.ts
@@ -12254,20 +12048,20 @@ var EXPECTED_CSS_VARS = [
12254
12048
  "--sidebar-ring"
12255
12049
  ];
12256
12050
  function checkMissingCssVars(projectRoot) {
12257
- const globalsPath = join19(projectRoot, "app", "globals.css");
12258
- if (!existsSync26(globalsPath)) return [];
12051
+ const globalsPath = join18(projectRoot, "app", "globals.css");
12052
+ if (!existsSync25(globalsPath)) return [];
12259
12053
  try {
12260
- const content = readFileSync18(globalsPath, "utf-8");
12054
+ const content = readFileSync17(globalsPath, "utf-8");
12261
12055
  return EXPECTED_CSS_VARS.filter((v) => !content.includes(v));
12262
12056
  } catch {
12263
12057
  return [];
12264
12058
  }
12265
12059
  }
12266
12060
  function patchGlobalsCss(projectRoot, missingVars) {
12267
- const globalsPath = join19(projectRoot, "app", "globals.css");
12268
- if (!existsSync26(globalsPath) || missingVars.length === 0) return;
12061
+ const globalsPath = join18(projectRoot, "app", "globals.css");
12062
+ if (!existsSync25(globalsPath) || missingVars.length === 0) return;
12269
12063
  const { writeFileSync: writeFileSync14 } = __require("fs");
12270
- let content = readFileSync18(globalsPath, "utf-8");
12064
+ let content = readFileSync17(globalsPath, "utf-8");
12271
12065
  const defaultValues = {
12272
12066
  "--chart-1": "220 70% 50%",
12273
12067
  "--chart-2": "160 60% 45%",
@@ -12345,26 +12139,26 @@ async function undoCommand(options) {
12345
12139
  // src/commands/sync.ts
12346
12140
  import chalk30 from "chalk";
12347
12141
  import ora9 from "ora";
12348
- import { existsSync as existsSync27, readFileSync as readFileSync19 } from "fs";
12349
- import { join as join20, relative as relative5, dirname as dirname10 } from "path";
12350
- import { readdir as readdir4, readFile as readFile7 } from "fs/promises";
12142
+ import { existsSync as existsSync26, readFileSync as readFileSync18 } from "fs";
12143
+ import { join as join19, relative as relative5, dirname as dirname10 } from "path";
12144
+ import { readdir as readdir3, readFile as readFile6 } from "fs/promises";
12351
12145
  import { DesignSystemManager as DesignSystemManager16 } from "@getcoherent/core";
12352
12146
  import { loadManifest as loadManifest13, saveManifest as saveManifest6, findSharedComponent } from "@getcoherent/core";
12353
12147
  function extractTokensFromProject(projectRoot) {
12354
12148
  const lightColors = {};
12355
12149
  const darkColors = {};
12356
- const globalsPath = join20(projectRoot, "app", "globals.css");
12357
- if (existsSync27(globalsPath)) {
12358
- const css = readFileSync19(globalsPath, "utf-8");
12150
+ const globalsPath = join19(projectRoot, "app", "globals.css");
12151
+ if (existsSync26(globalsPath)) {
12152
+ const css = readFileSync18(globalsPath, "utf-8");
12359
12153
  const rootMatch = css.match(/:root\s*\{([^}]+)\}/s);
12360
12154
  if (rootMatch) parseVarsInto(rootMatch[1], lightColors);
12361
12155
  const darkMatch = css.match(/\.dark\s*\{([^}]+)\}/s);
12362
12156
  if (darkMatch) parseVarsInto(darkMatch[1], darkColors);
12363
12157
  }
12364
- const layoutPath = join20(projectRoot, "app", "layout.tsx");
12158
+ const layoutPath = join19(projectRoot, "app", "layout.tsx");
12365
12159
  let layoutCode = "";
12366
- if (existsSync27(layoutPath)) {
12367
- layoutCode = readFileSync19(layoutPath, "utf-8");
12160
+ if (existsSync26(layoutPath)) {
12161
+ layoutCode = readFileSync18(layoutPath, "utf-8");
12368
12162
  const rootInline = layoutCode.match(/:root\s*\{([^}]+)\}/s);
12369
12163
  if (rootInline && Object.keys(lightColors).length === 0) {
12370
12164
  parseVarsInto(rootInline[1], lightColors);
@@ -12382,7 +12176,7 @@ function extractTokensFromProject(projectRoot) {
12382
12176
  defaultMode = "dark";
12383
12177
  }
12384
12178
  let radius;
12385
- const allCss = [existsSync27(globalsPath) ? readFileSync19(globalsPath, "utf-8") : "", layoutCode].join("\n");
12179
+ const allCss = [existsSync26(globalsPath) ? readFileSync18(globalsPath, "utf-8") : "", layoutCode].join("\n");
12386
12180
  const radiusMatch = allCss.match(/--radius:\s*([^;]+);/);
12387
12181
  if (radiusMatch) radius = radiusMatch[1].trim();
12388
12182
  return {
@@ -12405,13 +12199,13 @@ function parseVarsInto(block, target) {
12405
12199
  }
12406
12200
  async function detectCustomComponents(projectRoot, allPageCode) {
12407
12201
  const results = [];
12408
- const componentsDir = join20(projectRoot, "components");
12409
- if (!existsSync27(componentsDir)) return results;
12202
+ const componentsDir = join19(projectRoot, "components");
12203
+ if (!existsSync26(componentsDir)) return results;
12410
12204
  const files = [];
12411
12205
  await walkForTsx(componentsDir, files, ["ui"]);
12412
12206
  const fileResults = await Promise.all(
12413
12207
  files.map(async (filePath) => {
12414
- const code = await readFile7(filePath, "utf-8");
12208
+ const code = await readFile6(filePath, "utf-8");
12415
12209
  const relFile = relative5(projectRoot, filePath);
12416
12210
  const exportedNames = extractExportedComponentNames2(code);
12417
12211
  return exportedNames.map((name) => ({
@@ -12428,12 +12222,12 @@ async function detectCustomComponents(projectRoot, allPageCode) {
12428
12222
  async function walkForTsx(dir, files, skipDirs) {
12429
12223
  let entries;
12430
12224
  try {
12431
- entries = await readdir4(dir, { withFileTypes: true });
12225
+ entries = await readdir3(dir, { withFileTypes: true });
12432
12226
  } catch {
12433
12227
  return;
12434
12228
  }
12435
12229
  for (const e of entries) {
12436
- const full = join20(dir, e.name);
12230
+ const full = join19(dir, e.name);
12437
12231
  if (e.isDirectory()) {
12438
12232
  if (skipDirs.includes(e.name) || e.name.startsWith(".")) continue;
12439
12233
  await walkForTsx(full, files, skipDirs);
@@ -12502,18 +12296,18 @@ async function discoverPages(appDir) {
12502
12296
  async function walk(dir) {
12503
12297
  let entries;
12504
12298
  try {
12505
- entries = await readdir4(dir, { withFileTypes: true });
12299
+ entries = await readdir3(dir, { withFileTypes: true });
12506
12300
  } catch {
12507
12301
  return;
12508
12302
  }
12509
12303
  for (const entry of entries) {
12510
- const full = join20(dir, entry.name);
12304
+ const full = join19(dir, entry.name);
12511
12305
  if (entry.isDirectory()) {
12512
12306
  if (["design-system", "api", "_not-found"].includes(entry.name)) continue;
12513
12307
  if (entry.name.startsWith(".")) continue;
12514
12308
  await walk(full);
12515
12309
  } else if (entry.name === "page.tsx" || entry.name === "page.jsx") {
12516
- const code = await readFile7(full, "utf-8");
12310
+ const code = await readFile6(full, "utf-8");
12517
12311
  const routeDir = dirname10(relative5(appDir, full));
12518
12312
  let route = routeDir === "." ? "/" : "/" + routeDir;
12519
12313
  route = route.replace(/\/\([^)]+\)/g, "");
@@ -12596,8 +12390,8 @@ async function syncCommand(options = {}) {
12596
12390
  if (dryRun) console.log(chalk30.yellow(" [dry-run] No files will be written\n"));
12597
12391
  const spinner = ora9("Scanning project files...").start();
12598
12392
  try {
12599
- const appDir = join20(project.root, "app");
12600
- if (!existsSync27(appDir)) {
12393
+ const appDir = join19(project.root, "app");
12394
+ if (!existsSync26(appDir)) {
12601
12395
  spinner.fail("No app/ directory found");
12602
12396
  process.exit(1);
12603
12397
  }
@@ -12827,53 +12621,53 @@ async function syncCommand(options = {}) {
12827
12621
  // src/commands/migrate.ts
12828
12622
  import chalk31 from "chalk";
12829
12623
  import ora10 from "ora";
12830
- import { existsSync as existsSync28, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync12, readFileSync as readFileSync20, readdirSync as readdirSync10 } from "fs";
12831
- import { join as join21 } from "path";
12624
+ import { existsSync as existsSync27, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync12, readFileSync as readFileSync19, readdirSync as readdirSync10 } from "fs";
12625
+ import { join as join20 } from "path";
12832
12626
  function backupDir(projectRoot) {
12833
12627
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
12834
- return join21(projectRoot, ".coherent", "backups", `pre-migrate-${ts}`);
12628
+ return join20(projectRoot, ".coherent", "backups", `pre-migrate-${ts}`);
12835
12629
  }
12836
12630
  function guardPath(projectRoot) {
12837
- return join21(projectRoot, ".coherent", "migration-in-progress");
12631
+ return join20(projectRoot, ".coherent", "migration-in-progress");
12838
12632
  }
12839
12633
  function createBackup2(projectRoot) {
12840
- const uiDir = join21(projectRoot, "components", "ui");
12634
+ const uiDir = join20(projectRoot, "components", "ui");
12841
12635
  const dest = backupDir(projectRoot);
12842
12636
  mkdirSync8(dest, { recursive: true });
12843
- if (existsSync28(uiDir)) {
12844
- cpSync(uiDir, join21(dest, "components-ui"), { recursive: true });
12637
+ if (existsSync27(uiDir)) {
12638
+ cpSync(uiDir, join20(dest, "components-ui"), { recursive: true });
12845
12639
  }
12846
- const configPath = join21(projectRoot, "design-system.config.ts");
12847
- if (existsSync28(configPath)) {
12848
- cpSync(configPath, join21(dest, "design-system.config.ts"));
12640
+ const configPath = join20(projectRoot, "design-system.config.ts");
12641
+ if (existsSync27(configPath)) {
12642
+ cpSync(configPath, join20(dest, "design-system.config.ts"));
12849
12643
  }
12850
12644
  return dest;
12851
12645
  }
12852
12646
  function setGuard(projectRoot, backupPath) {
12853
12647
  const guard = guardPath(projectRoot);
12854
- mkdirSync8(join21(projectRoot, ".coherent"), { recursive: true });
12648
+ mkdirSync8(join20(projectRoot, ".coherent"), { recursive: true });
12855
12649
  writeFileSync12(guard, JSON.stringify({ backup: backupPath, startedAt: (/* @__PURE__ */ new Date()).toISOString() }));
12856
12650
  }
12857
12651
  function clearGuard(projectRoot) {
12858
12652
  const guard = guardPath(projectRoot);
12859
- if (existsSync28(guard)) rmSync6(guard);
12653
+ if (existsSync27(guard)) rmSync6(guard);
12860
12654
  }
12861
12655
  function rollback(projectRoot) {
12862
12656
  const guard = guardPath(projectRoot);
12863
- if (!existsSync28(guard)) return false;
12657
+ if (!existsSync27(guard)) return false;
12864
12658
  try {
12865
- const data = JSON.parse(readFileSync20(guard, "utf-8"));
12659
+ const data = JSON.parse(readFileSync19(guard, "utf-8"));
12866
12660
  const backup = data.backup;
12867
- if (!existsSync28(backup)) return false;
12868
- const uiBackup = join21(backup, "components-ui");
12869
- const uiDir = join21(projectRoot, "components", "ui");
12870
- if (existsSync28(uiBackup)) {
12871
- if (existsSync28(uiDir)) rmSync6(uiDir, { recursive: true });
12661
+ if (!existsSync27(backup)) return false;
12662
+ const uiBackup = join20(backup, "components-ui");
12663
+ const uiDir = join20(projectRoot, "components", "ui");
12664
+ if (existsSync27(uiBackup)) {
12665
+ if (existsSync27(uiDir)) rmSync6(uiDir, { recursive: true });
12872
12666
  cpSync(uiBackup, uiDir, { recursive: true });
12873
12667
  }
12874
- const configBackup = join21(backup, "design-system.config.ts");
12875
- const configDest = join21(projectRoot, "design-system.config.ts");
12876
- if (existsSync28(configBackup)) {
12668
+ const configBackup = join20(backup, "design-system.config.ts");
12669
+ const configDest = join20(projectRoot, "design-system.config.ts");
12670
+ if (existsSync27(configBackup)) {
12877
12671
  cpSync(configBackup, configDest);
12878
12672
  }
12879
12673
  clearGuard(projectRoot);
@@ -12901,13 +12695,13 @@ async function migrateAction(options) {
12901
12695
  return;
12902
12696
  }
12903
12697
  const guard = guardPath(projectRoot);
12904
- if (existsSync28(guard)) {
12698
+ if (existsSync27(guard)) {
12905
12699
  console.log(chalk31.yellow("A migration is already in progress."));
12906
12700
  console.log(chalk31.dim("Run `coherent migrate --rollback` to undo, or delete .coherent/migration-in-progress"));
12907
12701
  return;
12908
12702
  }
12909
- const uiDir = join21(projectRoot, "components", "ui");
12910
- if (!existsSync28(uiDir)) {
12703
+ const uiDir = join20(projectRoot, "components", "ui");
12704
+ if (!existsSync27(uiDir)) {
12911
12705
  console.log(chalk31.yellow("No components/ui directory found. Nothing to migrate."));
12912
12706
  return;
12913
12707
  }
@@ -12933,8 +12727,8 @@ Found ${migratable.length} component(s) to migrate:`));
12933
12727
  setGuard(projectRoot, backup);
12934
12728
  try {
12935
12729
  for (const id of migratable) {
12936
- const filePath = join21(uiDir, `${id}.tsx`);
12937
- if (existsSync28(filePath)) rmSync6(filePath);
12730
+ const filePath = join20(uiDir, `${id}.tsx`);
12731
+ if (existsSync27(filePath)) rmSync6(filePath);
12938
12732
  }
12939
12733
  const results = await provider.installBatch(migratable, projectRoot, { force: true });
12940
12734
  let migrated = 0;
@@ -12956,20 +12750,20 @@ Found ${migratable.length} component(s) to migrate:`));
12956
12750
  }
12957
12751
 
12958
12752
  // src/utils/update-notifier.ts
12959
- import { existsSync as existsSync29, mkdirSync as mkdirSync9, readFileSync as readFileSync21, writeFileSync as writeFileSync13 } from "fs";
12960
- import { join as join22 } from "path";
12753
+ import { existsSync as existsSync28, mkdirSync as mkdirSync9, readFileSync as readFileSync20, writeFileSync as writeFileSync13 } from "fs";
12754
+ import { join as join21 } from "path";
12961
12755
  import { homedir } from "os";
12962
12756
  import chalk32 from "chalk";
12963
12757
  import { CLI_VERSION as CLI_VERSION5 } from "@getcoherent/core";
12964
12758
  var DEBUG5 = process.env.COHERENT_DEBUG === "1";
12965
12759
  var PACKAGE_NAME = "@getcoherent/cli";
12966
- var CACHE_DIR = join22(homedir(), ".coherent");
12967
- var CACHE_FILE = join22(CACHE_DIR, "update-check.json");
12760
+ var CACHE_DIR = join21(homedir(), ".coherent");
12761
+ var CACHE_FILE = join21(CACHE_DIR, "update-check.json");
12968
12762
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
12969
12763
  function readCache() {
12970
12764
  try {
12971
- if (!existsSync29(CACHE_FILE)) return null;
12972
- const raw = readFileSync21(CACHE_FILE, "utf-8");
12765
+ if (!existsSync28(CACHE_FILE)) return null;
12766
+ const raw = readFileSync20(CACHE_FILE, "utf-8");
12973
12767
  return JSON.parse(raw);
12974
12768
  } catch (e) {
12975
12769
  if (DEBUG5) console.error("Failed to read update cache:", e);
@@ -12978,7 +12772,7 @@ function readCache() {
12978
12772
  }
12979
12773
  function writeCache(data) {
12980
12774
  try {
12981
- if (!existsSync29(CACHE_DIR)) mkdirSync9(CACHE_DIR, { recursive: true });
12775
+ if (!existsSync28(CACHE_DIR)) mkdirSync9(CACHE_DIR, { recursive: true });
12982
12776
  writeFileSync13(CACHE_FILE, JSON.stringify(data), "utf-8");
12983
12777
  } catch (e) {
12984
12778
  if (DEBUG5) console.error("Failed to write update cache:", e);