@getcoherent/cli 0.5.15 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,3 +1,10 @@
1
+ import {
2
+ generateArchitecturePlan,
3
+ getPageGroup,
4
+ getPageType,
5
+ loadPlan,
6
+ savePlan
7
+ } from "./chunk-4M2RBSYF.js";
1
8
  import {
2
9
  __require
3
10
  } from "./chunk-3RG5ZIWI.js";
@@ -1984,8 +1991,8 @@ function fixEscapedClosingQuotes(code) {
1984
1991
  }
1985
1992
  function fixUnescapedLtInJsx(code) {
1986
1993
  let out = code;
1987
- out = out.replace(/>([^<]*)<(\d)/g, ">$1&lt;$2");
1988
- out = out.replace(/>([^<]*)<([^/a-zA-Z!{>])/g, ">$1&lt;$2");
1994
+ out = out.replace(/>([^<\n]*)<(\d)/g, ">$1&lt;$2");
1995
+ out = out.replace(/>([^<\n]*)<([^/a-zA-Z!{>\n])/g, ">$1&lt;$2");
1989
1996
  return out;
1990
1997
  }
1991
1998
 
@@ -3745,7 +3752,7 @@ async function createAppRouteGroupLayout(projectPath) {
3745
3752
  }
3746
3753
 
3747
3754
  // src/commands/chat.ts
3748
- import chalk13 from "chalk";
3755
+ import chalk14 from "chalk";
3749
3756
  import ora2 from "ora";
3750
3757
  import { resolve as resolve9, relative as relative2, join as join11 } from "path";
3751
3758
  import { existsSync as existsSync16, readFileSync as readFileSync11, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
@@ -4101,6 +4108,7 @@ var PAGE_TEMPLATES = {
4101
4108
  var AUTH_ROUTE_SEGMENTS = /* @__PURE__ */ new Set([
4102
4109
  "login",
4103
4110
  "signin",
4111
+ "sign-in",
4104
4112
  "sign-up",
4105
4113
  "signup",
4106
4114
  "register",
@@ -4249,12 +4257,11 @@ CONTENT (zero placeholders):
4249
4257
  - NEVER: "Lorem ipsum", "Card content", "Description here"
4250
4258
  - ALWAYS: Real, contextual content. Realistic metric names, values, dates.
4251
4259
  `;
4252
- var DESIGN_QUALITY = `
4253
- ## DESIGN QUALITY (apply to EVERY page)
4260
+ var DESIGN_QUALITY_COMMON = `
4261
+ ## DESIGN QUALITY \u2014 COMMON
4254
4262
 
4255
4263
  ### Typography Hierarchy
4256
4264
  - Page headline (h1): text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight leading-[1.1]
4257
- - Landing/marketing hero headline: text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight leading-[1.05]
4258
4265
  - Section titles (h2): text-2xl md:text-3xl font-bold
4259
4266
  - Card titles (h3): text-sm font-semibold (never text-base or text-lg)
4260
4267
  - Body text: text-sm text-muted-foreground leading-relaxed
@@ -4267,6 +4274,29 @@ var DESIGN_QUALITY = `
4267
4274
  - Sections alternate between bg-background and bg-muted/5 for rhythm
4268
4275
  - Section dividers: border-t border-border/10 (subtle, not heavy)
4269
4276
 
4277
+ ### Buttons with Icons
4278
+ - Buttons containing text + icon: ALWAYS use inline-flex items-center gap-2 whitespace-nowrap
4279
+ - Icon inside button: h-4 w-4 (never larger), placed AFTER text for arrows, BEFORE text for action icons
4280
+ - NEVER let button content wrap to multiple lines \u2014 use whitespace-nowrap on the Button component
4281
+ - CTA buttons: use the Button component, NEVER raw <button> or <a> styled as button
4282
+
4283
+ ### Accent Color Discipline
4284
+ - ONE accent color per page (primary or emerald-400)
4285
+ - Use for: CTAs, terminal text, check icons, feature icon backgrounds, active states
4286
+ - NEVER mix blue + purple + emerald on same page
4287
+ - Badge: outline style (border-border/30 bg-transparent) not filled color
4288
+ - Status icons: text-emerald-400 for positive, text-red-400 for negative
4289
+
4290
+ ### Dark Theme Implementation
4291
+ - html element: className="dark"
4292
+ - Background: use CSS variables from globals.css dark section
4293
+ - Text: text-foreground for primary, text-muted-foreground for secondary
4294
+ - NEVER hardcode dark colors (bg-gray-900) \u2014 always use semantic tokens
4295
+ - Cards and elevated elements: slightly lighter than background (bg-card or bg-zinc-900/50)
4296
+ `;
4297
+ var DESIGN_QUALITY_MARKETING = `
4298
+ ## DESIGN QUALITY \u2014 MARKETING PAGES
4299
+
4270
4300
  ### Spacing Rhythm (3 distinct levels)
4271
4301
  - Between sections: py-20 md:py-28 (generous)
4272
4302
  - Within sections (title to content): mb-12 md:mb-16
@@ -4274,11 +4304,8 @@ var DESIGN_QUALITY = `
4274
4304
  - Between cards in grid: gap-5 (tight)
4275
4305
  - NEVER uniform spacing everywhere \u2014 contrast creates rhythm
4276
4306
 
4277
- ### Buttons with Icons
4278
- - Buttons containing text + icon: ALWAYS use inline-flex items-center gap-2 whitespace-nowrap
4279
- - Icon inside button: h-4 w-4 (never larger), placed AFTER text for arrows, BEFORE text for action icons
4280
- - NEVER let button content wrap to multiple lines \u2014 use whitespace-nowrap on the Button component
4281
- - CTA buttons: use the Button component, NEVER raw <button> or <a> styled as button
4307
+ ### Hero headline
4308
+ - Landing/marketing hero headline: text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight leading-[1.05]
4282
4309
 
4283
4310
  ### Icons in Feature Cards
4284
4311
  - Wrap in colored container: bg-primary/10 rounded-lg p-2.5
@@ -4294,14 +4321,7 @@ var DESIGN_QUALITY = `
4294
4321
  - Title bar (optional): flex with 3 dots (bg-zinc-700 rounded-full w-2.5 h-2.5) + title text-zinc-500 text-[11px]
4295
4322
  - Copy button: text-zinc-500 hover:text-zinc-300
4296
4323
 
4297
- ### Accent Color Discipline
4298
- - ONE accent color per page (primary or emerald-400)
4299
- - Use for: CTAs, terminal text, check icons, feature icon backgrounds, active states
4300
- - NEVER mix blue + purple + emerald on same page
4301
- - Badge: outline style (border-border/30 bg-transparent) not filled color
4302
- - Status icons: text-emerald-400 for positive, text-red-400 for negative
4303
-
4304
- ### Hero Section (landing/marketing pages)
4324
+ ### Hero Section
4305
4325
  - Minimum height: min-h-[80vh] flex items-center justify-center
4306
4326
  - Content: centered, max-w-3xl, flex flex-col items-center text-center gap-8
4307
4327
  - Badge above headline: small, outline, text-xs tracking-wide
@@ -4318,8 +4338,6 @@ var DESIGN_QUALITY = `
4318
4338
  ### Step/Process Sections
4319
4339
  - Numbered steps: circle with border, number inside (w-10 h-10 rounded-full border border-border/30 text-sm)
4320
4340
  - Label above: text-xs font-semibold tracking-widest uppercase text-muted-foreground
4321
- - Each step has a code block showing the command
4322
- - Description below: text-sm text-muted-foreground
4323
4341
 
4324
4342
  ### Footer
4325
4343
  - Minimal: border-t border-border/10, py-10
@@ -4327,13 +4345,66 @@ var DESIGN_QUALITY = `
4327
4345
  - Links: hover:text-foreground transition-colors
4328
4346
  - Layout: flex justify-between on desktop, stack on mobile
4329
4347
 
4330
- ### Dark Theme Implementation
4331
- - html element: className="dark"
4332
- - Background: use CSS variables from globals.css dark section
4333
- - Text: text-foreground for primary, text-muted-foreground for secondary
4334
- - NEVER hardcode dark colors (bg-gray-900) \u2014 always use semantic tokens
4335
- - Cards and elevated elements: slightly lighter than background (bg-card or bg-zinc-900/50)
4348
+ NEVER include app-style elements (sidebar widgets, data tables, filters) on marketing pages.
4349
+ `;
4350
+ var DESIGN_QUALITY_APP = `
4351
+ ## DESIGN QUALITY \u2014 APP PAGES
4352
+
4353
+ ### Spacing
4354
+ - gap-4 md:gap-6 between sections
4355
+ - p-4 lg:p-6 content padding
4356
+ - Within cards: p-4 to p-6 (compact)
4357
+ - Between cards in grid: gap-4 (tight)
4358
+
4359
+ ### Layout
4360
+ - Data tables, card grids, filters, stat rows
4361
+ - Page wrapper: flex flex-1 flex-col gap-4 p-4 lg:p-6
4362
+ - Stats grid: grid gap-4 md:grid-cols-2 lg:grid-cols-4
4363
+ - Content: functional, scannable, data-dense
4364
+
4365
+ NEVER include marketing sections (hero, pricing, testimonials) on app pages.
4336
4366
  `;
4367
+ var DESIGN_QUALITY_AUTH = `
4368
+ ## DESIGN QUALITY \u2014 AUTH PAGES
4369
+
4370
+ ### Layout
4371
+ - Centered card: flex min-h-svh items-center justify-center p-6 md:p-10
4372
+ - Card width: w-full max-w-sm
4373
+ - No navigation, no section containers, no sidebar
4374
+ - Single focused form with clear CTA
4375
+ - Card \u2192 CardHeader (title + description) \u2192 CardContent (form) \u2192 CardFooter (link to other auth page)
4376
+
4377
+ NEVER include navigation bars, sidebars, or multi-section layouts on auth pages.
4378
+ `;
4379
+ function getDesignQualityForType(type) {
4380
+ switch (type) {
4381
+ case "marketing":
4382
+ return DESIGN_QUALITY_MARKETING;
4383
+ case "app":
4384
+ return DESIGN_QUALITY_APP;
4385
+ case "auth":
4386
+ return DESIGN_QUALITY_AUTH;
4387
+ }
4388
+ }
4389
+ function inferPageTypeFromRoute(route) {
4390
+ const slug = route.replace(/^\//, "").split("/")[0] || "";
4391
+ const authSlugs = /* @__PURE__ */ new Set([
4392
+ "login",
4393
+ "register",
4394
+ "sign-up",
4395
+ "signup",
4396
+ "sign-in",
4397
+ "signin",
4398
+ "forgot-password",
4399
+ "reset-password"
4400
+ ]);
4401
+ const marketingSlugs = /* @__PURE__ */ new Set(["pricing", "features", "about", "blog", "contact", "terms", "privacy"]);
4402
+ if (authSlugs.has(slug)) return "auth";
4403
+ if (marketingSlugs.has(slug) || slug === "") return "marketing";
4404
+ return "app";
4405
+ }
4406
+ var DESIGN_QUALITY = `${DESIGN_QUALITY_COMMON}
4407
+ ${DESIGN_QUALITY_MARKETING}`;
4337
4408
  var VISUAL_DEPTH = `
4338
4409
  ## VISUAL DEPTH TECHNIQUES (pick 1-3 per page based on context)
4339
4410
 
@@ -5335,11 +5406,14 @@ Return valid JSON only, no markdown code fence. Use this shape:
5335
5406
  { "requests": [ ... array of ModificationRequest ... ], "uxRecommendations": "optional markdown or omit key" }
5336
5407
  Legacy: returning only a JSON array of requests is still accepted.`;
5337
5408
  }
5338
- function buildLightweightPagePrompt(pageName, route, styleContext, sharedComponentsSummary) {
5409
+ function buildLightweightPagePrompt(pageName, route, styleContext, sharedComponentsSummary, pageType) {
5410
+ const designConstraints = pageType ? getDesignQualityForType(pageType) : "";
5339
5411
  return [
5340
5412
  `Generate complete pageCode for a page called "${pageName}" at route "${route}".`,
5341
5413
  `Output valid TSX with a default export React component.`,
5342
5414
  `Use shadcn/ui components (import from @/components/ui/*). Use Tailwind CSS semantic tokens only.`,
5415
+ pageType ? `PAGE TYPE: ${pageType}` : "",
5416
+ designConstraints,
5343
5417
  styleContext ? `Follow this style context:
5344
5418
  ${styleContext}` : "",
5345
5419
  sharedComponentsSummary ? `Available shared components:
@@ -6449,11 +6523,36 @@ async function autoFixCode(code) {
6449
6523
  fixes.push("fixed escaped closing quotes in strings");
6450
6524
  }
6451
6525
  const beforeEntityFix = fixed;
6452
- fixed = fixed.replace(/&lt;=/g, "<=");
6453
- fixed = fixed.replace(/&gt;=/g, ">=");
6454
- fixed = fixed.replace(/&amp;&amp;/g, "&&");
6455
- fixed = fixed.replace(/([\w)\]])\s*&lt;\s*([\w(])/g, "$1 < $2");
6456
- fixed = fixed.replace(/([\w)\]])\s*&gt;\s*([\w(])/g, "$1 > $2");
6526
+ const isInsideAttrValue = (line, idx) => {
6527
+ let inQuote = false;
6528
+ let inAttr = false;
6529
+ for (let i = 0; i < idx; i++) {
6530
+ if (line[i] === "=" && line[i + 1] === '"') {
6531
+ inAttr = true;
6532
+ inQuote = true;
6533
+ i++;
6534
+ } else if (inAttr && line[i] === '"') {
6535
+ inAttr = false;
6536
+ inQuote = false;
6537
+ }
6538
+ }
6539
+ return inQuote;
6540
+ };
6541
+ fixed = fixed.split("\n").map((line) => {
6542
+ let l = line;
6543
+ l = l.replace(/&lt;=/g, (m, offset) => isInsideAttrValue(line, offset) ? m : "<=");
6544
+ l = l.replace(/&gt;=/g, (m, offset) => isInsideAttrValue(line, offset) ? m : ">=");
6545
+ l = l.replace(/&amp;&amp;/g, (m, offset) => isInsideAttrValue(line, offset) ? m : "&&");
6546
+ l = l.replace(
6547
+ /([\w)\]])\s*&lt;\s*([\w(])/g,
6548
+ (m, p1, p2, offset) => isInsideAttrValue(line, offset) ? m : `${p1} < ${p2}`
6549
+ );
6550
+ l = l.replace(
6551
+ /([\w)\]])\s*&gt;\s*([\w(])/g,
6552
+ (m, p1, p2, offset) => isInsideAttrValue(line, offset) ? m : `${p1} > ${p2}`
6553
+ );
6554
+ return l;
6555
+ }).join("\n");
6457
6556
  if (fixed !== beforeEntityFix) {
6458
6557
  fixes.push("Fixed syntax issues");
6459
6558
  }
@@ -6928,7 +7027,16 @@ import { DesignSystemManager as DesignSystemManager3, loadManifest as loadManife
6928
7027
  import chalk8 from "chalk";
6929
7028
  var MARKETING_ROUTES = /* @__PURE__ */ new Set(["", "landing", "pricing", "about", "contact", "blog", "features"]);
6930
7029
  var MIN_ANCHOR_PAGE_CODE_CHARS = 120;
6931
- var AUTH_ROUTE_SLUGS = /* @__PURE__ */ new Set(["login", "register", "forgot-password", "reset-password", "sign-up"]);
7030
+ var AUTH_ROUTE_SLUGS = /* @__PURE__ */ new Set([
7031
+ "login",
7032
+ "signin",
7033
+ "sign-in",
7034
+ "register",
7035
+ "sign-up",
7036
+ "signup",
7037
+ "forgot-password",
7038
+ "reset-password"
7039
+ ]);
6932
7040
  function inferRouteUsesAuthSegment(route) {
6933
7041
  const slug = route.replace(/^\//, "").split("/")[0] || "";
6934
7042
  return AUTH_ROUTE_SLUGS.has(slug);
@@ -6950,30 +7058,30 @@ function isMarketingRoute(route) {
6950
7058
  const slug = route.replace(/^\//, "").split("/")[0] || "";
6951
7059
  return MARKETING_ROUTES.has(slug);
6952
7060
  }
6953
- function routeToFsPath(projectRoot, route, isAuth) {
7061
+ function routeToFsPath(projectRoot, route, isAuthOrPlan) {
7062
+ const plan = typeof isAuthOrPlan === "object" ? isAuthOrPlan : void 0;
7063
+ const isAuth = typeof isAuthOrPlan === "boolean" ? isAuthOrPlan : false;
6954
7064
  const slug = route.replace(/^\//, "");
6955
- if (isAuth) {
6956
- return resolve5(projectRoot, "app", "(auth)", slug || "login", "page.tsx");
6957
- }
6958
- if (!slug) {
6959
- return resolve5(projectRoot, "app", "page.tsx");
6960
- }
6961
- if (isMarketingRoute(route)) {
6962
- return resolve5(projectRoot, "app", slug, "page.tsx");
7065
+ if (!slug) return resolve5(projectRoot, "app", "page.tsx");
7066
+ if (plan) {
7067
+ const group = getPageGroup(route, plan);
7068
+ if (group) return resolve5(projectRoot, "app", `(${group.id})`, slug, "page.tsx");
6963
7069
  }
7070
+ if (isAuth) return resolve5(projectRoot, "app", "(auth)", slug || "login", "page.tsx");
7071
+ if (isMarketingRoute(route)) return resolve5(projectRoot, "app", slug, "page.tsx");
6964
7072
  return resolve5(projectRoot, "app", "(app)", slug, "page.tsx");
6965
7073
  }
6966
- function routeToRelPath(route, isAuth) {
7074
+ function routeToRelPath(route, isAuthOrPlan) {
7075
+ const plan = typeof isAuthOrPlan === "object" ? isAuthOrPlan : void 0;
7076
+ const isAuth = typeof isAuthOrPlan === "boolean" ? isAuthOrPlan : false;
6967
7077
  const slug = route.replace(/^\//, "");
6968
- if (isAuth) {
6969
- return `app/(auth)/${slug || "login"}/page.tsx`;
6970
- }
6971
- if (!slug) {
6972
- return "app/page.tsx";
6973
- }
6974
- if (isMarketingRoute(route)) {
6975
- return `app/${slug}/page.tsx`;
7078
+ if (!slug) return "app/page.tsx";
7079
+ if (plan) {
7080
+ const group = getPageGroup(route, plan);
7081
+ if (group) return `app/(${group.id})/${slug}/page.tsx`;
6976
7082
  }
7083
+ if (isAuth) return `app/(auth)/${slug || "login"}/page.tsx`;
7084
+ if (isMarketingRoute(route)) return `app/${slug}/page.tsx`;
6977
7085
  return `app/(app)/${slug}/page.tsx`;
6978
7086
  }
6979
7087
  function deduplicatePages(pages) {
@@ -6998,13 +7106,24 @@ function extractComponentIdsFromCode(code) {
6998
7106
  }
6999
7107
  return ids;
7000
7108
  }
7001
- async function warnInlineDuplicates(projectRoot, pageName, pageCode, manifest) {
7109
+ async function warnInlineDuplicates(projectRoot, pageName, route, pageCode, manifest, plan) {
7002
7110
  const sectionOrWidget = manifest.shared.filter((e) => e.type === "section" || e.type === "widget");
7003
7111
  if (sectionOrWidget.length === 0) return;
7112
+ const plannedForPage = plan ? new Set(plan.sharedComponents.filter((c) => c.usedBy.includes(route)).map((c) => c.name)) : null;
7004
7113
  for (const e of sectionOrWidget) {
7114
+ if (plannedForPage && !plannedForPage.has(e.name)) continue;
7005
7115
  const kebab = e.file.replace(/^components\/shared\//, "").replace(/\.tsx$/, "");
7006
7116
  const hasImport = pageCode.includes(`@/components/shared/${kebab}`);
7007
7117
  if (hasImport) continue;
7118
+ if (plannedForPage) {
7119
+ console.log(
7120
+ chalk8.yellow(
7121
+ `
7122
+ \u26A0 Page "${pageName}" should use shared component ${e.name} (per architecture plan) but it's not imported. Import from @/components/shared/${kebab}`
7123
+ )
7124
+ );
7125
+ continue;
7126
+ }
7008
7127
  const sameNameAsTag = new RegExp(`<\\/?${e.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[\\s>]`).test(pageCode);
7009
7128
  if (sameNameAsTag) {
7010
7129
  console.log(
@@ -7616,6 +7735,7 @@ async function pMap(items, fn, concurrency = 3) {
7616
7735
  }
7617
7736
 
7618
7737
  // src/commands/chat/split-generator.ts
7738
+ import chalk9 from "chalk";
7619
7739
  function buildExistingPagesContext(config2) {
7620
7740
  const pages = config2.pages || [];
7621
7741
  const analyzed = pages.filter((p) => p.pageAnalysis);
@@ -7712,6 +7832,21 @@ Before implementing any section, check this list. Import and use matching compon
7712
7832
 
7713
7833
  ${sharedComponentsSummary}`;
7714
7834
  }
7835
+ function formatPlanSummary(plan) {
7836
+ if (plan.groups.length === 0) return "";
7837
+ const groupLines = plan.groups.map((g) => ` Group "${g.id}" (layout: ${g.layout}): ${g.pages.join(", ")}`);
7838
+ const compLines = plan.sharedComponents.map(
7839
+ (c) => ` ${c.name} (${c.type}) \u2014 ${c.description}; usedBy: ${c.usedBy.join(", ")}`
7840
+ );
7841
+ const parts = [`ARCHITECTURE PLAN:
7842
+ Groups:
7843
+ ${groupLines.join("\n")}`];
7844
+ if (compLines.length > 0) {
7845
+ parts.push(`Shared Components:
7846
+ ${compLines.join("\n")}`);
7847
+ }
7848
+ return parts.join("\n");
7849
+ }
7715
7850
  async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts) {
7716
7851
  let pageNames = [];
7717
7852
  spinner.start("Phase 1/5 \u2014 Planning pages...");
@@ -7745,7 +7880,7 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7745
7880
  }
7746
7881
  if (pageNames.length === 0) {
7747
7882
  spinner.fail("Could not determine pages to create");
7748
- return [];
7883
+ return { requests: [], plan: null };
7749
7884
  }
7750
7885
  pageNames = deduplicatePages(pageNames);
7751
7886
  const hasHomePage = pageNames.some((p) => p.route === "/");
@@ -7767,7 +7902,41 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7767
7902
  const allRoutes = pageNames.map((p) => p.route).join(", ");
7768
7903
  const allPagesList = pageNames.map((p) => `${p.name} (${p.route})`).join(", ");
7769
7904
  const inferredNote = inferred.length > 0 ? ` (${inferred.length} auto-inferred)` : "";
7770
- spinner.succeed(`Phase 1/5 \u2014 Found ${pageNames.length} pages${inferredNote}: ${allPagesList}`);
7905
+ spinner.succeed(`Phase 1/6 \u2014 Found ${pageNames.length} pages${inferredNote}: ${allPagesList}`);
7906
+ let plan = null;
7907
+ if (parseOpts.projectRoot) {
7908
+ spinner.start("Phase 2/6 \u2014 Generating architecture plan...");
7909
+ try {
7910
+ const ai = await createAIProvider(provider ?? "auto");
7911
+ const layoutHint = modCtx.config.navigation?.type || null;
7912
+ plan = await generateArchitecturePlan(pageNames, message, ai, layoutHint);
7913
+ if (plan) {
7914
+ const groupsSummary = plan.groups.map((g) => `${g.id} (${g.layout}, ${g.pages.length} pages)`).join(", ");
7915
+ const sharedSummary = plan.sharedComponents.length > 0 ? plan.sharedComponents.map((c) => `${c.name} \u2192 ${c.usedBy.join(", ")}`).join(" | ") : "";
7916
+ const totalPages = plan.groups.reduce((sum, g) => sum + g.pages.length, 0);
7917
+ spinner.succeed(`Phase 2/6 \u2014 Architecture plan created`);
7918
+ console.log(chalk9.dim(` Groups: ${groupsSummary}`));
7919
+ if (sharedSummary) console.log(chalk9.dim(` Shared: ${sharedSummary}`));
7920
+ console.log(chalk9.dim(` Total: ${totalPages} pages, ${plan.sharedComponents.length} shared components`));
7921
+ if (plan.sharedComponents.length > 0 && parseOpts.projectRoot) {
7922
+ const allDeps = new Set(plan.sharedComponents.flatMap((c) => c.shadcnDeps));
7923
+ if (allDeps.size > 0) {
7924
+ const componentProvider = getComponentProvider();
7925
+ for (const dep of allDeps) {
7926
+ try {
7927
+ await componentProvider.installComponent(dep, parseOpts.projectRoot);
7928
+ } catch {
7929
+ }
7930
+ }
7931
+ }
7932
+ }
7933
+ } else {
7934
+ spinner.warn("Phase 2/6 \u2014 Plan generation failed (continuing without plan)");
7935
+ }
7936
+ } catch {
7937
+ spinner.warn("Phase 2/6 \u2014 Plan generation failed (continuing without plan)");
7938
+ }
7939
+ }
7771
7940
  const homeIdx = pageNames.findIndex((p) => p.route === "/");
7772
7941
  const homePage = homeIdx !== -1 ? pageNames[homeIdx] : pageNames[0];
7773
7942
  const remainingPages = pageNames.filter((_, i) => i !== (homeIdx !== -1 ? homeIdx : 0));
@@ -7781,12 +7950,12 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7781
7950
  if (existingCode) {
7782
7951
  reusedExistingAnchor = true;
7783
7952
  homePageCode = existingCode;
7784
- spinner.start(`Phase 2/5 \u2014 Loading ${homePage.name} from disk (style anchor)...`);
7785
- spinner.succeed(`Phase 2/5 \u2014 Reused existing ${homePage.name} page (skipped AI regeneration)`);
7953
+ spinner.start(`Phase 3/6 \u2014 Loading ${homePage.name} from disk (style anchor)...`);
7954
+ spinner.succeed(`Phase 3/6 \u2014 Reused existing ${homePage.name} page (skipped AI regeneration)`);
7786
7955
  }
7787
7956
  }
7788
7957
  if (!reusedExistingAnchor) {
7789
- spinner.start(`Phase 2/5 \u2014 Generating ${homePage.name} page (sets design direction)...`);
7958
+ spinner.start(`Phase 3/6 \u2014 Generating ${homePage.name} page (sets design direction)...`);
7790
7959
  try {
7791
7960
  const homeResult = await parseModification(
7792
7961
  `Create ONE page called "${homePage.name}" at route "${homePage.route}". Context: ${message}. This REPLACES the default placeholder page \u2014 generate a complete, content-rich landing page for the project described above. Generate complete pageCode. Include a branded site-wide <header> with navigation links to ALL these pages: ${allPagesList}. Use these EXACT routes in navigation: ${allRoutes}. Include a <footer> at the bottom. Make it visually polished \u2014 this page sets the design direction for the entire site. Do not generate other pages.`,
@@ -7808,73 +7977,102 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7808
7977
  changes: { id: homePage.id, name: homePage.name, route: homePage.route }
7809
7978
  };
7810
7979
  }
7811
- spinner.succeed(`Phase 2/5 \u2014 ${homePage.name} page generated`);
7980
+ spinner.succeed(`Phase 3/6 \u2014 ${homePage.name} page generated`);
7812
7981
  }
7813
- spinner.start("Phase 3/5 \u2014 Extracting design patterns...");
7982
+ spinner.start("Phase 4/6 \u2014 Extracting design patterns...");
7814
7983
  const styleContext = homePageCode ? extractStyleContext(homePageCode) : "";
7815
7984
  if (styleContext) {
7816
7985
  const lineCount = styleContext.split("\n").length - 1;
7817
7986
  const source = reusedExistingAnchor ? `${homePage.name} (existing file)` : homePage.name;
7818
- spinner.succeed(`Phase 3/5 \u2014 Extracted ${lineCount} style patterns from ${source}`);
7987
+ spinner.succeed(`Phase 4/6 \u2014 Extracted ${lineCount} style patterns from ${source}`);
7819
7988
  } else {
7820
- spinner.succeed("Phase 3/5 \u2014 No style patterns extracted (anchor page had no code)");
7989
+ spinner.succeed("Phase 4/6 \u2014 No style patterns extracted (anchor page had no code)");
7821
7990
  }
7822
- if (remainingPages.length >= 2 && homePageCode && projectRoot) {
7823
- const manifest = await loadManifest5(projectRoot);
7824
- const shouldSkip = reusedExistingAnchor && manifest.shared.some((e) => e.type !== "layout");
7825
- if (!shouldSkip) {
7826
- spinner.start("Phase 3.5/5 \u2014 Extracting shared components...");
7991
+ if (remainingPages.length >= 2 && projectRoot) {
7992
+ if (plan && plan.sharedComponents.length > 0) {
7993
+ spinner.start(`Phase 4.5/6 \u2014 Generating ${plan.sharedComponents.length} shared components from plan...`);
7827
7994
  try {
7828
- const extraction = await extractSharedComponents(homePageCode, projectRoot, provider ?? "auto");
7829
- parseOpts.sharedComponentsSummary = extraction.summary;
7830
- if (extraction.components.length > 0) {
7831
- const names = extraction.components.map((c) => c.name).join(", ");
7832
- spinner.succeed(`Phase 3.5/5 \u2014 Extracted ${extraction.components.length} shared components (${names})`);
7995
+ const { generateSharedComponentsFromPlan } = await import("./plan-generator-XKMZTEGK.js");
7996
+ const generated = await generateSharedComponentsFromPlan(
7997
+ plan,
7998
+ styleContext,
7999
+ projectRoot,
8000
+ await createAIProvider(provider ?? "auto")
8001
+ );
8002
+ if (generated.length > 0) {
8003
+ const updatedManifest = await loadManifest5(projectRoot);
8004
+ parseOpts.sharedComponentsSummary = buildSharedComponentsSummary(updatedManifest);
8005
+ const names = generated.map((c) => c.name).join(", ");
8006
+ spinner.succeed(`Phase 4.5/6 \u2014 Generated ${generated.length} shared components (${names})`);
7833
8007
  } else {
7834
- spinner.succeed("Phase 3.5/5 \u2014 No shared components extracted");
8008
+ spinner.succeed("Phase 4.5/6 \u2014 No shared components generated");
7835
8009
  }
7836
8010
  } catch {
7837
- spinner.warn("Phase 3.5/5 \u2014 Could not extract shared components (continuing without)");
8011
+ spinner.warn("Phase 4.5/6 \u2014 Could not generate shared components (continuing without)");
8012
+ }
8013
+ } else if (homePageCode) {
8014
+ const manifest = await loadManifest5(projectRoot);
8015
+ const shouldSkip = reusedExistingAnchor && manifest.shared.some((e) => e.type !== "layout");
8016
+ if (!shouldSkip) {
8017
+ spinner.start("Phase 4.5/6 \u2014 Extracting shared components (legacy)...");
8018
+ try {
8019
+ const extraction = await extractSharedComponents(homePageCode, projectRoot, provider ?? "auto");
8020
+ parseOpts.sharedComponentsSummary = extraction.summary;
8021
+ if (extraction.components.length > 0) {
8022
+ const names = extraction.components.map((c) => c.name).join(", ");
8023
+ spinner.succeed(`Phase 4.5/6 \u2014 Extracted ${extraction.components.length} shared components (${names})`);
8024
+ } else {
8025
+ spinner.succeed("Phase 4.5/6 \u2014 No shared components extracted");
8026
+ }
8027
+ } catch {
8028
+ spinner.warn("Phase 4.5/6 \u2014 Could not extract shared components (continuing without)");
8029
+ }
7838
8030
  }
7839
8031
  }
7840
8032
  }
7841
8033
  if (remainingPages.length === 0) {
7842
- return homeRequest ? [homeRequest] : [];
8034
+ return { requests: homeRequest ? [homeRequest] : [], plan };
7843
8035
  }
7844
- spinner.start(`Phase 4/5 \u2014 Generating ${remainingPages.length} pages in parallel...`);
8036
+ spinner.start(`Phase 5/6 \u2014 Generating ${remainingPages.length} pages in parallel...`);
7845
8037
  const sharedLayoutNote = "Header and Footer are shared components rendered by the root layout. Do NOT include any site-wide <header>, <nav>, or <footer> in this page. Start with the main content directly.";
7846
8038
  const sharedComponentsNote = buildSharedComponentsNote(parseOpts.sharedComponentsSummary);
7847
8039
  const routeNote = `EXISTING ROUTES in this project: ${allRoutes}. All internal links MUST point to one of these routes. If a target doesn't exist, use href="#".`;
7848
8040
  const alignmentNote = 'CRITICAL LAYOUT RULE: Every <section> must wrap its content in a container div matching the header width. Use the EXACT same container classes as shown in the style context (e.g. className="container max-w-6xl px-4" or className="max-w-6xl mx-auto px-4"). Inner content can use narrower max-w for text centering, but the outer section container MUST match.';
8041
+ const planSummaryNote = plan ? formatPlanSummary(plan) : "";
7849
8042
  const existingPagesContext = buildExistingPagesContext(modCtx.config);
7850
8043
  const AI_CONCURRENCY = 3;
7851
- let phase4Done = 0;
8044
+ let phase5Done = 0;
7852
8045
  const remainingRequests = await pMap(
7853
8046
  remainingPages,
7854
8047
  async ({ name, id, route }) => {
7855
8048
  const isAuth = isAuthRoute(route) || isAuthRoute(name);
8049
+ const pageType = plan ? getPageType(route, plan) : inferPageTypeFromRoute(route);
8050
+ const designConstraints = getDesignQualityForType(pageType);
7856
8051
  const authNote = isAuth ? 'For this auth page: use centered card layout with outer div className="flex min-h-svh flex-col items-center justify-center p-6 md:p-10" and inner div className="w-full max-w-sm". Do NOT use section containers or full-width wrappers. The auth layout provides centering \u2014 just output the card content.' : void 0;
7857
8052
  const prompt = [
7858
8053
  `Create ONE page called "${name}" at route "${route}".`,
7859
8054
  `Context: ${message}.`,
7860
8055
  `Generate complete pageCode for this single page only. Do not generate other pages.`,
8056
+ `PAGE TYPE: ${pageType}`,
8057
+ designConstraints,
7861
8058
  sharedLayoutNote,
7862
8059
  sharedComponentsNote,
7863
8060
  routeNote,
7864
8061
  alignmentNote,
7865
8062
  authNote,
8063
+ planSummaryNote,
7866
8064
  existingPagesContext,
7867
8065
  styleContext
7868
8066
  ].filter(Boolean).join("\n\n");
7869
8067
  try {
7870
8068
  const result = await parseModification(prompt, modCtx, provider, parseOpts);
7871
- phase4Done++;
7872
- spinner.text = `Phase 4/5 \u2014 ${phase4Done}/${remainingPages.length} pages generated...`;
8069
+ phase5Done++;
8070
+ spinner.text = `Phase 5/6 \u2014 ${phase5Done}/${remainingPages.length} pages generated...`;
7873
8071
  const codePage = result.requests.find((r) => r.type === "add-page");
7874
8072
  return codePage || { type: "add-page", target: "new", changes: { id, name, route } };
7875
8073
  } catch {
7876
- phase4Done++;
7877
- spinner.text = `Phase 4/5 \u2014 ${phase4Done}/${remainingPages.length} pages generated...`;
8074
+ phase5Done++;
8075
+ spinner.text = `Phase 5/6 \u2014 ${phase5Done}/${remainingPages.length} pages generated...`;
7878
8076
  return { type: "add-page", target: "new", changes: { id, name, route } };
7879
8077
  }
7880
8078
  },
@@ -7889,18 +8087,18 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7889
8087
  const pageName = page.name || page.id || "page";
7890
8088
  const pageRoute = page.route || `/${pageName.toLowerCase()}`;
7891
8089
  try {
8090
+ const retryPageType = plan ? getPageType(pageRoute, plan) : inferPageTypeFromRoute(pageRoute);
7892
8091
  const lightweightPrompt = buildLightweightPagePrompt(
7893
8092
  pageName,
7894
8093
  pageRoute,
7895
8094
  styleContext || "",
7896
- parseOpts.sharedComponentsSummary
7897
- );
7898
- const retryResult = await parseModification(
7899
- lightweightPrompt,
7900
- modCtx,
7901
- provider,
7902
- { ...parseOpts, lightweight: true }
8095
+ parseOpts.sharedComponentsSummary,
8096
+ retryPageType
7903
8097
  );
8098
+ const retryResult = await parseModification(lightweightPrompt, modCtx, provider, {
8099
+ ...parseOpts,
8100
+ lightweight: true
8101
+ });
7904
8102
  const codePage = retryResult.requests.find((r) => r.type === "add-page");
7905
8103
  if (codePage && codePage.changes?.pageCode) {
7906
8104
  const idx = allRequests.indexOf(req);
@@ -7911,8 +8109,8 @@ async function splitGeneratePages(spinner, message, modCtx, provider, parseOpts)
7911
8109
  }
7912
8110
  }
7913
8111
  const withCode = allRequests.filter((r) => r.changes?.pageCode).length;
7914
- spinner.succeed(`Phase 4/5 \u2014 Generated ${allRequests.length} pages (${withCode} with full code)`);
7915
- return allRequests;
8112
+ spinner.succeed(`Phase 5/6 \u2014 Generated ${allRequests.length} pages (${withCode} with full code)`);
8113
+ return { requests: allRequests, plan };
7916
8114
  }
7917
8115
  var SharedExtractionItemSchema = z.object({
7918
8116
  name: z.string().min(2).max(50),
@@ -8026,7 +8224,7 @@ function extractAppNameFromPrompt(prompt) {
8026
8224
  import { resolve as resolve7 } from "path";
8027
8225
  import { mkdir as mkdir4 } from "fs/promises";
8028
8226
  import { dirname as dirname6 } from "path";
8029
- import chalk11 from "chalk";
8227
+ import chalk12 from "chalk";
8030
8228
  import {
8031
8229
  getTemplateForPageType,
8032
8230
  loadManifest as loadManifest6,
@@ -8047,7 +8245,7 @@ import {
8047
8245
  TailwindConfigGenerator
8048
8246
  } from "@getcoherent/core";
8049
8247
  import { integrateSharedLayoutIntoRootLayout as integrateSharedLayoutIntoRootLayout2, generateSharedComponent as generateSharedComponent3 } from "@getcoherent/core";
8050
- import chalk9 from "chalk";
8248
+ import chalk10 from "chalk";
8051
8249
 
8052
8250
  // src/utils/file-hashes.ts
8053
8251
  import { createHash } from "crypto";
@@ -8151,7 +8349,7 @@ async function canOverwriteShared(projectRoot, componentFile, storedHashes) {
8151
8349
  if (!storedHash) return true;
8152
8350
  const edited = await isManuallyEdited(filePath, storedHash);
8153
8351
  if (edited) {
8154
- console.log(chalk9.yellow(` \u26A0 Skipping ${componentFile} \u2014 manually edited since last generation`));
8352
+ console.log(chalk10.yellow(` \u26A0 Skipping ${componentFile} \u2014 manually edited since last generation`));
8155
8353
  }
8156
8354
  return !edited;
8157
8355
  }
@@ -8214,7 +8412,7 @@ async function regenerateLayout(config2, projectRoot, options = { navChanged: fa
8214
8412
  await ensureAppRouteGroupLayout(projectRoot, config2.navigation?.type, options.navChanged);
8215
8413
  } catch (err) {
8216
8414
  if (process.env.COHERENT_DEBUG === "1") {
8217
- console.log(chalk9.dim("Layout integration warning:", err));
8415
+ console.log(chalk10.dim("Layout integration warning:", err));
8218
8416
  }
8219
8417
  }
8220
8418
  }
@@ -8282,6 +8480,59 @@ export default function AppLayout({
8282
8480
  }
8283
8481
  `;
8284
8482
  }
8483
+ function buildGroupLayoutCode(layout, _pages) {
8484
+ if (layout === "sidebar" || layout === "both") {
8485
+ return `import { Sidebar } from '@/components/shared/sidebar'
8486
+
8487
+ export default function GroupLayout({
8488
+ children,
8489
+ }: {
8490
+ children: React.ReactNode
8491
+ }) {
8492
+ return (
8493
+ <div className="flex min-h-[calc(100vh-3.5rem)]">
8494
+ <Sidebar />
8495
+ <main className="flex-1 px-4 sm:px-6 lg:px-8 py-6">
8496
+ {children}
8497
+ </main>
8498
+ </div>
8499
+ )
8500
+ }
8501
+ `;
8502
+ }
8503
+ if (layout === "none") {
8504
+ return `export default function GroupLayout({
8505
+ children,
8506
+ }: {
8507
+ children: React.ReactNode
8508
+ }) {
8509
+ return <>{children}</>
8510
+ }
8511
+ `;
8512
+ }
8513
+ return `export default function GroupLayout({
8514
+ children,
8515
+ }: {
8516
+ children: React.ReactNode
8517
+ }) {
8518
+ return (
8519
+ <main className="mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8 py-6">
8520
+ {children}
8521
+ </main>
8522
+ )
8523
+ }
8524
+ `;
8525
+ }
8526
+ async function ensurePlanGroupLayouts(projectRoot, plan) {
8527
+ const { mkdir: mkdirAsync } = await import("fs/promises");
8528
+ for (const group of plan.groups) {
8529
+ const groupDir = resolve6(projectRoot, "app", `(${group.id})`);
8530
+ await mkdirAsync(groupDir, { recursive: true });
8531
+ const layoutPath = resolve6(groupDir, "layout.tsx");
8532
+ const code = buildGroupLayoutCode(group.layout, group.pages);
8533
+ await writeFile(layoutPath, code);
8534
+ }
8535
+ }
8285
8536
  async function regenerateFiles(modified, config2, projectRoot, options = { navChanged: false }) {
8286
8537
  const componentIds = /* @__PURE__ */ new Set();
8287
8538
  const pageIds = /* @__PURE__ */ new Set();
@@ -8299,7 +8550,7 @@ async function regenerateFiles(modified, config2, projectRoot, options = { navCh
8299
8550
  });
8300
8551
  const sharedInstalled = await scanAndInstallSharedDeps(projectRoot);
8301
8552
  if (sharedInstalled.length > 0 && process.env.COHERENT_DEBUG === "1") {
8302
- console.log(chalk9.dim(` Auto-installed shared deps: ${sharedInstalled.join(", ")}`));
8553
+ console.log(chalk10.dim(` Auto-installed shared deps: ${sharedInstalled.join(", ")}`));
8303
8554
  }
8304
8555
  }
8305
8556
  if (componentIds.size > 0) {
@@ -8356,7 +8607,7 @@ function extractBalancedTag(source, tagName) {
8356
8607
  }
8357
8608
 
8358
8609
  // src/commands/chat/reporting.ts
8359
- import chalk10 from "chalk";
8610
+ import chalk11 from "chalk";
8360
8611
  function extractImportsFrom(code, fromPath) {
8361
8612
  const escaped = fromPath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8362
8613
  const regex = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*['"\`]${escaped}[^'"\`]*['"\`]`, "g");
@@ -8378,27 +8629,27 @@ function printPostGenerationReport(opts) {
8378
8629
  const iconCount = extractImportsFrom(code, "lucide-react").length;
8379
8630
  const hasInstalled = postFixes.some((f) => f.startsWith("Installed:"));
8380
8631
  const syntaxStatus = postFixes.length > 0 ? postFixes.some((f) => f.includes("metadata")) ? "fixed (escaped metadata quotes) \u2714" : "fixed \u2714" : "valid \u2714";
8381
- console.log(chalk10.green(`
8632
+ console.log(chalk11.green(`
8382
8633
  \u2705 Page "${pageTitle}" ${action} at ${filePath}
8383
8634
  `));
8384
8635
  if (uiComponents.length > 0) {
8385
- console.log(chalk10.dim(` Components: ${uiComponents.join(", ")} (from @/components/ui)`));
8636
+ console.log(chalk11.dim(` Components: ${uiComponents.join(", ")} (from @/components/ui)`));
8386
8637
  }
8387
8638
  if (inCodeShared.length > 0) {
8388
- console.log(chalk10.dim(` Shared: ${inCodeShared.map((s) => `${s.id} (${s.name})`).join(", ")}`));
8639
+ console.log(chalk11.dim(` Shared: ${inCodeShared.map((s) => `${s.id} (${s.name})`).join(", ")}`));
8389
8640
  }
8390
8641
  if (layoutShared.length > 0) {
8391
- console.log(chalk10.dim(` Layout: ${layoutShared.map((l) => `${l.id} (${l.name})`).join(", ")} via layout.tsx`));
8642
+ console.log(chalk11.dim(` Layout: ${layoutShared.map((l) => `${l.id} (${l.name})`).join(", ")} via layout.tsx`));
8392
8643
  }
8393
8644
  if (iconCount > 0) {
8394
- console.log(chalk10.dim(` Icons: ${iconCount} from lucide-react`));
8645
+ console.log(chalk11.dim(` Icons: ${iconCount} from lucide-react`));
8395
8646
  }
8396
8647
  if (hasInstalled) {
8397
- console.log(chalk10.dim(" Dependencies: installed \u2714"));
8648
+ console.log(chalk11.dim(" Dependencies: installed \u2714"));
8398
8649
  }
8399
- console.log(chalk10.dim(` Syntax: ${syntaxStatus}`));
8650
+ console.log(chalk11.dim(` Syntax: ${syntaxStatus}`));
8400
8651
  if (route) {
8401
- console.log(chalk10.cyan(`
8652
+ console.log(chalk11.cyan(`
8402
8653
  Preview: http://localhost:3000${route}`));
8403
8654
  }
8404
8655
  console.log("");
@@ -8406,35 +8657,35 @@ function printPostGenerationReport(opts) {
8406
8657
  function printSharedComponentReport(opts) {
8407
8658
  const { id, name, file, instruction, postFixes = [] } = opts;
8408
8659
  const syntaxStatus = postFixes.length > 0 ? "fixed \u2714" : "valid \u2714";
8409
- console.log(chalk10.green(`
8660
+ console.log(chalk11.green(`
8410
8661
  \u2705 Updated ${id} (${name}) at ${file}
8411
8662
  `));
8412
8663
  if (instruction) {
8413
8664
  const snippet = instruction.length > 60 ? instruction.slice(0, 57) + "..." : instruction;
8414
- console.log(chalk10.dim(` Changed: ${snippet}`));
8665
+ console.log(chalk11.dim(` Changed: ${snippet}`));
8415
8666
  }
8416
- console.log(chalk10.dim(" Affects: all pages via layout.tsx"));
8417
- console.log(chalk10.dim(` Syntax: ${syntaxStatus}`));
8667
+ console.log(chalk11.dim(" Affects: all pages via layout.tsx"));
8668
+ console.log(chalk11.dim(` Syntax: ${syntaxStatus}`));
8418
8669
  console.log("");
8419
8670
  }
8420
8671
  function printLinkSharedReport(opts) {
8421
8672
  const { sharedId, sharedName, pageTarget, route, postFixes = [] } = opts;
8422
8673
  const syntaxStatus = postFixes.length > 0 ? "fixed \u2714" : "valid \u2714";
8423
- console.log(chalk10.green(`
8674
+ console.log(chalk11.green(`
8424
8675
  \u2705 Linked ${sharedId} (${sharedName}) to page "${pageTarget}"
8425
8676
  `));
8426
- console.log(chalk10.dim(` Syntax: ${syntaxStatus}`));
8427
- console.log(chalk10.cyan(` Preview: http://localhost:3000${route}`));
8677
+ console.log(chalk11.dim(` Syntax: ${syntaxStatus}`));
8678
+ console.log(chalk11.cyan(` Preview: http://localhost:3000${route}`));
8428
8679
  console.log("");
8429
8680
  }
8430
8681
  function printPromoteAndLinkReport(opts) {
8431
8682
  const { id, name, file, usedInFiles, postFixes = [] } = opts;
8432
8683
  const syntaxStatus = postFixes.length > 0 ? "fixed \u2714" : "valid \u2714";
8433
- console.log(chalk10.green(`
8684
+ console.log(chalk11.green(`
8434
8685
  \u2705 Created ${id} (${name}) at ${file}
8435
8686
  `));
8436
- console.log(chalk10.dim(` Linked to: ${usedInFiles.length} page(s)`));
8437
- console.log(chalk10.dim(` Syntax: ${syntaxStatus}`));
8687
+ console.log(chalk11.dim(` Linked to: ${usedInFiles.length} page(s)`));
8688
+ console.log(chalk11.dim(` Syntax: ${syntaxStatus}`));
8438
8689
  console.log("");
8439
8690
  }
8440
8691
  function showPreview(requests, results, config2, preflightInstalledNames) {
@@ -8452,23 +8703,23 @@ function showPreview(requests, results, config2, preflightInstalledNames) {
8452
8703
  const modifiedSharedComponents = successfulPairs.filter(({ request }) => request.type === "modify-layout-block");
8453
8704
  const modifiedPages = successfulPairs.filter(({ request }) => request.type === "update-page");
8454
8705
  const tokenChanges = successfulPairs.filter(({ request }) => request.type === "update-token");
8455
- console.log(chalk10.bold.cyan("\n\u{1F4CB} Changes Applied:\n"));
8706
+ console.log(chalk11.bold.cyan("\n\u{1F4CB} Changes Applied:\n"));
8456
8707
  if (preflightInstalledNames && preflightInstalledNames.length > 0) {
8457
- console.log(chalk10.cyan("\u{1F50D} Pre-flight check: Installed missing components:"));
8708
+ console.log(chalk11.cyan("\u{1F50D} Pre-flight check: Installed missing components:"));
8458
8709
  preflightInstalledNames.forEach((name) => {
8459
- console.log(chalk10.green(` \u2728 Auto-installed ${name}`));
8710
+ console.log(chalk11.green(` \u2728 Auto-installed ${name}`));
8460
8711
  });
8461
8712
  console.log("");
8462
8713
  }
8463
8714
  if (addedComponents.length > 0) {
8464
8715
  const names = addedComponents.map(({ request }) => request.changes.name).filter(Boolean);
8465
- console.log(chalk10.green("\u{1F4E6} Components:"));
8466
- console.log(chalk10.white(` \u2728 Auto-installed: ${names.join(", ")}`));
8716
+ console.log(chalk11.green("\u{1F4E6} Components:"));
8717
+ console.log(chalk11.white(` \u2728 Auto-installed: ${names.join(", ")}`));
8467
8718
  }
8468
8719
  if (customComponents.length > 0) {
8469
8720
  const names = customComponents.map(({ request }) => request.changes.name).filter(Boolean);
8470
- if (addedComponents.length === 0) console.log(chalk10.green("\u{1F4E6} Components:"));
8471
- console.log(chalk10.white(` \u2728 Created: ${names.join(", ")}`));
8721
+ if (addedComponents.length === 0) console.log(chalk11.green("\u{1F4E6} Components:"));
8722
+ console.log(chalk11.white(` \u2728 Created: ${names.join(", ")}`));
8472
8723
  }
8473
8724
  const usedComponentIds = /* @__PURE__ */ new Set();
8474
8725
  addedPages.forEach(({ request }) => {
@@ -8483,71 +8734,71 @@ function showPreview(requests, results, config2, preflightInstalledNames) {
8483
8734
  ]);
8484
8735
  const reusedIds = [...usedComponentIds].filter((id) => !newComponentIds.has(id));
8485
8736
  if (reusedIds.length > 0) {
8486
- if (addedComponents.length === 0 && customComponents.length === 0) console.log(chalk10.green("\u{1F4E6} Components:"));
8487
- console.log(chalk10.white(` \u{1F504} Reused: ${reusedIds.join(", ")}`));
8737
+ if (addedComponents.length === 0 && customComponents.length === 0) console.log(chalk11.green("\u{1F4E6} Components:"));
8738
+ console.log(chalk11.white(` \u{1F504} Reused: ${reusedIds.join(", ")}`));
8488
8739
  }
8489
8740
  if (addedComponents.length > 0 || customComponents.length > 0 || reusedIds.length > 0) {
8490
8741
  console.log("");
8491
8742
  }
8492
8743
  if (addedPages.length > 0) {
8493
- console.log(chalk10.green("\u{1F4C4} Pages Created:"));
8744
+ console.log(chalk11.green("\u{1F4C4} Pages Created:"));
8494
8745
  addedPages.forEach(({ request }) => {
8495
8746
  const page = request.changes;
8496
8747
  const route = page.route || "/";
8497
- console.log(chalk10.white(` \u2728 ${page.name || "Page"}`));
8498
- console.log(chalk10.gray(` Route: ${route}`));
8499
- console.log(chalk10.gray(` Sections: ${page.sections?.length ?? 0}`));
8748
+ console.log(chalk11.white(` \u2728 ${page.name || "Page"}`));
8749
+ console.log(chalk11.gray(` Route: ${route}`));
8750
+ console.log(chalk11.gray(` Sections: ${page.sections?.length ?? 0}`));
8500
8751
  });
8501
8752
  console.log("");
8502
8753
  }
8503
8754
  if (modifiedComponents.length > 0 || modifiedSharedComponents.length > 0 || modifiedPages.length > 0 || tokenChanges.length > 0) {
8504
- console.log(chalk10.yellow("\u{1F527} Modified:"));
8755
+ console.log(chalk11.yellow("\u{1F527} Modified:"));
8505
8756
  modifiedComponents.forEach(({ result }) => {
8506
- console.log(chalk10.white(` \u2022 ${result.message}`));
8757
+ console.log(chalk11.white(` \u2022 ${result.message}`));
8507
8758
  });
8508
8759
  modifiedSharedComponents.forEach(({ result }) => {
8509
- console.log(chalk10.white(` \u2022 ${result.message}`));
8760
+ console.log(chalk11.white(` \u2022 ${result.message}`));
8510
8761
  });
8511
8762
  modifiedPages.forEach(({ result }) => {
8512
- console.log(chalk10.white(` \u2022 ${result.message}`));
8763
+ console.log(chalk11.white(` \u2022 ${result.message}`));
8513
8764
  });
8514
8765
  tokenChanges.forEach(({ result }) => {
8515
- console.log(chalk10.white(` \u2022 ${result.message}`));
8766
+ console.log(chalk11.white(` \u2022 ${result.message}`));
8516
8767
  });
8517
8768
  console.log("");
8518
8769
  }
8519
8770
  if (failedPairs.length > 0) {
8520
- console.log(chalk10.red("\u274C Failed modifications:"));
8771
+ console.log(chalk11.red("\u274C Failed modifications:"));
8521
8772
  failedPairs.forEach(({ result }) => {
8522
- console.log(chalk10.gray(` \u2716 ${result.message}`));
8773
+ console.log(chalk11.gray(` \u2716 ${result.message}`));
8523
8774
  });
8524
8775
  console.log("");
8525
8776
  }
8526
8777
  const successCount = successfulPairs.length;
8527
8778
  const totalCount = results.length;
8528
8779
  if (successCount === totalCount) {
8529
- console.log(chalk10.green.bold(`\u2705 Success! ${successCount} modification(s) applied
8780
+ console.log(chalk11.green.bold(`\u2705 Success! ${successCount} modification(s) applied
8530
8781
  `));
8531
8782
  } else {
8532
- console.log(chalk10.yellow.bold(`\u26A0\uFE0F Partial success: ${successCount}/${totalCount} modification(s) applied
8783
+ console.log(chalk11.yellow.bold(`\u26A0\uFE0F Partial success: ${successCount}/${totalCount} modification(s) applied
8533
8784
  `));
8534
8785
  }
8535
8786
  if (addedPages.length > 0) {
8536
8787
  const firstPage = addedPages[0].request.changes;
8537
8788
  const route = firstPage?.route || "/";
8538
- console.log(chalk10.cyan("\u{1F680} What's next:\n"));
8539
- console.log(chalk10.white(" \u{1F4FA} View in browser:"));
8540
- console.log(chalk10.cyan(" coherent preview"));
8541
- console.log(chalk10.gray(` \u2192 Opens http://localhost:3000${route}
8789
+ console.log(chalk11.cyan("\u{1F680} What's next:\n"));
8790
+ console.log(chalk11.white(" \u{1F4FA} View in browser:"));
8791
+ console.log(chalk11.cyan(" coherent preview"));
8792
+ console.log(chalk11.gray(` \u2192 Opens http://localhost:3000${route}
8542
8793
  `));
8543
- console.log(chalk10.white(" \u{1F3A8} Customize:"));
8544
- console.log(chalk10.cyan(' coherent chat "make buttons rounded"'));
8545
- console.log(chalk10.cyan(` coherent chat "add hero section to ${firstPage?.name ?? "page"}"`));
8794
+ console.log(chalk11.white(" \u{1F3A8} Customize:"));
8795
+ console.log(chalk11.cyan(' coherent chat "make buttons rounded"'));
8796
+ console.log(chalk11.cyan(` coherent chat "add hero section to ${firstPage?.name ?? "page"}"`));
8546
8797
  console.log("");
8547
8798
  } else if (successCount > 0) {
8548
- console.log(chalk10.cyan("\u{1F680} What's next:\n"));
8549
- console.log(chalk10.white(" \u{1F4FA} Preview changes:"));
8550
- console.log(chalk10.cyan(" coherent preview\n"));
8799
+ console.log(chalk11.cyan("\u{1F680} What's next:\n"));
8800
+ console.log(chalk11.white(" \u{1F4FA} Preview changes:"));
8801
+ console.log(chalk11.cyan(" coherent preview\n"));
8551
8802
  }
8552
8803
  }
8553
8804
  function getChangeDescription(request, config2) {
@@ -8696,8 +8947,8 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8696
8947
  const newCode = await ai.editSharedComponentCode(currentCode, instruction, resolved.name);
8697
8948
  const { fixedCode, fixes } = await validateAndFixGeneratedCode(projectRoot, newCode, { isPage: false });
8698
8949
  if (fixes.length > 0) {
8699
- console.log(chalk11.dim(" \u{1F527} Post-generation fixes:"));
8700
- fixes.forEach((f) => console.log(chalk11.dim(` ${f}`)));
8950
+ console.log(chalk12.dim(" \u{1F527} Post-generation fixes:"));
8951
+ fixes.forEach((f) => console.log(chalk12.dim(` ${f}`)));
8701
8952
  }
8702
8953
  await writeFile(fullPath, fixedCode);
8703
8954
  printSharedComponentReport({
@@ -8770,8 +9021,8 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8770
9021
  const newPageCode = await ai.replaceInlineWithShared(pageCode, sharedCode, resolved.name, changes?.blockHint);
8771
9022
  const { fixedCode, fixes } = await validateAndFixGeneratedCode(projectRoot, newPageCode, { isPage: true });
8772
9023
  if (fixes.length > 0) {
8773
- console.log(chalk11.dim(" \u{1F527} Post-generation fixes:"));
8774
- fixes.forEach((f) => console.log(chalk11.dim(` ${f}`)));
9024
+ console.log(chalk12.dim(" \u{1F527} Post-generation fixes:"));
9025
+ fixes.forEach((f) => console.log(chalk12.dim(` ${f}`)));
8775
9026
  }
8776
9027
  await writeFile(pageFilePath, fixedCode);
8777
9028
  const manifest = await loadManifest6(projectRoot);
@@ -8873,8 +9124,8 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8873
9124
  const newCode = await ai.replaceInlineWithShared(linkPageCode, sharedCode, created.name, blockHint);
8874
9125
  const { fixedCode, fixes } = await validateAndFixGeneratedCode(projectRoot, newCode, { isPage: true });
8875
9126
  if (fixes.length > 0) {
8876
- console.log(chalk11.dim(" \u{1F527} Post-generation fixes:"));
8877
- fixes.forEach((f) => console.log(chalk11.dim(` ${f}`)));
9127
+ console.log(chalk12.dim(" \u{1F527} Post-generation fixes:"));
9128
+ fixes.forEach((f) => console.log(chalk12.dim(` ${f}`)));
8878
9129
  }
8879
9130
  await writeFile(fullPath, fixedCode);
8880
9131
  usedInFiles.push(relPath);
@@ -8965,7 +9216,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8965
9216
  const aiPageCode = typeof page.pageCode === "string" && page.pageCode.trim() !== "" ? page.pageCode : void 0;
8966
9217
  if (aiPageCode) {
8967
9218
  finalPageCode = aiPageCode;
8968
- if (DEBUG2) console.log(chalk11.dim(` [pageCode] Using AI-generated pageCode (user content priority)`));
9219
+ if (DEBUG2) console.log(chalk12.dim(` [pageCode] Using AI-generated pageCode (user content priority)`));
8969
9220
  } else {
8970
9221
  const inferredType = page.pageType || inferPageType(page.route || "", page.name || "");
8971
9222
  if (inferredType) {
@@ -8980,19 +9231,19 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
8980
9231
  const content = page.structuredContent || getDefaultContent(inferredType, page.name || pageName);
8981
9232
  finalPageCode = templateFn(content, opts);
8982
9233
  if (DEBUG2)
8983
- console.log(chalk11.dim(` [template] Used "${inferredType}" template (inferred from route/name)`));
9234
+ console.log(chalk12.dim(` [template] Used "${inferredType}" template (inferred from route/name)`));
8984
9235
  } catch {
8985
- if (DEBUG2) console.log(chalk11.dim(` [template] Failed for "${inferredType}"`));
9236
+ if (DEBUG2) console.log(chalk12.dim(` [template] Failed for "${inferredType}"`));
8986
9237
  }
8987
9238
  }
8988
9239
  }
8989
9240
  }
8990
9241
  if (!finalPageCode) {
8991
- console.log(chalk11.yellow(`
9242
+ console.log(chalk12.yellow(`
8992
9243
  \u26A0\uFE0F Page "${page.name || page.id}" has no generated code \u2014 it will appear empty.`));
8993
- console.log(chalk11.dim(" This usually means the AI did not produce pageCode for this page."));
9244
+ console.log(chalk12.dim(" This usually means the AI did not produce pageCode for this page."));
8994
9245
  console.log(
8995
- chalk11.dim(
9246
+ chalk12.dim(
8996
9247
  ' Try running: coherent chat "regenerate the ' + (page.name || page.id) + ' page with full content"'
8997
9248
  )
8998
9249
  );
@@ -9046,7 +9297,9 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
9046
9297
  }
9047
9298
  const { code: layoutStripped, stripped } = stripInlineLayoutElements(codeToWrite);
9048
9299
  codeToWrite = layoutStripped;
9049
- if (!isMarketingRoute(route) && !isAuthRoute(route)) {
9300
+ const currentPlan = projectRoot ? loadPlan(projectRoot) : null;
9301
+ const pageType = currentPlan ? getPageType(route, currentPlan) : isMarketingRoute(route) ? "marketing" : isAuth ? "auth" : "app";
9302
+ if (pageType === "app") {
9050
9303
  const { code: normalized, fixed: wrapperFixed } = normalizePageWrapper(codeToWrite);
9051
9304
  if (wrapperFixed) {
9052
9305
  codeToWrite = normalized;
@@ -9056,8 +9309,8 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
9056
9309
  const allFixes = [...postFixes, ...autoFixes];
9057
9310
  if (stripped.length > 0) allFixes.push(`stripped inline ${stripped.join(", ")} (layout owns these)`);
9058
9311
  if (allFixes.length > 0) {
9059
- console.log(chalk11.dim(" \u{1F527} Post-generation fixes:"));
9060
- allFixes.forEach((f) => console.log(chalk11.dim(` ${f}`)));
9312
+ console.log(chalk12.dim(" \u{1F527} Post-generation fixes:"));
9313
+ allFixes.forEach((f) => console.log(chalk12.dim(` ${f}`)));
9061
9314
  }
9062
9315
  await writeFile(filePath, codeToWrite);
9063
9316
  const pageIdx = dsm.getConfig().pages.findIndex((p) => p.id === page.id);
@@ -9069,7 +9322,15 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
9069
9322
  pm.updateConfig(cfg);
9070
9323
  }
9071
9324
  const manifestForAudit = await loadManifest6(projectRoot);
9072
- await warnInlineDuplicates(projectRoot, page.name || page.id || route.slice(1), codeToWrite, manifestForAudit);
9325
+ const planForAudit = loadPlan(projectRoot);
9326
+ await warnInlineDuplicates(
9327
+ projectRoot,
9328
+ page.name || page.id || route.slice(1),
9329
+ route,
9330
+ codeToWrite,
9331
+ manifestForAudit,
9332
+ planForAudit ?? void 0
9333
+ );
9073
9334
  const relFilePath = routeToRelPath(route, isAuth);
9074
9335
  printPostGenerationReport({
9075
9336
  action: "created",
@@ -9086,7 +9347,7 @@ async function applyModification(request, dsm, cm, pm, projectRoot, aiProvider,
9086
9347
  const errors = issues.filter((i) => i.severity === "error");
9087
9348
  if (errors.length >= 2 && aiProvider) {
9088
9349
  console.log(
9089
- chalk11.yellow(`
9350
+ chalk12.yellow(`
9090
9351
  \u{1F504} ${errors.length} quality errors \u2014 attempting AI fix for ${page.name || page.id}...`)
9091
9352
  );
9092
9353
  try {
@@ -9115,7 +9376,7 @@ Rules:
9115
9376
  await writeFile(filePath, codeToWrite);
9116
9377
  issues = validatePageQuality(codeToWrite);
9117
9378
  const finalErrors = issues.filter((i) => i.severity === "error").length;
9118
- console.log(chalk11.green(` \u2714 Quality fix: ${errors.length} \u2192 ${finalErrors} errors`));
9379
+ console.log(chalk12.green(` \u2714 Quality fix: ${errors.length} \u2192 ${finalErrors} errors`));
9119
9380
  }
9120
9381
  }
9121
9382
  }
@@ -9124,15 +9385,15 @@ Rules:
9124
9385
  }
9125
9386
  const report = formatIssues(issues);
9126
9387
  if (report) {
9127
- console.log(chalk11.yellow(`
9388
+ console.log(chalk12.yellow(`
9128
9389
  \u{1F50D} Quality check for ${page.name || page.id}:`));
9129
- console.log(chalk11.dim(report));
9390
+ console.log(chalk12.dim(report));
9130
9391
  }
9131
9392
  const consistency = checkDesignConsistency(codeToWrite);
9132
9393
  if (consistency.length > 0) {
9133
- console.log(chalk11.yellow(`
9394
+ console.log(chalk12.yellow(`
9134
9395
  \u{1F3A8} Design consistency for ${page.name || page.id}:`));
9135
- consistency.forEach((w) => console.log(chalk11.dim(` \u26A0 [${w.type}] ${w.message}`)));
9396
+ consistency.forEach((w) => console.log(chalk12.dim(` \u26A0 [${w.type}] ${w.message}`)));
9136
9397
  }
9137
9398
  }
9138
9399
  }
@@ -9147,9 +9408,9 @@ Rules:
9147
9408
  const changes = request.changes;
9148
9409
  const instruction = originalMessage || (typeof changes?.instruction === "string" ? changes.instruction : void 0);
9149
9410
  let resolvedPageCode = typeof changes?.pageCode === "string" && changes.pageCode.trim() !== "" ? changes.pageCode : void 0;
9150
- if (DEBUG2 && instruction) console.log(chalk11.dim(` [update-page] instruction: ${instruction.slice(0, 120)}...`));
9411
+ if (DEBUG2 && instruction) console.log(chalk12.dim(` [update-page] instruction: ${instruction.slice(0, 120)}...`));
9151
9412
  if (DEBUG2 && resolvedPageCode)
9152
- console.log(chalk11.dim(` [update-page] has pageCode (${resolvedPageCode.length} chars)`));
9413
+ console.log(chalk12.dim(` [update-page] has pageCode (${resolvedPageCode.length} chars)`));
9153
9414
  const configChanges = { ...changes };
9154
9415
  delete configChanges.pageCode;
9155
9416
  delete configChanges.pageType;
@@ -9173,12 +9434,12 @@ Rules:
9173
9434
  try {
9174
9435
  currentCode = await readFile(absPath);
9175
9436
  } catch {
9176
- if (DEBUG2) console.log(chalk11.dim(` [update-page] Could not read current file at ${absPath}`));
9437
+ if (DEBUG2) console.log(chalk12.dim(` [update-page] Could not read current file at ${absPath}`));
9177
9438
  }
9178
9439
  if (currentCode) {
9179
9440
  const ai = await createAIProvider(aiProvider ?? "auto");
9180
9441
  if (ai.editPageCode) {
9181
- console.log(chalk11.dim(" \u270F\uFE0F Applying changes to existing page..."));
9442
+ console.log(chalk12.dim(" \u270F\uFE0F Applying changes to existing page..."));
9182
9443
  const coreRules = CORE_CONSTRAINTS;
9183
9444
  const qualityRules = DESIGN_QUALITY;
9184
9445
  const contextualRules = selectContextualRules(instruction);
@@ -9198,15 +9459,15 @@ ${contextualRules}
9198
9459
  ${routeRules}
9199
9460
  ${pagesCtx}`
9200
9461
  );
9201
- if (DEBUG2) console.log(chalk11.dim(` [update-page] AI returned ${resolvedPageCode.length} chars`));
9462
+ if (DEBUG2) console.log(chalk12.dim(` [update-page] AI returned ${resolvedPageCode.length} chars`));
9202
9463
  const editIssues = verifyIncrementalEdit(currentCode, resolvedPageCode);
9203
9464
  if (editIssues.length > 0) {
9204
- console.log(chalk11.yellow(`
9465
+ console.log(chalk12.yellow(`
9205
9466
  \u26A0 Incremental edit issues for ${pageDef.name || pageDef.id}:`));
9206
- editIssues.forEach((issue) => console.log(chalk11.dim(` [${issue.type}] ${issue.message}`)));
9467
+ editIssues.forEach((issue) => console.log(chalk12.dim(` [${issue.type}] ${issue.message}`)));
9207
9468
  }
9208
9469
  } else {
9209
- console.log(chalk11.yellow(" \u26A0 AI provider does not support editPageCode"));
9470
+ console.log(chalk12.yellow(" \u26A0 AI provider does not support editPageCode"));
9210
9471
  }
9211
9472
  }
9212
9473
  }
@@ -9246,7 +9507,9 @@ ${pagesCtx}`
9246
9507
  }
9247
9508
  const { code: layoutStripped, stripped } = stripInlineLayoutElements(codeToWrite);
9248
9509
  codeToWrite = layoutStripped;
9249
- if (!isMarketingRoute(route) && !isAuthRoute(route)) {
9510
+ const currentPlan2 = projectRoot ? loadPlan(projectRoot) : null;
9511
+ const pageType2 = currentPlan2 ? getPageType(route, currentPlan2) : isMarketingRoute(route) ? "marketing" : isAuth ? "auth" : "app";
9512
+ if (pageType2 === "app") {
9250
9513
  const { code: normalized, fixed: wrapperFixed } = normalizePageWrapper(codeToWrite);
9251
9514
  if (wrapperFixed) {
9252
9515
  codeToWrite = normalized;
@@ -9256,8 +9519,8 @@ ${pagesCtx}`
9256
9519
  const allFixes = [...postFixes, ...autoFixes];
9257
9520
  if (stripped.length > 0) allFixes.push(`stripped inline ${stripped.join(", ")} (layout owns these)`);
9258
9521
  if (allFixes.length > 0) {
9259
- console.log(chalk11.dim(" \u{1F527} Post-generation fixes:"));
9260
- allFixes.forEach((f) => console.log(chalk11.dim(` ${f}`)));
9522
+ console.log(chalk12.dim(" \u{1F527} Post-generation fixes:"));
9523
+ allFixes.forEach((f) => console.log(chalk12.dim(` ${f}`)));
9261
9524
  }
9262
9525
  await writeFile(absPath, codeToWrite);
9263
9526
  const updatePageIdx = dsm.getConfig().pages.findIndex((p) => p.id === pageDef.id);
@@ -9269,11 +9532,14 @@ ${pagesCtx}`
9269
9532
  pm.updateConfig(cfg);
9270
9533
  }
9271
9534
  const manifestForAudit = await loadManifest6(projectRoot);
9535
+ const planForAudit2 = loadPlan(projectRoot);
9272
9536
  await warnInlineDuplicates(
9273
9537
  projectRoot,
9274
9538
  pageDef.name || pageDef.id || route.slice(1),
9539
+ route,
9275
9540
  codeToWrite,
9276
- manifestForAudit
9541
+ manifestForAudit,
9542
+ planForAudit2 ?? void 0
9277
9543
  );
9278
9544
  const relFilePath = routeToRelPath(route, isAuth);
9279
9545
  printPostGenerationReport({
@@ -9290,15 +9556,15 @@ ${pagesCtx}`
9290
9556
  const issues = validatePageQuality(codeToWrite);
9291
9557
  const report = formatIssues(issues);
9292
9558
  if (report) {
9293
- console.log(chalk11.yellow(`
9559
+ console.log(chalk12.yellow(`
9294
9560
  \u{1F50D} Quality check for ${pageDef.name || pageDef.id}:`));
9295
- console.log(chalk11.dim(report));
9561
+ console.log(chalk12.dim(report));
9296
9562
  }
9297
9563
  const consistency = checkDesignConsistency(codeToWrite);
9298
9564
  if (consistency.length > 0) {
9299
- console.log(chalk11.yellow(`
9565
+ console.log(chalk12.yellow(`
9300
9566
  \u{1F3A8} Design consistency for ${pageDef.name || pageDef.id}:`));
9301
- consistency.forEach((w) => console.log(chalk11.dim(` \u26A0 [${w.type}] ${w.message}`)));
9567
+ consistency.forEach((w) => console.log(chalk12.dim(` \u26A0 [${w.type}] ${w.message}`)));
9302
9568
  }
9303
9569
  } else {
9304
9570
  try {
@@ -9307,8 +9573,8 @@ ${pagesCtx}`
9307
9573
  if (fixes.length > 0) {
9308
9574
  code = fixed;
9309
9575
  await writeFile(absPath, code);
9310
- console.log(chalk11.dim(" \u{1F527} Auto-fixes applied:"));
9311
- fixes.forEach((f) => console.log(chalk11.dim(` ${f}`)));
9576
+ console.log(chalk12.dim(" \u{1F527} Auto-fixes applied:"));
9577
+ fixes.forEach((f) => console.log(chalk12.dim(` ${f}`)));
9312
9578
  }
9313
9579
  const relFilePath = routeToRelPath(route, isAuth);
9314
9580
  const manifest = await loadManifest6(projectRoot);
@@ -9325,9 +9591,9 @@ ${pagesCtx}`
9325
9591
  const issues = validatePageQuality(code);
9326
9592
  const report = formatIssues(issues);
9327
9593
  if (report) {
9328
- console.log(chalk11.yellow(`
9594
+ console.log(chalk12.yellow(`
9329
9595
  \u{1F50D} Quality check for ${pageDef.name || pageDef.id}:`));
9330
- console.log(chalk11.dim(report));
9596
+ console.log(chalk12.dim(report));
9331
9597
  }
9332
9598
  } catch {
9333
9599
  }
@@ -9450,7 +9716,7 @@ function hasNavChanged(before, after) {
9450
9716
  }
9451
9717
 
9452
9718
  // src/commands/chat/interactive.ts
9453
- import chalk12 from "chalk";
9719
+ import chalk13 from "chalk";
9454
9720
  import { resolve as resolve8 } from "path";
9455
9721
  import { existsSync as existsSync15, readFileSync as readFileSync10, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5 } from "fs";
9456
9722
  import { DesignSystemManager as DesignSystemManager6, ComponentManager as ComponentManager4, loadManifest as loadManifest7 } from "@getcoherent/core";
@@ -9468,7 +9734,7 @@ async function interactiveChat(options, chatCommandFn) {
9468
9734
  const validProviders = ["claude", "openai", "auto"];
9469
9735
  const provider = (options.provider || "auto").toLowerCase();
9470
9736
  if (!validProviders.includes(provider)) {
9471
- console.error(chalk12.red(`
9737
+ console.error(chalk13.red(`
9472
9738
  \u274C Invalid provider: ${options.provider}`));
9473
9739
  process.exit(1);
9474
9740
  }
@@ -9483,13 +9749,13 @@ async function interactiveChat(options, chatCommandFn) {
9483
9749
  } catch (e) {
9484
9750
  if (DEBUG3) console.error("Failed to load REPL history:", e);
9485
9751
  }
9486
- console.log(chalk12.cyan("\n\u{1F3A8} Coherent Interactive Mode"));
9487
- console.log(chalk12.dim(" Type your requests, or use built-in commands."));
9488
- console.log(chalk12.dim(' Type "help" for available commands, "exit" to quit.\n'));
9752
+ console.log(chalk13.cyan("\n\u{1F3A8} Coherent Interactive Mode"));
9753
+ console.log(chalk13.dim(" Type your requests, or use built-in commands."));
9754
+ console.log(chalk13.dim(' Type "help" for available commands, "exit" to quit.\n'));
9489
9755
  const rl = createInterface({
9490
9756
  input: process.stdin,
9491
9757
  output: process.stdout,
9492
- prompt: chalk12.cyan("Coherent> "),
9758
+ prompt: chalk13.cyan("Coherent> "),
9493
9759
  history,
9494
9760
  historySize: 200
9495
9761
  });
@@ -9503,37 +9769,37 @@ async function interactiveChat(options, chatCommandFn) {
9503
9769
  const lower = input.toLowerCase();
9504
9770
  if (lower === "exit" || lower === "quit" || lower === "q") {
9505
9771
  saveHistory();
9506
- console.log(chalk12.dim("\nBye!\n"));
9772
+ console.log(chalk13.dim("\nBye!\n"));
9507
9773
  rl.close();
9508
9774
  process.exit(0);
9509
9775
  }
9510
9776
  if (lower === "help") {
9511
- console.log(chalk12.bold("\n Built-in commands:"));
9512
- console.log(chalk12.white(" components") + chalk12.dim(" \u2014 list shared and UI components"));
9513
- console.log(chalk12.white(" pages") + chalk12.dim(" \u2014 list all pages"));
9514
- console.log(chalk12.white(" tokens") + chalk12.dim(" \u2014 show design tokens"));
9515
- console.log(chalk12.white(" status") + chalk12.dim(" \u2014 project summary"));
9516
- console.log(chalk12.white(" help") + chalk12.dim(" \u2014 this help"));
9517
- console.log(chalk12.white(" exit") + chalk12.dim(" \u2014 quit interactive mode"));
9518
- console.log(chalk12.bold("\n Target shortcuts:"));
9519
- console.log(chalk12.white(" @ComponentName <msg>") + chalk12.dim(" \u2014 target a shared component"));
9520
- console.log(chalk12.white(" @/route <msg>") + chalk12.dim(" \u2014 target a page by route"));
9521
- console.log(chalk12.dim("\n Anything else is sent to AI as a modification request.\n"));
9777
+ console.log(chalk13.bold("\n Built-in commands:"));
9778
+ console.log(chalk13.white(" components") + chalk13.dim(" \u2014 list shared and UI components"));
9779
+ console.log(chalk13.white(" pages") + chalk13.dim(" \u2014 list all pages"));
9780
+ console.log(chalk13.white(" tokens") + chalk13.dim(" \u2014 show design tokens"));
9781
+ console.log(chalk13.white(" status") + chalk13.dim(" \u2014 project summary"));
9782
+ console.log(chalk13.white(" help") + chalk13.dim(" \u2014 this help"));
9783
+ console.log(chalk13.white(" exit") + chalk13.dim(" \u2014 quit interactive mode"));
9784
+ console.log(chalk13.bold("\n Target shortcuts:"));
9785
+ console.log(chalk13.white(" @ComponentName <msg>") + chalk13.dim(" \u2014 target a shared component"));
9786
+ console.log(chalk13.white(" @/route <msg>") + chalk13.dim(" \u2014 target a page by route"));
9787
+ console.log(chalk13.dim("\n Anything else is sent to AI as a modification request.\n"));
9522
9788
  rl.prompt();
9523
9789
  return;
9524
9790
  }
9525
9791
  if (lower === "components" || lower === "list components" || lower.includes("what components")) {
9526
9792
  const manifest = await loadManifest7(projectRoot);
9527
9793
  if (manifest.shared.length === 0) {
9528
- console.log(chalk12.gray("\n No shared components yet.\n"));
9794
+ console.log(chalk13.gray("\n No shared components yet.\n"));
9529
9795
  } else {
9530
9796
  console.log("");
9531
9797
  const order = { layout: 0, section: 1, widget: 2 };
9532
9798
  const sorted = [...manifest.shared].sort((a, b) => (order[a.type] ?? 9) - (order[b.type] ?? 9));
9533
9799
  sorted.forEach((entry) => {
9534
- const usage = entry.usedIn.includes("app/layout.tsx") ? chalk12.green("all pages") : entry.usedIn.length > 0 ? chalk12.gray(entry.usedIn.join(", ")) : chalk12.gray("unused");
9800
+ const usage = entry.usedIn.includes("app/layout.tsx") ? chalk13.green("all pages") : entry.usedIn.length > 0 ? chalk13.gray(entry.usedIn.join(", ")) : chalk13.gray("unused");
9535
9801
  console.log(
9536
- ` ${chalk12.cyan(entry.id.padEnd(8))} ${chalk12.white(entry.name.padEnd(18))} ${chalk12.gray(entry.type.padEnd(9))} ${usage}`
9802
+ ` ${chalk13.cyan(entry.id.padEnd(8))} ${chalk13.white(entry.name.padEnd(18))} ${chalk13.gray(entry.type.padEnd(9))} ${usage}`
9537
9803
  );
9538
9804
  });
9539
9805
  console.log("");
@@ -9544,11 +9810,11 @@ async function interactiveChat(options, chatCommandFn) {
9544
9810
  if (lower === "pages" || lower === "list pages" || lower.includes("what pages")) {
9545
9811
  const currentConfig = dsm.getConfig();
9546
9812
  if (currentConfig.pages.length === 0) {
9547
- console.log(chalk12.gray("\n No pages yet.\n"));
9813
+ console.log(chalk13.gray("\n No pages yet.\n"));
9548
9814
  } else {
9549
9815
  console.log("");
9550
9816
  currentConfig.pages.forEach((p) => {
9551
- console.log(` ${chalk12.white(p.name.padEnd(22))} ${chalk12.gray(p.route)}`);
9817
+ console.log(` ${chalk13.white(p.name.padEnd(22))} ${chalk13.gray(p.route)}`);
9552
9818
  });
9553
9819
  console.log("");
9554
9820
  }
@@ -9558,10 +9824,10 @@ async function interactiveChat(options, chatCommandFn) {
9558
9824
  if (lower === "status") {
9559
9825
  const currentConfig = dsm.getConfig();
9560
9826
  const manifest = await loadManifest7(projectRoot);
9561
- console.log(chalk12.bold(`
9827
+ console.log(chalk13.bold(`
9562
9828
  ${currentConfig.name || "Coherent Project"}`));
9563
9829
  console.log(
9564
- chalk12.dim(
9830
+ chalk13.dim(
9565
9831
  ` Pages: ${currentConfig.pages.length} | Shared components: ${manifest.shared.length} | UI components: ${cm.getAllComponents().length}
9566
9832
  `
9567
9833
  )
@@ -9572,21 +9838,21 @@ async function interactiveChat(options, chatCommandFn) {
9572
9838
  if (lower === "tokens" || lower === "show tokens" || lower === "design tokens") {
9573
9839
  const currentConfig = dsm.getConfig();
9574
9840
  const t = currentConfig.tokens;
9575
- console.log(chalk12.bold("\n Design Tokens\n"));
9576
- console.log(chalk12.cyan(" Colors (light)"));
9841
+ console.log(chalk13.bold("\n Design Tokens\n"));
9842
+ console.log(chalk13.cyan(" Colors (light)"));
9577
9843
  for (const [k, v] of Object.entries(t.colors.light)) {
9578
- console.log(` ${chalk12.white(k.padEnd(14))} ${chalk12.gray(v)}`);
9844
+ console.log(` ${chalk13.white(k.padEnd(14))} ${chalk13.gray(v)}`);
9579
9845
  }
9580
- console.log(chalk12.cyan("\n Typography"));
9581
- console.log(` ${chalk12.white("sans".padEnd(14))} ${chalk12.gray(t.typography.fontFamily.sans)}`);
9582
- console.log(` ${chalk12.white("mono".padEnd(14))} ${chalk12.gray(t.typography.fontFamily.mono)}`);
9583
- console.log(chalk12.cyan("\n Spacing"));
9846
+ console.log(chalk13.cyan("\n Typography"));
9847
+ console.log(` ${chalk13.white("sans".padEnd(14))} ${chalk13.gray(t.typography.fontFamily.sans)}`);
9848
+ console.log(` ${chalk13.white("mono".padEnd(14))} ${chalk13.gray(t.typography.fontFamily.mono)}`);
9849
+ console.log(chalk13.cyan("\n Spacing"));
9584
9850
  for (const [k, v] of Object.entries(t.spacing)) {
9585
- console.log(` ${chalk12.white(k.padEnd(14))} ${chalk12.gray(v)}`);
9851
+ console.log(` ${chalk13.white(k.padEnd(14))} ${chalk13.gray(v)}`);
9586
9852
  }
9587
- console.log(chalk12.cyan("\n Radius"));
9853
+ console.log(chalk13.cyan("\n Radius"));
9588
9854
  for (const [k, v] of Object.entries(t.radius)) {
9589
- console.log(` ${chalk12.white(k.padEnd(14))} ${chalk12.gray(v)}`);
9855
+ console.log(` ${chalk13.white(k.padEnd(14))} ${chalk13.gray(v)}`);
9590
9856
  }
9591
9857
  console.log("");
9592
9858
  rl.prompt();
@@ -9608,7 +9874,7 @@ async function interactiveChat(options, chatCommandFn) {
9608
9874
  await dsm.load();
9609
9875
  } catch (err) {
9610
9876
  if (!err._printed) {
9611
- console.error(chalk12.red(`
9877
+ console.error(chalk13.red(`
9612
9878
  Error: ${err.message}
9613
9879
  `));
9614
9880
  }
@@ -9640,8 +9906,8 @@ async function chatCommand(message, options) {
9640
9906
  process.exit(1);
9641
9907
  };
9642
9908
  if (!message) {
9643
- console.error(chalk13.red('\n\u274C No message provided. Use: coherent chat "your request"\n'));
9644
- console.log(chalk13.dim(" Or use interactive mode: coherent chat -i\n"));
9909
+ console.error(chalk14.red('\n\u274C No message provided. Use: coherent chat "your request"\n'));
9910
+ console.log(chalk14.dim(" Or use interactive mode: coherent chat -i\n"));
9645
9911
  bail("No message provided");
9646
9912
  }
9647
9913
  const spinner = ora2("Processing your request...").start();
@@ -9651,7 +9917,7 @@ async function chatCommand(message, options) {
9651
9917
  const migrationGuard = join11(projectRoot, ".coherent", "migration-in-progress");
9652
9918
  if (existsSync16(migrationGuard)) {
9653
9919
  spinner.fail("Migration in progress");
9654
- console.error(chalk13.red("\n\u274C A migration is in progress. Run `coherent migrate --rollback` to undo first."));
9920
+ console.error(chalk14.red("\n\u274C A migration is in progress. Run `coherent migrate --rollback` to undo first."));
9655
9921
  bail("Migration in progress");
9656
9922
  }
9657
9923
  const validProviders = ["claude", "openai", "auto"];
@@ -9661,20 +9927,20 @@ async function chatCommand(message, options) {
9661
9927
  releaseLock = await acquireProjectLock(projectRoot);
9662
9928
  if (!validProviders.includes(provider)) {
9663
9929
  spinner.fail("Invalid provider");
9664
- console.error(chalk13.red(`
9930
+ console.error(chalk14.red(`
9665
9931
  \u274C Invalid provider: ${options.provider}`));
9666
- console.log(chalk13.dim(`Valid options: ${validProviders.join(", ")}`));
9932
+ console.log(chalk14.dim(`Valid options: ${validProviders.join(", ")}`));
9667
9933
  bail(`Invalid provider: ${options.provider}`);
9668
9934
  }
9669
9935
  spinner.text = "Loading design system configuration...";
9670
9936
  const config2 = await loadConfig(configPath);
9671
9937
  if (config2.coherentVersion && config2.coherentVersion !== CLI_VERSION2) {
9672
9938
  spinner.stop();
9673
- console.log(chalk13.yellow("\n\u26A0\uFE0F Version mismatch detected\n"));
9674
- console.log(chalk13.gray(" Project created with: ") + chalk13.white(`v${config2.coherentVersion}`));
9675
- console.log(chalk13.gray(" Current CLI version: ") + chalk13.white(`v${CLI_VERSION2}`));
9676
- console.log(chalk13.cyan("\n \u{1F4A1} Run `coherent update` to apply latest changes to your project.\n"));
9677
- console.log(chalk13.dim(" Continuing anyway...\n"));
9939
+ console.log(chalk14.yellow("\n\u26A0\uFE0F Version mismatch detected\n"));
9940
+ console.log(chalk14.gray(" Project created with: ") + chalk14.white(`v${config2.coherentVersion}`));
9941
+ console.log(chalk14.gray(" Current CLI version: ") + chalk14.white(`v${CLI_VERSION2}`));
9942
+ console.log(chalk14.cyan("\n \u{1F4A1} Run `coherent update` to apply latest changes to your project.\n"));
9943
+ console.log(chalk14.dim(" Continuing anyway...\n"));
9678
9944
  spinner.start("Loading design system configuration...");
9679
9945
  }
9680
9946
  if (needsGlobalsFix(projectRoot)) {
@@ -9701,9 +9967,9 @@ async function chatCommand(message, options) {
9701
9967
  const done = await setDefaultDarkTheme(projectRoot);
9702
9968
  spinner.stop();
9703
9969
  if (done) {
9704
- console.log(chalk13.green("\n\u2705 Default theme set to dark. Reload the app to see changes.\n"));
9970
+ console.log(chalk14.green("\n\u2705 Default theme set to dark. Reload the app to see changes.\n"));
9705
9971
  } else {
9706
- console.log(chalk13.yellow("\n\u26A0\uFE0F Could not update layout (app/layout.tsx not found).\n"));
9972
+ console.log(chalk14.yellow("\n\u26A0\uFE0F Could not update layout (app/layout.tsx not found).\n"));
9707
9973
  }
9708
9974
  return;
9709
9975
  }
@@ -9719,10 +9985,10 @@ async function chatCommand(message, options) {
9719
9985
  dsm.updateConfig(cfg);
9720
9986
  dsm.save();
9721
9987
  spinner.stop();
9722
- console.log(chalk13.green("\n\u2705 Default theme set to light. Reload the app to see changes.\n"));
9988
+ console.log(chalk14.green("\n\u2705 Default theme set to light. Reload the app to see changes.\n"));
9723
9989
  } catch {
9724
9990
  spinner.stop();
9725
- console.log(chalk13.yellow("\n\u26A0\uFE0F Could not update layout (app/layout.tsx not found).\n"));
9991
+ console.log(chalk14.yellow("\n\u26A0\uFE0F Could not update layout (app/layout.tsx not found).\n"));
9726
9992
  }
9727
9993
  return;
9728
9994
  }
@@ -9732,7 +9998,7 @@ async function chatCommand(message, options) {
9732
9998
  const { created, id } = await ensureThemeToggle(projectRoot);
9733
9999
  spinner.stop();
9734
10000
  console.log(
9735
- chalk13.green(
10001
+ chalk14.green(
9736
10002
  `
9737
10003
  \u2705 ${created ? `Created ${id} (ThemeToggle) and added to layout` : "ThemeToggle already present; layout updated"}.
9738
10004
  `
@@ -9740,7 +10006,7 @@ async function chatCommand(message, options) {
9740
10006
  );
9741
10007
  } catch (e) {
9742
10008
  spinner.fail("Failed to add theme toggle");
9743
- if (e instanceof Error) console.error(chalk13.red("\n\u274C " + e.message + "\n"));
10009
+ if (e instanceof Error) console.error(chalk14.red("\n\u274C " + e.message + "\n"));
9744
10010
  }
9745
10011
  return;
9746
10012
  }
@@ -9756,12 +10022,12 @@ async function chatCommand(message, options) {
9756
10022
  manifest = { ...manifest, shared: validShared };
9757
10023
  await saveManifest2(project.root, manifest);
9758
10024
  if (DEBUG4) {
9759
- console.log(chalk13.dim(`[pre-gen] Cleaned ${cleaned} orphaned component(s) from manifest`));
10025
+ console.log(chalk14.dim(`[pre-gen] Cleaned ${cleaned} orphaned component(s) from manifest`));
9760
10026
  }
9761
10027
  }
9762
10028
  const sharedComponentsSummary = buildSharedComponentsSummary(manifest);
9763
10029
  if (DEBUG4 && sharedComponentsSummary) {
9764
- console.log(chalk13.dim("[add-page] sharedComponentsSummary in prompt:\n" + sharedComponentsSummary));
10030
+ console.log(chalk14.dim("[add-page] sharedComponentsSummary in prompt:\n" + sharedComponentsSummary));
9765
10031
  }
9766
10032
  let requests;
9767
10033
  let uxRecommendations;
@@ -9773,7 +10039,12 @@ async function chatCommand(message, options) {
9773
10039
  ) || []).length >= SPLIT_THRESHOLD;
9774
10040
  if (multiPageHint) {
9775
10041
  try {
9776
- requests = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
10042
+ const splitResult = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
10043
+ requests = splitResult.requests;
10044
+ if (splitResult.plan && projectRoot) {
10045
+ savePlan(projectRoot, splitResult.plan);
10046
+ await ensurePlanGroupLayouts(projectRoot, splitResult.plan);
10047
+ }
9777
10048
  uxRecommendations = void 0;
9778
10049
  } catch {
9779
10050
  spinner.warn("Split generation encountered an issue \u2014 trying page-by-page...");
@@ -9846,7 +10117,12 @@ async function chatCommand(message, options) {
9846
10117
  if (isTruncated || isJsonError) {
9847
10118
  spinner.warn("Response too large \u2014 splitting into smaller requests...");
9848
10119
  try {
9849
- requests = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
10120
+ const splitResult = await splitGeneratePages(spinner, message, modCtx, provider, parseOpts);
10121
+ requests = splitResult.requests;
10122
+ if (splitResult.plan && projectRoot) {
10123
+ savePlan(projectRoot, splitResult.plan);
10124
+ await ensurePlanGroupLayouts(projectRoot, splitResult.plan);
10125
+ }
9850
10126
  uxRecommendations = void 0;
9851
10127
  } catch {
9852
10128
  throw firstError;
@@ -9858,10 +10134,10 @@ async function chatCommand(message, options) {
9858
10134
  }
9859
10135
  if (requests.length === 0) {
9860
10136
  spinner.fail("No modifications found in your request");
9861
- console.log(chalk13.yellow("\n\u{1F4A1} Try being more specific, e.g.:"));
9862
- console.log(chalk13.dim(' - "make buttons blue"'));
9863
- console.log(chalk13.dim(' - "add a pricing page"'));
9864
- console.log(chalk13.dim(' - "change primary color to green"'));
10137
+ console.log(chalk14.yellow("\n\u{1F4A1} Try being more specific, e.g.:"));
10138
+ console.log(chalk14.dim(' - "make buttons blue"'));
10139
+ console.log(chalk14.dim(' - "add a pricing page"'));
10140
+ console.log(chalk14.dim(' - "change primary color to green"'));
9865
10141
  return;
9866
10142
  }
9867
10143
  spinner.succeed(`Parsed ${requests.length} modification(s)`);
@@ -9869,11 +10145,11 @@ async function chatCommand(message, options) {
9869
10145
  normalizedRequests = normalizedRequests.map((req) => {
9870
10146
  const result = normalizeRequest(req, dsm.getConfig());
9871
10147
  if ("error" in result) {
9872
- console.log(chalk13.yellow(` \u26A0 Skipped: ${result.error}`));
10148
+ console.log(chalk14.yellow(` \u26A0 Skipped: ${result.error}`));
9873
10149
  return null;
9874
10150
  }
9875
10151
  if (result.type !== req.type) {
9876
- console.log(chalk13.dim(` \u2139 Adjusted: ${req.type} \u2192 ${result.type} (target: ${req.target})`));
10152
+ console.log(chalk14.dim(` \u2139 Adjusted: ${req.type} \u2192 ${result.type} (target: ${req.target})`));
9877
10153
  }
9878
10154
  return result;
9879
10155
  }).filter((r) => r !== null);
@@ -9929,13 +10205,13 @@ async function chatCommand(message, options) {
9929
10205
  }
9930
10206
  }
9931
10207
  if (DEBUG4) {
9932
- console.log(chalk13.gray(`
10208
+ console.log(chalk14.gray(`
9933
10209
  [DEBUG] Pre-flight analysis for page "${page.name || page.route}": `));
9934
- console.log(chalk13.gray(` Page sections: ${page.sections?.length || 0}`));
10210
+ console.log(chalk14.gray(` Page sections: ${page.sections?.length || 0}`));
9935
10211
  if (page.sections?.[0]?.props?.fields) {
9936
- console.log(chalk13.gray(` First section has ${page.sections[0].props.fields.length} fields`));
10212
+ console.log(chalk14.gray(` First section has ${page.sections[0].props.fields.length} fields`));
9937
10213
  page.sections[0].props.fields.forEach((f, i) => {
9938
- console.log(chalk13.gray(` Field ${i}: component=${f.component}`));
10214
+ console.log(chalk14.gray(` Field ${i}: component=${f.component}`));
9939
10215
  });
9940
10216
  }
9941
10217
  }
@@ -9958,8 +10234,8 @@ async function chatCommand(message, options) {
9958
10234
  const INVALID_COMPONENT_IDS = /* @__PURE__ */ new Set(["ui", "shared", "lib", "utils", "hooks", "app", "components"]);
9959
10235
  for (const id of INVALID_COMPONENT_IDS) allNeededComponentIds.delete(id);
9960
10236
  if (DEBUG4) {
9961
- console.log(chalk13.gray("\n[DEBUG] Pre-flight analysis (consolidated):"));
9962
- console.log(chalk13.gray(` All needed components: ${Array.from(allNeededComponentIds).join(", ")}`));
10237
+ console.log(chalk14.gray("\n[DEBUG] Pre-flight analysis (consolidated):"));
10238
+ console.log(chalk14.gray(` All needed components: ${Array.from(allNeededComponentIds).join(", ")}`));
9963
10239
  console.log("");
9964
10240
  }
9965
10241
  const missingComponents = [];
@@ -9967,59 +10243,59 @@ async function chatCommand(message, options) {
9967
10243
  const isRegistered = !!cm.read(componentId);
9968
10244
  const filePath = join11(projectRoot, "components", "ui", `${componentId}.tsx`);
9969
10245
  const fileExists = existsSync16(filePath);
9970
- if (DEBUG4) console.log(chalk13.gray(` Checking ${componentId}: registered=${isRegistered} file=${fileExists}`));
10246
+ if (DEBUG4) console.log(chalk14.gray(` Checking ${componentId}: registered=${isRegistered} file=${fileExists}`));
9971
10247
  if (!isRegistered || !fileExists) {
9972
10248
  missingComponents.push(componentId);
9973
10249
  }
9974
10250
  }
9975
10251
  if (missingComponents.length > 0) {
9976
10252
  spinner.stop();
9977
- console.log(chalk13.cyan("\n\u{1F50D} Pre-flight check: Installing missing components...\n"));
10253
+ console.log(chalk14.cyan("\n\u{1F50D} Pre-flight check: Installing missing components...\n"));
9978
10254
  const provider2 = getComponentProvider();
9979
10255
  for (const componentId of missingComponents) {
9980
10256
  if (DEBUG4) {
9981
- console.log(chalk13.gray(` [DEBUG] Trying to install: ${componentId}`));
9982
- console.log(chalk13.gray(` [DEBUG] provider.has(${componentId}): ${provider2.has(componentId)}`));
10257
+ console.log(chalk14.gray(` [DEBUG] Trying to install: ${componentId}`));
10258
+ console.log(chalk14.gray(` [DEBUG] provider.has(${componentId}): ${provider2.has(componentId)}`));
9983
10259
  }
9984
10260
  if (provider2.has(componentId)) {
9985
10261
  try {
9986
10262
  const result = await provider2.installComponent(componentId, projectRoot);
9987
- if (DEBUG4) console.log(chalk13.gray(` [DEBUG] installComponent result: ${result.success}`));
10263
+ if (DEBUG4) console.log(chalk14.gray(` [DEBUG] installComponent result: ${result.success}`));
9988
10264
  if (result.success && result.componentDef) {
9989
10265
  if (!cm.read(componentId)) {
9990
10266
  if (DEBUG4)
9991
10267
  console.log(
9992
- chalk13.gray(` [DEBUG] Registering ${result.componentDef.id} (${result.componentDef.name})`)
10268
+ chalk14.gray(` [DEBUG] Registering ${result.componentDef.id} (${result.componentDef.name})`)
9993
10269
  );
9994
10270
  const regResult = await cm.register(result.componentDef);
9995
10271
  if (DEBUG4) {
9996
10272
  console.log(
9997
- chalk13.gray(
10273
+ chalk14.gray(
9998
10274
  ` [DEBUG] Register result: ${regResult.success ? "SUCCESS" : "FAILED"}${!regResult.success && regResult.message ? ` - ${regResult.message}` : ""}`
9999
10275
  )
10000
10276
  );
10001
10277
  }
10002
10278
  if (regResult.success) {
10003
10279
  preflightInstalledIds.push(result.componentDef.id);
10004
- console.log(chalk13.green(` \u2728 Auto-installed ${result.componentDef.name} component`));
10280
+ console.log(chalk14.green(` \u2728 Auto-installed ${result.componentDef.name} component`));
10005
10281
  dsm.updateConfig(regResult.config);
10006
10282
  cm.updateConfig(regResult.config);
10007
10283
  pm.updateConfig(regResult.config);
10008
10284
  }
10009
10285
  } else {
10010
10286
  preflightInstalledIds.push(result.componentDef.id);
10011
- console.log(chalk13.green(` \u2728 Re-installed ${result.componentDef.name} component (file was missing)`));
10287
+ console.log(chalk14.green(` \u2728 Re-installed ${result.componentDef.name} component (file was missing)`));
10012
10288
  }
10013
10289
  }
10014
10290
  } catch (error) {
10015
- console.log(chalk13.red(` \u274C Failed to install ${componentId}:`));
10016
- console.log(chalk13.red(` ${error instanceof Error ? error.message : error}`));
10291
+ console.log(chalk14.red(` \u274C Failed to install ${componentId}:`));
10292
+ console.log(chalk14.red(` ${error instanceof Error ? error.message : error}`));
10017
10293
  if (error instanceof Error && error.stack) {
10018
- console.log(chalk13.gray(` ${error.stack.split("\n")[1]}`));
10294
+ console.log(chalk14.gray(` ${error.stack.split("\n")[1]}`));
10019
10295
  }
10020
10296
  }
10021
10297
  } else {
10022
- console.log(chalk13.yellow(` \u26A0\uFE0F Component ${componentId} not available`));
10298
+ console.log(chalk14.yellow(` \u26A0\uFE0F Component ${componentId} not available`));
10023
10299
  }
10024
10300
  }
10025
10301
  console.log("");
@@ -10030,11 +10306,11 @@ async function chatCommand(message, options) {
10030
10306
  const toInstallNpm = [...neededPkgs].filter((p) => !installedPkgs.has(p));
10031
10307
  if (toInstallNpm.length > 0) {
10032
10308
  spinner.stop();
10033
- console.log(chalk13.cyan(`
10309
+ console.log(chalk14.cyan(`
10034
10310
  \u{1F4E6} Auto-installing missing dependencies: ${toInstallNpm.join(", ")}
10035
10311
  `));
10036
10312
  const ok = await installPackages(projectRoot, toInstallNpm);
10037
- if (!ok) console.log(chalk13.yellow(` Run manually: npm install ${toInstallNpm.join(" ")}
10313
+ if (!ok) console.log(chalk14.yellow(` Run manually: npm install ${toInstallNpm.join(" ")}
10038
10314
  `));
10039
10315
  spinner.start("Applying modifications...");
10040
10316
  }
@@ -10045,7 +10321,7 @@ async function chatCommand(message, options) {
10045
10321
  if (componentId && preflightComponentIds.has(componentId)) {
10046
10322
  if (DEBUG4) {
10047
10323
  console.log(
10048
- chalk13.gray(`[DEBUG] Filtered duplicate add-component: ${componentId} (already installed in pre-flight)`)
10324
+ chalk14.gray(`[DEBUG] Filtered duplicate add-component: ${componentId} (already installed in pre-flight)`)
10049
10325
  );
10050
10326
  }
10051
10327
  return false;
@@ -10054,11 +10330,11 @@ async function chatCommand(message, options) {
10054
10330
  return true;
10055
10331
  });
10056
10332
  if (DEBUG4 && preflightComponentIds.size > 0) {
10057
- console.log(chalk13.gray(`[DEBUG] Remaining requests after filtering: ${normalizedRequests.length}`));
10333
+ console.log(chalk14.gray(`[DEBUG] Remaining requests after filtering: ${normalizedRequests.length}`));
10058
10334
  }
10059
10335
  try {
10060
10336
  createBackup(projectRoot);
10061
- if (DEBUG4) console.log(chalk13.dim("[backup] Created snapshot"));
10337
+ if (DEBUG4) console.log(chalk14.dim("[backup] Created snapshot"));
10062
10338
  } catch {
10063
10339
  }
10064
10340
  const navBefore = takeNavSnapshot(
@@ -10113,10 +10389,10 @@ async function chatCommand(message, options) {
10113
10389
  const SCAFFOLD_AI_LIMIT = 10;
10114
10390
  if (missingRoutes.length > 0 && missingRoutes.length <= SCAFFOLD_AI_LIMIT) {
10115
10391
  spinner.stop();
10116
- console.log(chalk13.cyan(`
10392
+ console.log(chalk14.cyan(`
10117
10393
  \u{1F517} Auto-scaffolding ${missingRoutes.length} linked page(s)...`));
10118
10394
  console.log(
10119
- chalk13.dim(
10395
+ chalk14.dim(
10120
10396
  ` (${missingRoutes.length} additional AI call(s) \u2014 disable with settings.autoScaffold: false in config)
10121
10397
  `
10122
10398
  )
@@ -10153,7 +10429,7 @@ async function chatCommand(message, options) {
10153
10429
  }
10154
10430
  } catch (err) {
10155
10431
  scaffoldSpinner.warn(` Could not scaffold "${pageName}" (${linkedRoute}) \u2014 skipped`);
10156
- if (DEBUG4) console.log(chalk13.dim(` ${err instanceof Error ? err.message : "unknown error"}`));
10432
+ if (DEBUG4) console.log(chalk14.dim(` ${err instanceof Error ? err.message : "unknown error"}`));
10157
10433
  }
10158
10434
  }
10159
10435
  console.log("");
@@ -10161,7 +10437,7 @@ async function chatCommand(message, options) {
10161
10437
  } else if (missingRoutes.length > SCAFFOLD_AI_LIMIT) {
10162
10438
  spinner.stop();
10163
10439
  console.log(
10164
- chalk13.yellow(
10440
+ chalk14.yellow(
10165
10441
  `
10166
10442
  \u26A0 Found ${missingRoutes.length} linked pages \u2014 creating placeholder pages (too many for AI generation).`
10167
10443
  )
@@ -10190,7 +10466,7 @@ async function chatCommand(message, options) {
10190
10466
  scaffoldedPages.push({ route: linkedRoute, name: `${pageName} (placeholder)` });
10191
10467
  }
10192
10468
  console.log(
10193
- chalk13.cyan(` Created ${missingRoutes.length} placeholder pages. Use \`coherent chat\` to fill them.
10469
+ chalk14.cyan(` Created ${missingRoutes.length} placeholder pages. Use \`coherent chat\` to fill them.
10194
10470
  `)
10195
10471
  );
10196
10472
  spinner.start("Finalizing...");
@@ -10218,9 +10494,9 @@ async function chatCommand(message, options) {
10218
10494
  }
10219
10495
  }
10220
10496
  if (linkIssues.length > 0) {
10221
- console.log(chalk13.yellow("\n\u{1F517} Broken internal links:"));
10497
+ console.log(chalk14.yellow("\n\u{1F517} Broken internal links:"));
10222
10498
  for (const { page, message: message2 } of linkIssues) {
10223
- console.log(chalk13.dim(` ${page}: ${message2}`));
10499
+ console.log(chalk14.dim(` ${page}: ${message2}`));
10224
10500
  }
10225
10501
  }
10226
10502
  }
@@ -10233,7 +10509,7 @@ async function chatCommand(message, options) {
10233
10509
  if (latestConfig.theme.defaultMode !== targetMode) {
10234
10510
  latestConfig.theme.defaultMode = targetMode;
10235
10511
  dsm.updateConfig(latestConfig);
10236
- if (DEBUG4) console.log(chalk13.dim(` [theme] Set defaultMode to "${targetMode}"`));
10512
+ if (DEBUG4) console.log(chalk14.dim(` [theme] Set defaultMode to "${targetMode}"`));
10237
10513
  }
10238
10514
  const layoutPath = resolve9(projectRoot, "app", "layout.tsx");
10239
10515
  try {
@@ -10241,11 +10517,11 @@ async function chatCommand(message, options) {
10241
10517
  if (targetMode === "dark" && !layoutCode.includes('className="dark"')) {
10242
10518
  layoutCode = layoutCode.replace(/<html\s+lang="en"/, '<html lang="en" className="dark"');
10243
10519
  await writeFile(layoutPath, layoutCode);
10244
- console.log(chalk13.dim(` \u{1F319} Applied dark theme to layout`));
10520
+ console.log(chalk14.dim(` \u{1F319} Applied dark theme to layout`));
10245
10521
  } else if (targetMode === "light" && layoutCode.includes('className="dark"')) {
10246
10522
  layoutCode = layoutCode.replace(' className="dark"', "");
10247
10523
  await writeFile(layoutPath, layoutCode);
10248
- console.log(chalk13.dim(` \u2600\uFE0F Applied light theme to layout`));
10524
+ console.log(chalk14.dim(` \u2600\uFE0F Applied light theme to layout`));
10249
10525
  }
10250
10526
  } catch {
10251
10527
  }
@@ -10277,7 +10553,7 @@ async function chatCommand(message, options) {
10277
10553
  }
10278
10554
  const finalDeps = await scanAndInstallSharedDeps(projectRoot);
10279
10555
  if (finalDeps.length > 0) {
10280
- console.log(chalk13.dim(` Auto-installed shared deps: ${finalDeps.join(", ")}`));
10556
+ console.log(chalk14.dim(` Auto-installed shared deps: ${finalDeps.join(", ")}`));
10281
10557
  }
10282
10558
  try {
10283
10559
  fixGlobalsCss(projectRoot, updatedConfig);
@@ -10301,7 +10577,7 @@ async function chatCommand(message, options) {
10301
10577
  }
10302
10578
  await saveHashes(projectRoot, updatedHashes);
10303
10579
  } catch {
10304
- if (DEBUG4) console.log(chalk13.dim("[hashes] Could not save file hashes"));
10580
+ if (DEBUG4) console.log(chalk14.dim("[hashes] Could not save file hashes"));
10305
10581
  }
10306
10582
  const successfulPairs = normalizedRequests.map((request, index) => ({ request, result: results[index] })).filter(({ result }) => result.success);
10307
10583
  if (successfulPairs.length > 0) {
@@ -10318,9 +10594,9 @@ async function chatCommand(message, options) {
10318
10594
  const preflightNames = preflightInstalledIds.map((id) => updatedConfig.components.find((c) => c.id === id)?.name).filter(Boolean);
10319
10595
  showPreview(normalizedRequests, results, updatedConfig, preflightNames);
10320
10596
  if (scaffoldedPages.length > 0) {
10321
- console.log(chalk13.cyan("\u{1F517} Auto-scaffolded linked pages:"));
10597
+ console.log(chalk14.cyan("\u{1F517} Auto-scaffolded linked pages:"));
10322
10598
  scaffoldedPages.forEach(({ route, name }) => {
10323
- console.log(chalk13.white(` \u2728 ${name} \u2192 ${route}`));
10599
+ console.log(chalk14.white(` \u2728 ${name} \u2192 ${route}`));
10324
10600
  });
10325
10601
  console.log("");
10326
10602
  }
@@ -10342,58 +10618,58 @@ ${uxRecommendations}
10342
10618
  );
10343
10619
  }
10344
10620
  await appendFile(recPath, section);
10345
- console.log(chalk13.cyan("\n\u{1F4CB} UX Recommendations:"));
10621
+ console.log(chalk14.cyan("\n\u{1F4CB} UX Recommendations:"));
10346
10622
  for (const line of uxRecommendations.split("\n").filter(Boolean)) {
10347
- console.log(chalk13.dim(` ${line}`));
10623
+ console.log(chalk14.dim(` ${line}`));
10348
10624
  }
10349
- console.log(chalk13.dim(" \u2192 Saved to /design-system/docs/recommendations"));
10625
+ console.log(chalk14.dim(" \u2192 Saved to /design-system/docs/recommendations"));
10350
10626
  } catch (e) {
10351
10627
  console.log(
10352
- chalk13.yellow("\n\u26A0\uFE0F Could not write recommendations.md: " + (e instanceof Error ? e.message : String(e)))
10628
+ chalk14.yellow("\n\u26A0\uFE0F Could not write recommendations.md: " + (e instanceof Error ? e.message : String(e)))
10353
10629
  );
10354
- console.log(chalk13.dim("Recommendations:\n") + uxRecommendations);
10630
+ console.log(chalk14.dim("Recommendations:\n") + uxRecommendations);
10355
10631
  }
10356
10632
  }
10357
10633
  } catch (error) {
10358
10634
  spinner.fail("Chat command failed");
10359
- console.error(chalk13.red("\n\u2716 Chat command failed"));
10635
+ console.error(chalk14.red("\n\u2716 Chat command failed"));
10360
10636
  const zodError = error;
10361
10637
  const issues = zodError.issues || error.errors;
10362
10638
  if (issues && Array.isArray(issues)) {
10363
- console.log(chalk13.yellow("\n\u26A0\uFE0F AI generated incomplete data. Missing or invalid fields:"));
10639
+ console.log(chalk14.yellow("\n\u26A0\uFE0F AI generated incomplete data. Missing or invalid fields:"));
10364
10640
  issues.forEach((err) => {
10365
- console.log(chalk13.gray(` \u2022 ${err.path.join(".")}: ${err.message}`));
10641
+ console.log(chalk14.gray(` \u2022 ${err.path.join(".")}: ${err.message}`));
10366
10642
  });
10367
- console.log(chalk13.cyan("\n\u{1F4A1} Try being more specific, e.g.:"));
10368
- console.log(chalk13.white(' coherent chat "add a dashboard page with hero section using Button component"'));
10369
- console.log(chalk13.white(' coherent chat "add pricing page"'));
10643
+ console.log(chalk14.cyan("\n\u{1F4A1} Try being more specific, e.g.:"));
10644
+ console.log(chalk14.white(' coherent chat "add a dashboard page with hero section using Button component"'));
10645
+ console.log(chalk14.white(' coherent chat "add pricing page"'));
10370
10646
  } else if (error instanceof Error) {
10371
- console.error(chalk13.red(error.message));
10647
+ console.error(chalk14.red(error.message));
10372
10648
  if (error.message.includes("Unterminated string") || error.message.includes("Unexpected end of JSON") || error.message.includes("Failed to parse modification") && error.message.includes("JSON")) {
10373
10649
  console.log(
10374
- chalk13.yellow("\n\u{1F4A1} The AI response was too large or contained invalid JSON. Try splitting your request:")
10650
+ chalk14.yellow("\n\u{1F4A1} The AI response was too large or contained invalid JSON. Try splitting your request:")
10375
10651
  );
10376
- console.log(chalk13.white(' coherent chat "add dashboard page with stats and recent activity"'));
10377
- console.log(chalk13.white(' coherent chat "add account page"'));
10378
- console.log(chalk13.white(' coherent chat "add settings page"'));
10652
+ console.log(chalk14.white(' coherent chat "add dashboard page with stats and recent activity"'));
10653
+ console.log(chalk14.white(' coherent chat "add account page"'));
10654
+ console.log(chalk14.white(' coherent chat "add settings page"'));
10379
10655
  } else if (error.message.includes("API key not found") || error.message.includes("ANTHROPIC_API_KEY") || error.message.includes("OPENAI_API_KEY")) {
10380
10656
  const isOpenAI = error.message.includes("OpenAI") || typeof provider !== "undefined" && provider === "openai";
10381
10657
  const providerName = isOpenAI ? "OpenAI" : "Anthropic Claude";
10382
10658
  const envVar = isOpenAI ? "OPENAI_API_KEY" : "ANTHROPIC_API_KEY";
10383
10659
  const url = isOpenAI ? "https://platform.openai.com" : "https://console.anthropic.com";
10384
- console.log(chalk13.yellow("\n\u{1F4A1} Setup Instructions:"));
10385
- console.log(chalk13.dim(` 1. Get your ${providerName} API key from: ${url}`));
10386
- console.log(chalk13.dim(" 2. Create a .env file in the current directory:"));
10387
- console.log(chalk13.cyan(` echo "${envVar}=your_key_here" > .env`));
10388
- console.log(chalk13.dim(" 3. Or export it in your shell:"));
10389
- console.log(chalk13.cyan(` export ${envVar}=your_key_here`));
10660
+ console.log(chalk14.yellow("\n\u{1F4A1} Setup Instructions:"));
10661
+ console.log(chalk14.dim(` 1. Get your ${providerName} API key from: ${url}`));
10662
+ console.log(chalk14.dim(" 2. Create a .env file in the current directory:"));
10663
+ console.log(chalk14.cyan(` echo "${envVar}=your_key_here" > .env`));
10664
+ console.log(chalk14.dim(" 3. Or export it in your shell:"));
10665
+ console.log(chalk14.cyan(` export ${envVar}=your_key_here`));
10390
10666
  if (isOpenAI) {
10391
- console.log(chalk13.dim('\n Also ensure "openai" package is installed:'));
10392
- console.log(chalk13.cyan(" npm install openai"));
10667
+ console.log(chalk14.dim('\n Also ensure "openai" package is installed:'));
10668
+ console.log(chalk14.cyan(" npm install openai"));
10393
10669
  }
10394
10670
  }
10395
10671
  } else {
10396
- console.error(chalk13.red("Unknown error occurred"));
10672
+ console.error(chalk14.red("Unknown error occurred"));
10397
10673
  }
10398
10674
  console.log("");
10399
10675
  if (options._throwOnError) {
@@ -10406,7 +10682,7 @@ ${uxRecommendations}
10406
10682
  }
10407
10683
 
10408
10684
  // src/commands/preview.ts
10409
- import chalk14 from "chalk";
10685
+ import chalk15 from "chalk";
10410
10686
  import ora3 from "ora";
10411
10687
  import { spawn } from "child_process";
10412
10688
  import { existsSync as existsSync19, rmSync as rmSync3, readFileSync as readFileSync14, writeFileSync as writeFileSync10, readdirSync as readdirSync5 } from "fs";
@@ -10746,13 +11022,13 @@ async function handleFileChange(projectRoot, filePath) {
10746
11022
  return;
10747
11023
  }
10748
11024
  const config2 = getWatcherConfig(projectRoot);
10749
- const chalk33 = (await import("chalk")).default;
11025
+ const chalk34 = (await import("chalk")).default;
10750
11026
  if (config2.autoInstall) {
10751
11027
  const missing = findMissingPackagesInCode(content, projectRoot);
10752
11028
  if (missing.length > 0) {
10753
11029
  const ok = await installPackages(projectRoot, missing);
10754
11030
  if (ok) {
10755
- console.log(chalk33.cyan(`
11031
+ console.log(chalk34.cyan(`
10756
11032
  \u{1F527} Auto-installed: ${missing.join(", ")} (needed by ${relativePath})`));
10757
11033
  }
10758
11034
  }
@@ -10761,12 +11037,12 @@ async function handleFileChange(projectRoot, filePath) {
10761
11037
  const fixed = sanitizeMetadataStrings(ensureUseClientIfNeeded(content));
10762
11038
  if (fixed !== content) {
10763
11039
  writeFileSync9(filePath, fixed, "utf-8");
10764
- console.log(chalk33.cyan(` \u{1F527} Auto-fixed syntax in ${relativePath}`));
11040
+ console.log(chalk34.cyan(` \u{1F527} Auto-fixed syntax in ${relativePath}`));
10765
11041
  }
10766
11042
  }
10767
11043
  if (config2.warnNativeElements && hasNativeElements(content)) {
10768
- console.log(chalk33.yellow(` \u26A0 ${relativePath}: uses native HTML elements (<button>, <select>, etc.)`));
10769
- console.log(chalk33.dim(" Use components from @/components/ui/ instead"));
11044
+ console.log(chalk34.yellow(` \u26A0 ${relativePath}: uses native HTML elements (<button>, <select>, etc.)`));
11045
+ console.log(chalk34.dim(" Use components from @/components/ui/ instead"));
10770
11046
  }
10771
11047
  if (config2.warnSharedReuse) {
10772
11048
  let manifest;
@@ -10779,8 +11055,8 @@ async function handleFileChange(projectRoot, filePath) {
10779
11055
  const dupes = findInlineDuplicatesOfShared(content, manifest);
10780
11056
  for (const d of dupes) {
10781
11057
  const importPath = d.file.replace(/\.tsx$/, "").replace(/^components\/shared\//, "");
10782
- console.log(chalk33.yellow(` \u26A0 ${relativePath}: has inline code similar to ${d.cid} (${d.name})`));
10783
- console.log(chalk33.dim(` Consider: import { ${d.name} } from "@/components/shared/${importPath}"`));
11058
+ console.log(chalk34.yellow(` \u26A0 ${relativePath}: has inline code similar to ${d.cid} (${d.name})`));
11059
+ console.log(chalk34.dim(` Consider: import { ${d.name} } from "@/components/shared/${importPath}"`));
10784
11060
  }
10785
11061
  }
10786
11062
  }
@@ -10789,7 +11065,7 @@ async function handleFileDelete(projectRoot, filePath) {
10789
11065
  const relativePath = relative4(projectRoot, filePath).replace(/\\/g, "/");
10790
11066
  if (!relativePath.startsWith("components/") || relativePath.startsWith("components/ui/")) return;
10791
11067
  try {
10792
- const chalk33 = (await import("chalk")).default;
11068
+ const chalk34 = (await import("chalk")).default;
10793
11069
  const manifest = await loadManifest9(projectRoot);
10794
11070
  const orphaned = manifest.shared.find((s) => s.file === relativePath);
10795
11071
  if (orphaned) {
@@ -10798,7 +11074,7 @@ async function handleFileDelete(projectRoot, filePath) {
10798
11074
  shared: manifest.shared.filter((s) => s.id !== orphaned.id)
10799
11075
  };
10800
11076
  await saveManifest3(projectRoot, cleaned);
10801
- console.log(chalk33.cyan(`
11077
+ console.log(chalk34.cyan(`
10802
11078
  \u{1F5D1} Auto-removed ${orphaned.id} (${orphaned.name}) \u2014 file deleted`));
10803
11079
  await writeCursorRules(projectRoot);
10804
11080
  }
@@ -10810,7 +11086,7 @@ async function detectNewComponent(projectRoot, filePath) {
10810
11086
  if (!relativePath.startsWith("components/") || relativePath.startsWith("components/ui/")) return;
10811
11087
  if (!relativePath.endsWith(".tsx") && !relativePath.endsWith(".jsx")) return;
10812
11088
  try {
10813
- const chalk33 = (await import("chalk")).default;
11089
+ const chalk34 = (await import("chalk")).default;
10814
11090
  const manifest = await loadManifest9(projectRoot);
10815
11091
  const alreadyRegistered = manifest.shared.some((s) => s.file === relativePath);
10816
11092
  if (alreadyRegistered) return;
@@ -10819,9 +11095,9 @@ async function detectNewComponent(projectRoot, filePath) {
10819
11095
  if (exports.length > 0) {
10820
11096
  const alreadyByName = exports.every((n) => manifest.shared.some((s) => s.name === n));
10821
11097
  if (!alreadyByName) {
10822
- console.log(chalk33.cyan(`
11098
+ console.log(chalk34.cyan(`
10823
11099
  \u2139 New component detected: ${exports[0]} in ${relativePath}`));
10824
- console.log(chalk33.dim(" Register with: coherent sync"));
11100
+ console.log(chalk34.dim(" Register with: coherent sync"));
10825
11101
  }
10826
11102
  }
10827
11103
  } catch {
@@ -10908,17 +11184,17 @@ function clearStaleCache(projectRoot) {
10908
11184
  const nextDir = join14(projectRoot, ".next");
10909
11185
  if (existsSync19(nextDir)) {
10910
11186
  rmSync3(nextDir, { recursive: true, force: true });
10911
- console.log(chalk14.dim(" \u2714 Cleared stale build cache"));
11187
+ console.log(chalk15.dim(" \u2714 Cleared stale build cache"));
10912
11188
  }
10913
11189
  }
10914
11190
  async function preflightDependencyCheck(projectRoot) {
10915
11191
  const missing = await findMissingPackages(projectRoot);
10916
11192
  if (missing.length === 0) return;
10917
- console.log(chalk14.cyan(`
11193
+ console.log(chalk15.cyan(`
10918
11194
  Auto-installing missing dependencies: ${missing.join(", ")}`));
10919
11195
  const ok = await installPackages(projectRoot, missing);
10920
- if (ok) console.log(chalk14.dim(" \u2714 Installed"));
10921
- else console.log(chalk14.yellow(` Run manually: npm install ${missing.join(" ")}`));
11196
+ if (ok) console.log(chalk15.dim(" \u2714 Installed"));
11197
+ else console.log(chalk15.yellow(` Run manually: npm install ${missing.join(" ")}`));
10922
11198
  }
10923
11199
  async function listPageFiles(appDir) {
10924
11200
  const out = [];
@@ -10942,7 +11218,7 @@ async function validateSyntax(projectRoot) {
10942
11218
  const fixed = fixUnescapedLtInJsx(sanitizeMetadataStrings(ensureUseClientIfNeeded(content)));
10943
11219
  if (fixed !== content) {
10944
11220
  writeFileSync10(file, fixed, "utf-8");
10945
- console.log(chalk14.dim(` \u2714 Auto-fixed syntax: ${file.replace(projectRoot, ".").replace(/^\.[/\\]/, "")}`));
11221
+ console.log(chalk15.dim(` \u2714 Auto-fixed syntax: ${file.replace(projectRoot, ".").replace(/^\.[/\\]/, "")}`));
10946
11222
  }
10947
11223
  }
10948
11224
  }
@@ -10984,7 +11260,7 @@ async function fixMissingComponentExports(projectRoot) {
10984
11260
  try {
10985
11261
  const result = await provider.installComponent(componentId, projectRoot);
10986
11262
  if (result.success) {
10987
- console.log(chalk14.dim(` \u2714 Installed missing ${componentId}.tsx`));
11263
+ console.log(chalk15.dim(` \u2714 Installed missing ${componentId}.tsx`));
10988
11264
  }
10989
11265
  } catch {
10990
11266
  }
@@ -10996,7 +11272,7 @@ async function fixMissingComponentExports(projectRoot) {
10996
11272
  mkdirSync10(uiDir, { recursive: true });
10997
11273
  const newContent = await generator.generate(def);
10998
11274
  writeFileSync10(componentFile, newContent, "utf-8");
10999
- console.log(chalk14.dim(` \u2714 Created missing ${componentId}.tsx`));
11275
+ console.log(chalk15.dim(` \u2714 Created missing ${componentId}.tsx`));
11000
11276
  } catch {
11001
11277
  }
11002
11278
  }
@@ -11019,7 +11295,7 @@ async function fixMissingComponentExports(projectRoot) {
11019
11295
  try {
11020
11296
  const result = await provider.installComponent(componentId, projectRoot, { force: true });
11021
11297
  if (result.success) {
11022
- console.log(chalk14.dim(` \u2714 Reinstalled ${componentId}.tsx (added missing exports: ${missing.join(", ")})`));
11298
+ console.log(chalk15.dim(` \u2714 Reinstalled ${componentId}.tsx (added missing exports: ${missing.join(", ")})`));
11023
11299
  }
11024
11300
  } catch {
11025
11301
  }
@@ -11029,7 +11305,7 @@ async function fixMissingComponentExports(projectRoot) {
11029
11305
  try {
11030
11306
  const newContent = await generator.generate(def);
11031
11307
  writeFileSync10(componentFile, newContent, "utf-8");
11032
- console.log(chalk14.dim(` \u2714 Regenerated ${componentId}.tsx (added missing exports: ${missing.join(", ")})`));
11308
+ console.log(chalk15.dim(` \u2714 Regenerated ${componentId}.tsx (added missing exports: ${missing.join(", ")})`));
11033
11309
  } catch {
11034
11310
  }
11035
11311
  }
@@ -11088,14 +11364,14 @@ async function healthCheck(port) {
11088
11364
  try {
11089
11365
  const res = await fetch(`http://localhost:${port}`);
11090
11366
  if (res.status === 200) {
11091
- console.log(chalk14.green(`
11367
+ console.log(chalk15.green(`
11092
11368
  \u2705 Preview healthy at http://localhost:${port}`));
11093
11369
  } else {
11094
- console.log(chalk14.yellow(`
11370
+ console.log(chalk15.yellow(`
11095
11371
  \u26A0 Preview returned ${res.status}. Run: coherent fix`));
11096
11372
  }
11097
11373
  } catch {
11098
- console.log(chalk14.yellow(`
11374
+ console.log(chalk15.yellow(`
11099
11375
  \u26A0 Preview not responding. Run: coherent fix`));
11100
11376
  }
11101
11377
  }
@@ -11134,29 +11410,29 @@ function launchWithMonitoring(projectRoot, restarts) {
11134
11410
  const shadcnId = extractShadcnComponentFromModuleNotFound(msg);
11135
11411
  if (shadcnId && !installingSet.has(shadcnId)) {
11136
11412
  installingSet.add(shadcnId);
11137
- console.log(chalk14.yellow(`
11413
+ console.log(chalk15.yellow(`
11138
11414
  \u26A0 Missing component detected: ${shadcnId}`));
11139
- console.log(chalk14.cyan(" Auto-installing..."));
11415
+ console.log(chalk15.cyan(" Auto-installing..."));
11140
11416
  autoInstallShadcnComponent(shadcnId, projectRoot).then((ok) => {
11141
11417
  if (ok) {
11142
- console.log(chalk14.green(` \u2714 Installed ${shadcnId}.tsx. Restarting...`));
11418
+ console.log(chalk15.green(` \u2714 Installed ${shadcnId}.tsx. Restarting...`));
11143
11419
  intentionalRestart = true;
11144
11420
  server.kill("SIGTERM");
11145
11421
  launchWithMonitoring(projectRoot, restarts + 1).then(resolvePromise).catch(rejectPromise);
11146
11422
  } else {
11147
- console.log(chalk14.red(` \u2716 Could not install ${shadcnId}. Run: npx shadcn@latest add ${shadcnId}`));
11423
+ console.log(chalk15.red(` \u2716 Could not install ${shadcnId}. Run: npx shadcn@latest add ${shadcnId}`));
11148
11424
  }
11149
11425
  });
11150
11426
  } else if (!shadcnId) {
11151
11427
  const pkg = extractPackageFromModuleNotFound(msg);
11152
11428
  if (pkg && !installingSet.has(pkg)) {
11153
11429
  installingSet.add(pkg);
11154
- console.log(chalk14.yellow(`
11430
+ console.log(chalk15.yellow(`
11155
11431
  \u26A0 Missing package detected: ${pkg}`));
11156
- console.log(chalk14.cyan(" Auto-installing..."));
11432
+ console.log(chalk15.cyan(" Auto-installing..."));
11157
11433
  installPackages(projectRoot, [pkg]).then((ok) => {
11158
11434
  if (ok) {
11159
- console.log(chalk14.green(` \u2714 Installed ${pkg}. Restarting...`));
11435
+ console.log(chalk15.green(` \u2714 Installed ${pkg}. Restarting...`));
11160
11436
  intentionalRestart = true;
11161
11437
  server.kill("SIGTERM");
11162
11438
  launchWithMonitoring(projectRoot, restarts + 1).then(resolvePromise).catch(rejectPromise);
@@ -11166,19 +11442,19 @@ function launchWithMonitoring(projectRoot, restarts) {
11166
11442
  }
11167
11443
  }
11168
11444
  if (msg.includes("Failed to compile")) {
11169
- console.log(chalk14.yellow("\n\u26A0 Compilation error detected."));
11170
- console.log(chalk14.dim(' Hint: run "coherent fix" in another terminal to auto-fix'));
11171
- console.log(chalk14.dim(' Or: coherent chat "fix the broken page"'));
11445
+ console.log(chalk15.yellow("\n\u26A0 Compilation error detected."));
11446
+ console.log(chalk15.dim(' Hint: run "coherent fix" in another terminal to auto-fix'));
11447
+ console.log(chalk15.dim(' Or: coherent chat "fix the broken page"'));
11172
11448
  }
11173
11449
  });
11174
11450
  server.on("exit", (code) => {
11175
11451
  if (intentionalRestart) return;
11176
11452
  if (code !== 0 && code !== null) {
11177
- console.log(chalk14.red(`
11453
+ console.log(chalk15.red(`
11178
11454
  \u274C Dev server exited with code ${code}`));
11179
- console.log(chalk14.dim(' Check the output above. Fix and run "coherent preview" again.\n'));
11455
+ console.log(chalk15.dim(' Check the output above. Fix and run "coherent preview" again.\n'));
11180
11456
  } else {
11181
- console.log(chalk14.dim("\n\u{1F44B} Dev server stopped"));
11457
+ console.log(chalk15.dim("\n\u{1F44B} Dev server stopped"));
11182
11458
  }
11183
11459
  process.exit(code ?? 0);
11184
11460
  });
@@ -11187,7 +11463,7 @@ function launchWithMonitoring(projectRoot, restarts) {
11187
11463
  });
11188
11464
  const shutdown = () => {
11189
11465
  closeWatcher();
11190
- console.log(chalk14.dim("\n\n\u{1F6D1} Stopping dev server..."));
11466
+ console.log(chalk15.dim("\n\n\u{1F6D1} Stopping dev server..."));
11191
11467
  server.kill("SIGTERM");
11192
11468
  };
11193
11469
  process.on("SIGINT", shutdown);
@@ -11199,9 +11475,9 @@ async function openBrowser(url) {
11199
11475
  const open = await import("open");
11200
11476
  await open.default(url);
11201
11477
  } catch (error) {
11202
- console.log(chalk14.yellow(`
11478
+ console.log(chalk15.yellow(`
11203
11479
  \u26A0\uFE0F Could not open browser automatically`));
11204
- console.log(chalk14.dim(` Please open ${url} manually`));
11480
+ console.log(chalk15.dim(` Please open ${url} manually`));
11205
11481
  }
11206
11482
  }
11207
11483
  function startDevServer(projectRoot) {
@@ -11232,8 +11508,8 @@ async function previewCommand() {
11232
11508
  try {
11233
11509
  if (!checkProjectInitialized(projectRoot)) {
11234
11510
  spinner.fail("Project not initialized");
11235
- console.log(chalk14.red("\n\u274C Project not found"));
11236
- console.log(chalk14.dim('Run "coherent init" first to create a project.'));
11511
+ console.log(chalk15.red("\n\u274C Project not found"));
11512
+ console.log(chalk15.dim('Run "coherent init" first to create a project.'));
11237
11513
  process.exit(1);
11238
11514
  }
11239
11515
  spinner.text = "Checking dependencies...";
@@ -11241,16 +11517,16 @@ async function previewCommand() {
11241
11517
  spinner.warn("Dependencies not installed");
11242
11518
  const pm = getPackageManager(projectRoot);
11243
11519
  const installCommand = pm === "pnpm" ? "pnpm install" : "npm install";
11244
- console.log(chalk14.yellow("\n\u26A0\uFE0F Dependencies not installed"));
11245
- console.log(chalk14.cyan(`
11520
+ console.log(chalk15.yellow("\n\u26A0\uFE0F Dependencies not installed"));
11521
+ console.log(chalk15.cyan(`
11246
11522
  Running ${installCommand}...
11247
11523
  `));
11248
11524
  const ok = await runInstall(projectRoot);
11249
11525
  if (!ok) {
11250
- console.error(chalk14.red('\n\u274C Install failed. Fix errors above and run "coherent preview" again.\n'));
11526
+ console.error(chalk15.red('\n\u274C Install failed. Fix errors above and run "coherent preview" again.\n'));
11251
11527
  process.exit(1);
11252
11528
  }
11253
- console.log(chalk14.green("\n\u2705 Dependencies installed\n"));
11529
+ console.log(chalk15.green("\n\u2705 Dependencies installed\n"));
11254
11530
  } else {
11255
11531
  spinner.succeed("Project ready");
11256
11532
  }
@@ -11273,27 +11549,27 @@ async function previewCommand() {
11273
11549
  await fixMissingComponentExports(projectRoot);
11274
11550
  await backfillPageAnalysis(projectRoot);
11275
11551
  spinner.succeed("Project ready");
11276
- console.log(chalk14.dim(" \u{1F4A1} Edited files manually? Run `coherent sync` to update the Design System.\n"));
11277
- console.log(chalk14.blue("\n\u{1F680} Starting Next.js dev server...\n"));
11552
+ console.log(chalk15.dim(" \u{1F4A1} Edited files manually? Run `coherent sync` to update the Design System.\n"));
11553
+ console.log(chalk15.blue("\n\u{1F680} Starting Next.js dev server...\n"));
11278
11554
  await launchWithMonitoring(projectRoot, 0);
11279
11555
  } catch (error) {
11280
11556
  spinner.fail("Failed to start dev server");
11281
11557
  if (error instanceof Error) {
11282
- console.error(chalk14.red(`
11558
+ console.error(chalk15.red(`
11283
11559
  \u274C ${error.message}`));
11284
11560
  if (error.message.includes("package.json")) {
11285
- console.log(chalk14.yellow("\n\u{1F4A1} Tip: Make sure you're in a Coherent project directory."));
11286
- console.log(chalk14.dim(' Run "coherent init" to create a new project.'));
11561
+ console.log(chalk15.yellow("\n\u{1F4A1} Tip: Make sure you're in a Coherent project directory."));
11562
+ console.log(chalk15.dim(' Run "coherent init" to create a new project.'));
11287
11563
  }
11288
11564
  } else {
11289
- console.error(chalk14.red("Unknown error occurred"));
11565
+ console.error(chalk15.red("Unknown error occurred"));
11290
11566
  }
11291
11567
  process.exit(1);
11292
11568
  }
11293
11569
  }
11294
11570
 
11295
11571
  // src/commands/export.ts
11296
- import chalk15 from "chalk";
11572
+ import chalk16 from "chalk";
11297
11573
  import ora4 from "ora";
11298
11574
  import { spawn as spawn2 } from "child_process";
11299
11575
  import { existsSync as existsSync20, rmSync as rmSync4, readdirSync as readdirSync6 } from "fs";
@@ -11572,7 +11848,7 @@ async function exportCommand(options = {}) {
11572
11848
  const missingDeps = await findMissingDepsInExport(outputDir);
11573
11849
  if (missingDeps.length > 0) {
11574
11850
  console.log(
11575
- chalk15.yellow(
11851
+ chalk16.yellow(
11576
11852
  "\n\u26A0\uFE0F Warning: exported code imports packages not in package.json: " + missingDeps.join(", ") + "\n Add them to dependencies and run npm install in the export dir.\n"
11577
11853
  )
11578
11854
  );
@@ -11588,7 +11864,7 @@ async function exportCommand(options = {}) {
11588
11864
  spinner.succeed("Dependencies installed");
11589
11865
  await ensureReadmeDeploySection(outputDir);
11590
11866
  await patchNextConfigForExport(outputDir);
11591
- console.log(chalk15.dim("\n Tip: run `coherent check` before export to catch quality issues.\n"));
11867
+ console.log(chalk16.dim("\n Tip: run `coherent check` before export to catch quality issues.\n"));
11592
11868
  let buildOk = false;
11593
11869
  if (doBuild) {
11594
11870
  spinner.start("Running next build...");
@@ -11598,7 +11874,7 @@ async function exportCommand(options = {}) {
11598
11874
  spinner.succeed("Build: success");
11599
11875
  } catch (e) {
11600
11876
  spinner.fail("Build failed");
11601
- if (e instanceof Error) console.error(chalk15.red(e.message));
11877
+ if (e instanceof Error) console.error(chalk16.red(e.message));
11602
11878
  }
11603
11879
  } else {
11604
11880
  buildOk = true;
@@ -11606,23 +11882,23 @@ async function exportCommand(options = {}) {
11606
11882
  const pageCount = await countPages(outputDir);
11607
11883
  const componentCount = countComponents(outputDir);
11608
11884
  spinner.stop();
11609
- console.log(chalk15.green("\n\u2705 Exported to " + outputDir + "\n"));
11610
- console.log(chalk15.blue(" Pages: " + pageCount));
11611
- console.log(chalk15.blue(" Components: " + componentCount + " (base + shared)"));
11612
- console.log(chalk15.blue(" Build: " + (doBuild ? buildOk ? "success" : "failed" : "skipped (--no-build)")));
11885
+ console.log(chalk16.green("\n\u2705 Exported to " + outputDir + "\n"));
11886
+ console.log(chalk16.blue(" Pages: " + pageCount));
11887
+ console.log(chalk16.blue(" Components: " + componentCount + " (base + shared)"));
11888
+ console.log(chalk16.blue(" Build: " + (doBuild ? buildOk ? "success" : "failed" : "skipped (--no-build)")));
11613
11889
  console.log("");
11614
- console.log(chalk15.dim(" Deploy: npx vercel " + outputDir));
11615
- console.log(chalk15.dim(" or: npx netlify deploy --dir " + outputDir + "/.next"));
11890
+ console.log(chalk16.dim(" Deploy: npx vercel " + outputDir));
11891
+ console.log(chalk16.dim(" or: npx netlify deploy --dir " + outputDir + "/.next"));
11616
11892
  console.log("");
11617
11893
  } catch (error) {
11618
11894
  spinner.fail("Export failed");
11619
- if (error instanceof Error) console.error(chalk15.red("\n\u274C " + error.message));
11895
+ if (error instanceof Error) console.error(chalk16.red("\n\u274C " + error.message));
11620
11896
  process.exit(1);
11621
11897
  }
11622
11898
  }
11623
11899
 
11624
11900
  // src/commands/status.ts
11625
- import chalk16 from "chalk";
11901
+ import chalk17 from "chalk";
11626
11902
  import { basename } from "path";
11627
11903
  import { DesignSystemManager as DesignSystemManager9 } from "@getcoherent/core";
11628
11904
  function countTokens(tokens) {
@@ -11646,58 +11922,58 @@ async function statusCommand() {
11646
11922
  try {
11647
11923
  const project = findConfig();
11648
11924
  if (!project) {
11649
- console.log(chalk16.yellow("\u26A0\uFE0F Not in a Coherent project\n"));
11925
+ console.log(chalk17.yellow("\u26A0\uFE0F Not in a Coherent project\n"));
11650
11926
  console.log("Initialize a project:");
11651
- console.log(chalk16.white(" $ coherent init\n"));
11927
+ console.log(chalk17.white(" $ coherent init\n"));
11652
11928
  return;
11653
11929
  }
11654
- console.log(chalk16.cyan("\n\u2728 Current Project\n"));
11655
- console.log(chalk16.gray("\u{1F4C1} Location: ") + chalk16.white(project.root));
11656
- console.log(chalk16.gray("\u{1F4C4} Config: ") + chalk16.white(basename(project.configPath)));
11930
+ console.log(chalk17.cyan("\n\u2728 Current Project\n"));
11931
+ console.log(chalk17.gray("\u{1F4C1} Location: ") + chalk17.white(project.root));
11932
+ console.log(chalk17.gray("\u{1F4C4} Config: ") + chalk17.white(basename(project.configPath)));
11657
11933
  console.log("");
11658
11934
  try {
11659
11935
  const manager = new DesignSystemManager9(project.configPath);
11660
11936
  await manager.load();
11661
11937
  const config2 = manager.getConfig();
11662
- console.log(chalk16.cyan("\u{1F4CA} Statistics:\n"));
11938
+ console.log(chalk17.cyan("\u{1F4CA} Statistics:\n"));
11663
11939
  const pageCount = Array.isArray(config2.pages) ? config2.pages.length : Object.keys(config2.pages || {}).length;
11664
- console.log(chalk16.gray(" Pages: ") + chalk16.white(String(pageCount)));
11940
+ console.log(chalk17.gray(" Pages: ") + chalk17.white(String(pageCount)));
11665
11941
  const componentCount = Array.isArray(config2.components) ? config2.components.length : Object.keys(config2.components || {}).length;
11666
- console.log(chalk16.gray(" Components: ") + chalk16.white(String(componentCount)));
11942
+ console.log(chalk17.gray(" Components: ") + chalk17.white(String(componentCount)));
11667
11943
  const tokenCount = countTokens(config2.tokens);
11668
- console.log(chalk16.gray(" Design tokens: ") + chalk16.white(String(tokenCount)));
11944
+ console.log(chalk17.gray(" Design tokens: ") + chalk17.white(String(tokenCount)));
11669
11945
  console.log("");
11670
11946
  const recent = readRecentChanges(project.root);
11671
11947
  if (recent.length > 0) {
11672
- console.log(chalk16.cyan("\u{1F4DD} Recent changes:\n"));
11948
+ console.log(chalk17.cyan("\u{1F4DD} Recent changes:\n"));
11673
11949
  recent.slice(0, 5).forEach((change) => {
11674
11950
  const ago = formatTimeAgo(change.timestamp);
11675
- console.log(chalk16.gray(" \u2022 ") + chalk16.white(change.description) + chalk16.gray(` (${ago})`));
11951
+ console.log(chalk17.gray(" \u2022 ") + chalk17.white(change.description) + chalk17.gray(` (${ago})`));
11676
11952
  });
11677
11953
  console.log("");
11678
11954
  }
11679
- console.log(chalk16.cyan("\u{1F680} Quick actions:\n"));
11680
- console.log(chalk16.white(' $ coherent chat "add new page"'));
11681
- console.log(chalk16.white(" $ coherent preview"));
11682
- console.log(chalk16.white(" $ coherent export"));
11955
+ console.log(chalk17.cyan("\u{1F680} Quick actions:\n"));
11956
+ console.log(chalk17.white(' $ coherent chat "add new page"'));
11957
+ console.log(chalk17.white(" $ coherent preview"));
11958
+ console.log(chalk17.white(" $ coherent export"));
11683
11959
  console.log("");
11684
11960
  } catch (error) {
11685
- console.error(chalk16.red("Error loading config:"));
11961
+ console.error(chalk17.red("Error loading config:"));
11686
11962
  if (error instanceof Error) {
11687
- console.error(chalk16.red(` ${error.message}`));
11963
+ console.error(chalk17.red(` ${error.message}`));
11688
11964
  } else {
11689
- console.error(chalk16.red(" Unknown error"));
11965
+ console.error(chalk17.red(" Unknown error"));
11690
11966
  }
11691
11967
  console.log("");
11692
11968
  }
11693
11969
  } catch (error) {
11694
- console.error(chalk16.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
11970
+ console.error(chalk17.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
11695
11971
  process.exit(1);
11696
11972
  }
11697
11973
  }
11698
11974
 
11699
11975
  // src/commands/regenerate-docs.ts
11700
- import chalk17 from "chalk";
11976
+ import chalk18 from "chalk";
11701
11977
  import ora5 from "ora";
11702
11978
  import { DesignSystemManager as DesignSystemManager10 } from "@getcoherent/core";
11703
11979
  import { ProjectScaffolder as ProjectScaffolder2 } from "@getcoherent/core";
@@ -11705,9 +11981,9 @@ async function regenerateDocsCommand() {
11705
11981
  try {
11706
11982
  const project = findConfig();
11707
11983
  if (!project) {
11708
- console.log(chalk17.yellow("\u26A0\uFE0F Not in a Coherent project\n"));
11984
+ console.log(chalk18.yellow("\u26A0\uFE0F Not in a Coherent project\n"));
11709
11985
  console.log("Run this command from a project root that has design-system.config.ts");
11710
- console.log(chalk17.white(" $ coherent init # in an empty folder first\n"));
11986
+ console.log(chalk18.white(" $ coherent init # in an empty folder first\n"));
11711
11987
  process.exit(1);
11712
11988
  }
11713
11989
  const spinner = ora5("Regenerating documentation pages...").start();
@@ -11719,23 +11995,23 @@ async function regenerateDocsCommand() {
11719
11995
  await scaffolder.generateDocsPages();
11720
11996
  spinner.succeed("Documentation pages updated");
11721
11997
  console.log(
11722
- chalk17.gray(
11998
+ chalk18.gray(
11723
11999
  "\nUpdated: app/design-system/docs/ (layout, page, components, tokens, for-designers, recommendations)\n"
11724
12000
  )
11725
12001
  );
11726
12002
  } catch (err) {
11727
12003
  spinner.fail("Failed to regenerate docs");
11728
- console.error(chalk17.red(err instanceof Error ? err.message : String(err)));
12004
+ console.error(chalk18.red(err instanceof Error ? err.message : String(err)));
11729
12005
  process.exit(1);
11730
12006
  }
11731
12007
  } catch (error) {
11732
- console.error(chalk17.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
12008
+ console.error(chalk18.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
11733
12009
  process.exit(1);
11734
12010
  }
11735
12011
  }
11736
12012
 
11737
12013
  // src/commands/fix.ts
11738
- import chalk18 from "chalk";
12014
+ import chalk19 from "chalk";
11739
12015
  import { readdirSync as readdirSync7, readFileSync as readFileSync15, existsSync as existsSync21, writeFileSync as writeFileSync11, rmSync as rmSync5, mkdirSync as mkdirSync7 } from "fs";
11740
12016
  import { resolve as resolve12, join as join16 } from "path";
11741
12017
  import {
@@ -11787,31 +12063,31 @@ async function fixCommand(opts = {}) {
11787
12063
  const fixes = [];
11788
12064
  const remaining = [];
11789
12065
  if (dryRun) {
11790
- console.log(chalk18.cyan("\ncoherent fix --dry-run\n"));
12066
+ console.log(chalk19.cyan("\ncoherent fix --dry-run\n"));
11791
12067
  } else {
11792
- console.log(chalk18.cyan("\ncoherent fix\n"));
12068
+ console.log(chalk19.cyan("\ncoherent fix\n"));
11793
12069
  }
11794
12070
  if (!skipCache) {
11795
12071
  const nextDir = join16(projectRoot, ".next");
11796
12072
  if (existsSync21(nextDir)) {
11797
12073
  if (!dryRun) rmSync5(nextDir, { recursive: true, force: true });
11798
12074
  fixes.push("Cleared build cache");
11799
- console.log(chalk18.green(" \u2714 Cleared build cache"));
12075
+ console.log(chalk19.green(" \u2714 Cleared build cache"));
11800
12076
  }
11801
12077
  }
11802
12078
  const missingPkgs = await findMissingPackages(projectRoot);
11803
12079
  if (missingPkgs.length > 0) {
11804
12080
  if (dryRun) {
11805
12081
  fixes.push(`Would install packages: ${missingPkgs.join(", ")}`);
11806
- console.log(chalk18.green(` \u2714 Would install packages: ${missingPkgs.join(", ")}`));
12082
+ console.log(chalk19.green(` \u2714 Would install packages: ${missingPkgs.join(", ")}`));
11807
12083
  } else {
11808
12084
  const ok = await installPackages(projectRoot, missingPkgs);
11809
12085
  if (ok) {
11810
12086
  fixes.push(`Installed missing packages: ${missingPkgs.join(", ")}`);
11811
- console.log(chalk18.green(` \u2714 Installed missing packages: ${missingPkgs.join(", ")}`));
12087
+ console.log(chalk19.green(` \u2714 Installed missing packages: ${missingPkgs.join(", ")}`));
11812
12088
  } else {
11813
12089
  remaining.push(`Failed to install: ${missingPkgs.join(", ")}. Run: npm install ${missingPkgs.join(" ")}`);
11814
- console.log(chalk18.yellow(` \u26A0 Could not install: ${missingPkgs.join(", ")}`));
12090
+ console.log(chalk19.yellow(` \u26A0 Could not install: ${missingPkgs.join(", ")}`));
11815
12091
  }
11816
12092
  }
11817
12093
  }
@@ -11848,7 +12124,7 @@ async function fixCommand(opts = {}) {
11848
12124
  if (toInstall.length > 0) {
11849
12125
  if (dryRun) {
11850
12126
  fixes.push(`Would install components: ${toInstall.join(", ")}`);
11851
- console.log(chalk18.green(` \u2714 Would install components: ${toInstall.join(", ")}`));
12127
+ console.log(chalk19.green(` \u2714 Would install components: ${toInstall.join(", ")}`));
11852
12128
  } else {
11853
12129
  let installed = 0;
11854
12130
  for (const componentId of toInstall) {
@@ -11877,14 +12153,14 @@ async function fixCommand(opts = {}) {
11877
12153
  installed++;
11878
12154
  } catch (err) {
11879
12155
  console.log(
11880
- chalk18.yellow(` \u26A0 Failed to install ${componentId}: ${err instanceof Error ? err.message : "unknown"}`)
12156
+ chalk19.yellow(` \u26A0 Failed to install ${componentId}: ${err instanceof Error ? err.message : "unknown"}`)
11881
12157
  );
11882
12158
  }
11883
12159
  }
11884
12160
  if (installed > 0) {
11885
12161
  await dsm.save();
11886
12162
  fixes.push(`Installed missing components: ${toInstall.join(", ")}`);
11887
- console.log(chalk18.green(` \u2714 Installed missing components: ${toInstall.join(", ")}`));
12163
+ console.log(chalk19.green(` \u2714 Installed missing components: ${toInstall.join(", ")}`));
11888
12164
  }
11889
12165
  }
11890
12166
  }
@@ -11904,7 +12180,7 @@ async function fixCommand(opts = {}) {
11904
12180
  if (syntaxFixed > 0) {
11905
12181
  const verb = dryRun ? "Would fix" : "Fixed";
11906
12182
  fixes.push(`${verb} syntax in ${syntaxFixed} file(s)`);
11907
- console.log(chalk18.green(` \u2714 ${verb} syntax: ${syntaxFixed} file(s) (use client, metadata, quotes)`));
12183
+ console.log(chalk19.green(` \u2714 ${verb} syntax: ${syntaxFixed} file(s) (use client, metadata, quotes)`));
11908
12184
  }
11909
12185
  if (!skipQuality) {
11910
12186
  let qualityFixCount = 0;
@@ -11922,7 +12198,7 @@ async function fixCommand(opts = {}) {
11922
12198
  const uniqueFixes = [...new Set(qualityFixDetails)];
11923
12199
  const verb = dryRun ? "Would fix" : "Fixed";
11924
12200
  fixes.push(`${verb} quality in ${qualityFixCount} file(s)`);
11925
- console.log(chalk18.green(` \u2714 ${verb} ${uniqueFixes.length} quality issue type(s): ${uniqueFixes.join(", ")}`));
12201
+ console.log(chalk19.green(` \u2714 ${verb} ${uniqueFixes.length} quality issue type(s): ${uniqueFixes.join(", ")}`));
11926
12202
  }
11927
12203
  }
11928
12204
  let totalErrors = 0;
@@ -11967,13 +12243,13 @@ async function fixCommand(opts = {}) {
11967
12243
  if (dryRun) {
11968
12244
  fixes.push(`Would update ${o.id} path to ${newPath}`);
11969
12245
  } else {
11970
- console.log(chalk18.green(` \u2714 Updated ${o.id} (${o.name}) path \u2192 ${newPath}`));
12246
+ console.log(chalk19.green(` \u2714 Updated ${o.id} (${o.name}) path \u2192 ${newPath}`));
11971
12247
  }
11972
12248
  } else {
11973
12249
  if (dryRun) {
11974
12250
  fixes.push(`Would remove orphaned ${o.id} (${o.name})`);
11975
12251
  } else {
11976
- console.log(chalk18.green(` \u2714 Removed orphaned ${o.id} (${o.name}) \u2014 file missing`));
12252
+ console.log(chalk19.green(` \u2714 Removed orphaned ${o.id} (${o.name}) \u2014 file missing`));
11977
12253
  }
11978
12254
  }
11979
12255
  }
@@ -11986,7 +12262,7 @@ async function fixCommand(opts = {}) {
11986
12262
  entry.usedIn = fullActual;
11987
12263
  manifestModified = true;
11988
12264
  if (!dryRun) {
11989
- console.log(chalk18.green(` \u2714 Updated ${entry.id} usedIn: ${fullActual.join(", ") || "none"}`));
12265
+ console.log(chalk19.green(` \u2714 Updated ${entry.id} usedIn: ${fullActual.join(", ") || "none"}`));
11990
12266
  }
11991
12267
  }
11992
12268
  }
@@ -12004,7 +12280,7 @@ async function fixCommand(opts = {}) {
12004
12280
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
12005
12281
  });
12006
12282
  manifest.nextId++;
12007
- console.log(chalk18.green(` \u2714 Registered ${id} (${comp.name}) from ${comp.file}`));
12283
+ console.log(chalk19.green(` \u2714 Registered ${id} (${comp.name}) from ${comp.file}`));
12008
12284
  } else {
12009
12285
  fixes.push(`Would register ${comp.name} from ${comp.file}`);
12010
12286
  }
@@ -12024,33 +12300,33 @@ async function fixCommand(opts = {}) {
12024
12300
  } catch {
12025
12301
  }
12026
12302
  if (fixes.length === 0 && totalErrors === 0 && totalWarnings === 0 && remaining.length === 0) {
12027
- console.log(chalk18.green("\n \u2705 Everything looks good \u2014 no issues found\n"));
12028
- console.log(chalk18.cyan(" Run: coherent preview\n"));
12303
+ console.log(chalk19.green("\n \u2705 Everything looks good \u2014 no issues found\n"));
12304
+ console.log(chalk19.cyan(" Run: coherent preview\n"));
12029
12305
  return;
12030
12306
  }
12031
12307
  if (fixes.length > 0) console.log("");
12032
12308
  if (totalErrors > 0 || totalWarnings > 0 || remaining.length > 0) {
12033
- console.log(chalk18.dim(" \u2500".repeat(25)));
12034
- console.log(chalk18.yellow(`
12309
+ console.log(chalk19.dim(" \u2500".repeat(25)));
12310
+ console.log(chalk19.yellow(`
12035
12311
  Remaining (need manual fix or AI):`));
12036
12312
  for (const { path: path4, report } of fileIssues) {
12037
- console.log(chalk18.dim(` \u{1F4C4} ${path4}`));
12313
+ console.log(chalk19.dim(` \u{1F4C4} ${path4}`));
12038
12314
  console.log(report);
12039
12315
  }
12040
12316
  for (const r of remaining) {
12041
- console.log(chalk18.yellow(` \u26A0 ${r}`));
12317
+ console.log(chalk19.yellow(` \u26A0 ${r}`));
12042
12318
  }
12043
12319
  console.log("");
12044
12320
  const parts = [];
12045
- if (totalErrors > 0) parts.push(chalk18.red(`\u274C ${totalErrors} error(s)`));
12046
- if (totalWarnings > 0) parts.push(chalk18.yellow(`\u26A0 ${totalWarnings} warning(s)`));
12321
+ if (totalErrors > 0) parts.push(chalk19.red(`\u274C ${totalErrors} error(s)`));
12322
+ if (totalWarnings > 0) parts.push(chalk19.yellow(`\u26A0 ${totalWarnings} warning(s)`));
12047
12323
  if (parts.length > 0) console.log(` ${parts.join(" ")}`);
12048
12324
  }
12049
- console.log(chalk18.cyan("\n Run: coherent preview\n"));
12325
+ console.log(chalk19.cyan("\n Run: coherent preview\n"));
12050
12326
  }
12051
12327
 
12052
12328
  // src/commands/check.ts
12053
- import chalk19 from "chalk";
12329
+ import chalk20 from "chalk";
12054
12330
  import { resolve as resolve13 } from "path";
12055
12331
  import { readdirSync as readdirSync8, readFileSync as readFileSync16, statSync as statSync2, existsSync as existsSync22 } from "fs";
12056
12332
  import { loadManifest as loadManifest11 } from "@getcoherent/core";
@@ -12098,7 +12374,7 @@ async function checkCommand(opts = {}) {
12098
12374
  const appDir = resolve13(projectRoot, "app");
12099
12375
  const files = findTsxFiles(appDir);
12100
12376
  result.pages.total = files.length;
12101
- if (!opts.json) console.log(chalk19.cyan("\n \u{1F4C4} Pages") + chalk19.dim(` (${files.length} scanned)
12377
+ if (!opts.json) console.log(chalk20.cyan("\n \u{1F4C4} Pages") + chalk20.dim(` (${files.length} scanned)
12102
12378
  `));
12103
12379
  const autoFixableTypes = /* @__PURE__ */ new Set([
12104
12380
  "RAW_COLOR",
@@ -12128,7 +12404,7 @@ async function checkCommand(opts = {}) {
12128
12404
  result.autoFixable += fileAutoFixable;
12129
12405
  if (filteredIssues.length === 0) {
12130
12406
  result.pages.clean++;
12131
- if (!opts.json) console.log(chalk19.green(` \u2714 ${relativePath}`) + chalk19.dim(" \u2014 clean"));
12407
+ if (!opts.json) console.log(chalk20.green(` \u2714 ${relativePath}`) + chalk20.dim(" \u2014 clean"));
12132
12408
  continue;
12133
12409
  }
12134
12410
  if (errors > 0) result.pages.withErrors++;
@@ -12141,9 +12417,9 @@ async function checkCommand(opts = {}) {
12141
12417
  });
12142
12418
  if (!opts.json) {
12143
12419
  const parts = [];
12144
- if (errors > 0) parts.push(chalk19.red(`${errors} error(s)`));
12145
- if (warnings > 0) parts.push(chalk19.yellow(`${warnings} warning(s)`));
12146
- console.log(chalk19.yellow(` \u26A0 ${relativePath}`) + chalk19.dim(` \u2014 ${parts.join(", ")}`));
12420
+ if (errors > 0) parts.push(chalk20.red(`${errors} error(s)`));
12421
+ if (warnings > 0) parts.push(chalk20.yellow(`${warnings} warning(s)`));
12422
+ console.log(chalk20.yellow(` \u26A0 ${relativePath}`) + chalk20.dim(` \u2014 ${parts.join(", ")}`));
12147
12423
  console.log(formatIssues(filteredIssues));
12148
12424
  }
12149
12425
  }
@@ -12169,15 +12445,15 @@ async function checkCommand(opts = {}) {
12169
12445
  }
12170
12446
  }
12171
12447
  if (!opts.json && result.links.broken.length > 0) {
12172
- console.log(chalk19.yellow(`
12173
- \u{1F517} Internal Links`) + chalk19.dim(` (${result.links.total} scanned)
12448
+ console.log(chalk20.yellow(`
12449
+ \u{1F517} Internal Links`) + chalk20.dim(` (${result.links.total} scanned)
12174
12450
  `));
12175
12451
  for (const b of result.links.broken) {
12176
- console.log(chalk19.red(` \u2717 ${b.file}:${b.line}`) + chalk19.dim(` \u2192 ${b.href} (route does not exist)`));
12452
+ console.log(chalk20.red(` \u2717 ${b.file}:${b.line}`) + chalk20.dim(` \u2192 ${b.href} (route does not exist)`));
12177
12453
  }
12178
12454
  } else if (!opts.json && result.links.total > 0) {
12179
- console.log(chalk19.green(`
12180
- \u{1F517} Internal Links`) + chalk19.dim(` \u2014 all ${result.links.total} links resolve \u2713`));
12455
+ console.log(chalk20.green(`
12456
+ \u{1F517} Internal Links`) + chalk20.dim(` \u2014 all ${result.links.total} links resolve \u2713`));
12181
12457
  }
12182
12458
  try {
12183
12459
  const manifest = await loadManifest11(project.root);
@@ -12186,7 +12462,7 @@ async function checkCommand(opts = {}) {
12186
12462
  const fullPath = resolve13(project.root, entry.file);
12187
12463
  if (!existsSync22(fullPath)) {
12188
12464
  result.pages.withErrors++;
12189
- if (!opts.json) console.log(chalk19.red(`
12465
+ if (!opts.json) console.log(chalk20.red(`
12190
12466
  \u2717 Missing shared component file: ${entry.id} (${entry.file})`));
12191
12467
  }
12192
12468
  }
@@ -12198,8 +12474,8 @@ async function checkCommand(opts = {}) {
12198
12474
  try {
12199
12475
  const manifest = await loadManifest11(projectRoot);
12200
12476
  if (!opts.json && manifest.shared.length > 0) {
12201
- console.log(chalk19.cyan(`
12202
- \u{1F9E9} Shared Components`) + chalk19.dim(` (${manifest.shared.length} registered)
12477
+ console.log(chalk20.cyan(`
12478
+ \u{1F9E9} Shared Components`) + chalk20.dim(` (${manifest.shared.length} registered)
12203
12479
  `));
12204
12480
  }
12205
12481
  let consistent = 0;
@@ -12213,8 +12489,8 @@ async function checkCommand(opts = {}) {
12213
12489
  if (!fileExists) {
12214
12490
  _orphaned++;
12215
12491
  if (!opts.json) {
12216
- console.log(chalk19.red(` \u274C ${entry.id} (${entry.name}) \u2014 file missing: ${entry.file}`));
12217
- console.log(chalk19.dim(` Fix: coherent fix or coherent sync`));
12492
+ console.log(chalk20.red(` \u274C ${entry.id} (${entry.name}) \u2014 file missing: ${entry.file}`));
12493
+ console.log(chalk20.dim(` Fix: coherent fix or coherent sync`));
12218
12494
  }
12219
12495
  continue;
12220
12496
  }
@@ -12225,11 +12501,11 @@ async function checkCommand(opts = {}) {
12225
12501
  _nameMismatch++;
12226
12502
  if (!opts.json) {
12227
12503
  console.log(
12228
- chalk19.yellow(
12504
+ chalk20.yellow(
12229
12505
  ` \u26A0 ${entry.id} \u2014 manifest name "${entry.name}" doesn't match export "${actualExports[0]}"`
12230
12506
  )
12231
12507
  );
12232
- console.log(chalk19.dim(` Fix: coherent sync`));
12508
+ console.log(chalk20.dim(` Fix: coherent sync`));
12233
12509
  }
12234
12510
  }
12235
12511
  } catch {
@@ -12244,35 +12520,35 @@ async function checkCommand(opts = {}) {
12244
12520
  if (totalUsage === 0) {
12245
12521
  unused++;
12246
12522
  if (!opts.json) {
12247
- console.log(chalk19.blue(` \u2139 ${entry.id} (${entry.name}) \u2014 registered but not used anywhere`));
12248
- console.log(chalk19.dim(` Remove: coherent components shared remove ${entry.id}`));
12523
+ console.log(chalk20.blue(` \u2139 ${entry.id} (${entry.name}) \u2014 registered but not used anywhere`));
12524
+ console.log(chalk20.dim(` Remove: coherent components shared remove ${entry.id}`));
12249
12525
  }
12250
12526
  } else {
12251
12527
  consistent++;
12252
12528
  const usageDesc = inLayout ? `layout + ${actualUsedIn.length} page(s)` : `${actualUsedIn.length} page(s)`;
12253
12529
  if (!opts.json) {
12254
- const staleNote = isStale ? chalk19.yellow(" [usedIn stale]") : "";
12255
- console.log(chalk19.green(` \u2714 ${entry.id} (${entry.name})`) + chalk19.dim(` \u2014 ${usageDesc}`) + staleNote);
12530
+ const staleNote = isStale ? chalk20.yellow(" [usedIn stale]") : "";
12531
+ console.log(chalk20.green(` \u2714 ${entry.id} (${entry.name})`) + chalk20.dim(` \u2014 ${usageDesc}`) + staleNote);
12256
12532
  }
12257
12533
  }
12258
12534
  }
12259
12535
  const unregistered = findUnregisteredComponents(projectRoot, manifest);
12260
12536
  if (unregistered.length > 0 && !opts.json) {
12261
- console.log(chalk19.cyan(`
12537
+ console.log(chalk20.cyan(`
12262
12538
  \u{1F4E6} Unregistered components found:`));
12263
12539
  for (const comp of unregistered) {
12264
- console.log(chalk19.blue(` \u2139 ${comp.name}`) + chalk19.dim(` \u2014 ${comp.file} (not in manifest)`));
12265
- console.log(chalk19.dim(` Register: coherent sync`));
12540
+ console.log(chalk20.blue(` \u2139 ${comp.name}`) + chalk20.dim(` \u2014 ${comp.file} (not in manifest)`));
12541
+ console.log(chalk20.dim(` Register: coherent sync`));
12266
12542
  }
12267
12543
  }
12268
12544
  const inlineDupes = findInlineDuplicates(projectRoot, manifest);
12269
12545
  if (inlineDupes.length > 0 && !opts.json) {
12270
- console.log(chalk19.cyan(`
12546
+ console.log(chalk20.cyan(`
12271
12547
  \u{1F50D} Inline duplicates:`));
12272
12548
  for (const dup of inlineDupes) {
12273
- console.log(chalk19.yellow(` \u26A0 ${dup.pageFile}`) + chalk19.dim(` has inline ${dup.componentName}`));
12549
+ console.log(chalk20.yellow(` \u26A0 ${dup.pageFile}`) + chalk20.dim(` has inline ${dup.componentName}`));
12274
12550
  console.log(
12275
- chalk19.dim(
12551
+ chalk20.dim(
12276
12552
  ` Use shared: import { ${dup.componentName} } from "@/${dup.sharedFile.replace(".tsx", "")}"`
12277
12553
  )
12278
12554
  );
@@ -12299,24 +12575,24 @@ async function checkCommand(opts = {}) {
12299
12575
  console.log(JSON.stringify(result, null, 2));
12300
12576
  return;
12301
12577
  }
12302
- console.log(chalk19.dim("\n " + "\u2500".repeat(50)));
12578
+ console.log(chalk20.dim("\n " + "\u2500".repeat(50)));
12303
12579
  const summaryParts = [];
12304
12580
  if (!skipPages) {
12305
- summaryParts.push(`${chalk19.green(`${result.pages.clean} clean`)} pages`);
12306
- if (result.pages.withErrors > 0) summaryParts.push(chalk19.red(`${result.pages.withErrors} with errors`));
12307
- if (result.pages.withWarnings > 0) summaryParts.push(chalk19.yellow(`${result.pages.withWarnings} with warnings`));
12581
+ summaryParts.push(`${chalk20.green(`${result.pages.clean} clean`)} pages`);
12582
+ if (result.pages.withErrors > 0) summaryParts.push(chalk20.red(`${result.pages.withErrors} with errors`));
12583
+ if (result.pages.withWarnings > 0) summaryParts.push(chalk20.yellow(`${result.pages.withWarnings} with warnings`));
12308
12584
  }
12309
12585
  if (!skipShared && result.shared.total > 0) {
12310
12586
  summaryParts.push(`${result.shared.consistent} healthy shared`);
12311
12587
  if (result.shared.unused > 0) summaryParts.push(`${result.shared.unused} unused`);
12312
12588
  }
12313
12589
  if (result.links.broken.length > 0) {
12314
- summaryParts.push(chalk19.red(`${result.links.broken.length} broken link(s)`));
12590
+ summaryParts.push(chalk20.red(`${result.links.broken.length} broken link(s)`));
12315
12591
  }
12316
12592
  console.log(`
12317
12593
  ${summaryParts.join(" | ")}`);
12318
12594
  if (result.autoFixable > 0) {
12319
- console.log(chalk19.cyan(`
12595
+ console.log(chalk20.cyan(`
12320
12596
  Auto-fixable: ${result.autoFixable} issues. Run: coherent fix`));
12321
12597
  }
12322
12598
  console.log("");
@@ -12325,21 +12601,21 @@ async function checkCommand(opts = {}) {
12325
12601
  }
12326
12602
 
12327
12603
  // src/commands/repair.ts
12328
- import chalk20 from "chalk";
12604
+ import chalk21 from "chalk";
12329
12605
  async function repairCommand() {
12330
- console.log(chalk20.dim(" \u2139\uFE0F `coherent repair` is deprecated \u2014 use `coherent fix` instead\n"));
12606
+ console.log(chalk21.dim(" \u2139\uFE0F `coherent repair` is deprecated \u2014 use `coherent fix` instead\n"));
12331
12607
  await fixCommand();
12332
12608
  }
12333
12609
 
12334
12610
  // src/commands/doctor.ts
12335
- import chalk21 from "chalk";
12611
+ import chalk22 from "chalk";
12336
12612
  async function doctorCommand() {
12337
- console.log(chalk21.dim(" \u2139\uFE0F `coherent doctor` is deprecated \u2014 use `coherent fix` instead\n"));
12613
+ console.log(chalk22.dim(" \u2139\uFE0F `coherent doctor` is deprecated \u2014 use `coherent fix` instead\n"));
12338
12614
  await fixCommand();
12339
12615
  }
12340
12616
 
12341
12617
  // src/commands/rules.ts
12342
- import chalk22 from "chalk";
12618
+ import chalk23 from "chalk";
12343
12619
  async function rulesCommand() {
12344
12620
  try {
12345
12621
  const result = await regenerateCursorRules();
@@ -12350,31 +12626,31 @@ async function rulesCommand() {
12350
12626
  if (result.sharedCount !== void 0) parts.push(`${result.sharedCount} shared components`);
12351
12627
  if (result.tokenKeys !== void 0) parts.push(`${result.tokenKeys} design token keys`);
12352
12628
  const summary = parts.length > 0 ? ` (${parts.join(", ")})` : "";
12353
- console.log(chalk22.green(`\u2714 Updated .cursorrules and CLAUDE.md${summary}
12629
+ console.log(chalk23.green(`\u2714 Updated .cursorrules and CLAUDE.md${summary}
12354
12630
  `));
12355
12631
  } catch (error) {
12356
- console.error(chalk22.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
12632
+ console.error(chalk23.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
12357
12633
  process.exit(1);
12358
12634
  }
12359
12635
  }
12360
12636
 
12361
12637
  // src/commands/validate.ts
12362
- import chalk23 from "chalk";
12638
+ import chalk24 from "chalk";
12363
12639
  async function validateCommand() {
12364
- console.log(chalk23.dim(" \u2139\uFE0F `coherent validate` is deprecated \u2014 use `coherent check` instead\n"));
12640
+ console.log(chalk24.dim(" \u2139\uFE0F `coherent validate` is deprecated \u2014 use `coherent check` instead\n"));
12365
12641
  await checkCommand({ pages: true });
12366
12642
  }
12367
12643
 
12368
12644
  // src/commands/audit.ts
12369
- import chalk24 from "chalk";
12645
+ import chalk25 from "chalk";
12370
12646
  async function auditCommand(options) {
12371
- console.log(chalk24.dim(" \u2139\uFE0F `coherent audit` is deprecated \u2014 use `coherent check` instead\n"));
12647
+ console.log(chalk25.dim(" \u2139\uFE0F `coherent audit` is deprecated \u2014 use `coherent check` instead\n"));
12372
12648
  await checkCommand({ shared: true, json: options.json });
12373
12649
  }
12374
12650
 
12375
12651
  // src/commands/components.ts
12376
12652
  import { Command } from "commander";
12377
- import chalk25 from "chalk";
12653
+ import chalk26 from "chalk";
12378
12654
  import {
12379
12655
  DesignSystemManager as DesignSystemManager12,
12380
12656
  ComponentManager as ComponentManager7,
@@ -12425,9 +12701,9 @@ function createComponentsCommand() {
12425
12701
  console.log(JSON.stringify({ shared: manifest.shared, ui: installed2 }, null, 2));
12426
12702
  return;
12427
12703
  }
12428
- console.log(chalk25.bold("\n\u{1F4E6} Shared Components"));
12704
+ console.log(chalk26.bold("\n\u{1F4E6} Shared Components"));
12429
12705
  if (manifest.shared.length === 0) {
12430
- console.log(chalk25.gray(" None yet. Generate pages with header/footer to create them.\n"));
12706
+ console.log(chalk26.gray(" None yet. Generate pages with header/footer to create them.\n"));
12431
12707
  } else {
12432
12708
  const order = { layout: 0, section: 1, widget: 2 };
12433
12709
  const sorted = [...manifest.shared].sort(
@@ -12435,9 +12711,9 @@ function createComponentsCommand() {
12435
12711
  );
12436
12712
  console.log("");
12437
12713
  sorted.forEach((entry) => {
12438
- const usage = entry.usedIn.length === 0 ? chalk25.gray("unused") : entry.usedIn.includes("app/layout.tsx") ? chalk25.green("all pages") : chalk25.gray(entry.usedIn.join(", "));
12714
+ const usage = entry.usedIn.length === 0 ? chalk26.gray("unused") : entry.usedIn.includes("app/layout.tsx") ? chalk26.green("all pages") : chalk26.gray(entry.usedIn.join(", "));
12439
12715
  console.log(
12440
- ` ${chalk25.cyan(entry.id.padEnd(8))} ${chalk25.white(entry.name.padEnd(18))} ${chalk25.gray(entry.type.padEnd(9))} ${usage}`
12716
+ ` ${chalk26.cyan(entry.id.padEnd(8))} ${chalk26.white(entry.name.padEnd(18))} ${chalk26.gray(entry.type.padEnd(9))} ${usage}`
12441
12717
  );
12442
12718
  });
12443
12719
  console.log("");
@@ -12446,24 +12722,24 @@ function createComponentsCommand() {
12446
12722
  const availableShadcn = listShadcnComponents();
12447
12723
  const installedIds = new Set(installed.map((c) => c.id));
12448
12724
  const notInstalled = availableShadcn.filter((id) => !installedIds.has(id));
12449
- console.log(chalk25.bold("\u{1F9E9} UI Components (shadcn)"));
12725
+ console.log(chalk26.bold("\u{1F9E9} UI Components (shadcn)"));
12450
12726
  if (installed.length === 0) {
12451
- console.log(chalk25.gray(" None installed yet.\n"));
12727
+ console.log(chalk26.gray(" None installed yet.\n"));
12452
12728
  } else {
12453
12729
  const names = installed.map((c) => c.name).sort();
12454
- console.log(chalk25.green(` Installed (${names.length}): `) + chalk25.white(names.join(", ")));
12730
+ console.log(chalk26.green(` Installed (${names.length}): `) + chalk26.white(names.join(", ")));
12455
12731
  }
12456
12732
  if (notInstalled.length > 0) {
12457
- console.log(chalk25.gray(` Available (${notInstalled.length}): `) + chalk25.gray(notInstalled.join(", ")));
12733
+ console.log(chalk26.gray(` Available (${notInstalled.length}): `) + chalk26.gray(notInstalled.join(", ")));
12458
12734
  }
12459
12735
  console.log("");
12460
- console.log(chalk25.cyan("\u{1F4A1} Commands:"));
12461
- console.log(chalk25.white(' coherent chat "add a testimonial component"'));
12462
- console.log(chalk25.white(' coherent chat --component "Header" "add a search button"'));
12736
+ console.log(chalk26.cyan("\u{1F4A1} Commands:"));
12737
+ console.log(chalk26.white(' coherent chat "add a testimonial component"'));
12738
+ console.log(chalk26.white(' coherent chat --component "Header" "add a search button"'));
12463
12739
  console.log("");
12464
12740
  });
12465
12741
  cmd.command("add <name>").description("Install a specific component").action(async (name) => {
12466
- console.log(chalk25.yellow(`
12742
+ console.log(chalk26.yellow(`
12467
12743
  \u{1F4A1} Use: coherent chat "add ${name} component"
12468
12744
  `));
12469
12745
  });
@@ -12476,25 +12752,25 @@ function createComponentsCommand() {
12476
12752
  console.log(JSON.stringify(manifest, null, 2));
12477
12753
  return;
12478
12754
  }
12479
- console.log(chalk25.bold("\n\u{1F4E6} Shared Components\n"));
12755
+ console.log(chalk26.bold("\n\u{1F4E6} Shared Components\n"));
12480
12756
  if (manifest.shared.length === 0) {
12481
- console.log(chalk25.yellow(" No shared components yet.\n"));
12482
- console.log(chalk25.gray(' Create via chat: coherent chat "add a page with header and footer"\n'));
12757
+ console.log(chalk26.yellow(" No shared components yet.\n"));
12758
+ console.log(chalk26.gray(' Create via chat: coherent chat "add a page with header and footer"\n'));
12483
12759
  return;
12484
12760
  }
12485
12761
  const order = { layout: 0, section: 1, widget: 2 };
12486
12762
  const sorted = [...manifest.shared].sort((a, b) => order[a.type] - order[b.type] || a.name.localeCompare(b.name));
12487
12763
  sorted.forEach((entry) => {
12488
- const usedIn = entry.usedIn.length === 0 ? chalk25.gray("(not used yet)") : entry.usedIn.length === 1 && entry.usedIn[0] === "app/layout.tsx" ? chalk25.gray("layout.tsx (all pages)") : chalk25.gray(`used in: ${entry.usedIn.join(", ")}`);
12489
- console.log(chalk25.cyan(` ${entry.id}`), chalk25.white(entry.name), chalk25.gray(entry.type));
12764
+ const usedIn = entry.usedIn.length === 0 ? chalk26.gray("(not used yet)") : entry.usedIn.length === 1 && entry.usedIn[0] === "app/layout.tsx" ? chalk26.gray("layout.tsx (all pages)") : chalk26.gray(`used in: ${entry.usedIn.join(", ")}`);
12765
+ console.log(chalk26.cyan(` ${entry.id}`), chalk26.white(entry.name), chalk26.gray(entry.type));
12490
12766
  if (opts.verbose) {
12491
- console.log(chalk25.gray(` file: ${entry.file}`));
12492
- if (entry.description) console.log(chalk25.gray(` ${entry.description}`));
12767
+ console.log(chalk26.gray(` file: ${entry.file}`));
12768
+ if (entry.description) console.log(chalk26.gray(` ${entry.description}`));
12493
12769
  }
12494
- console.log(chalk25.gray(` ${usedIn}`));
12770
+ console.log(chalk26.gray(` ${usedIn}`));
12495
12771
  console.log("");
12496
12772
  });
12497
- console.log(chalk25.cyan("\u{1F4A1} Modify by ID:"), chalk25.white('coherent chat "in CID-001 add a search button"\n'));
12773
+ console.log(chalk26.cyan("\u{1F4A1} Modify by ID:"), chalk26.white('coherent chat "in CID-001 add a search button"\n'));
12498
12774
  });
12499
12775
  sharedCmd.command("add <name>").description("Create a shared component (layout/section/widget) and register in manifest").option("-t, --type <type>", "Type: layout | section | widget", "layout").option("-d, --description <desc>", "Description").action(async (name, opts) => {
12500
12776
  const project = findConfig();
@@ -12506,12 +12782,12 @@ function createComponentsCommand() {
12506
12782
  description: opts.description,
12507
12783
  usedIn: type === "layout" ? ["app/layout.tsx"] : []
12508
12784
  });
12509
- console.log(chalk25.green(`
12785
+ console.log(chalk26.green(`
12510
12786
  \u2705 Created ${result.id} (${result.name}) at ${result.file}
12511
12787
  `));
12512
12788
  if (type === "layout") {
12513
12789
  const updated = await integrateSharedLayoutIntoRootLayout3(project.root);
12514
- if (updated) console.log(chalk25.cyan(" Updated app/layout.tsx to use shared layout components.\n"));
12790
+ if (updated) console.log(chalk26.cyan(" Updated app/layout.tsx to use shared layout components.\n"));
12515
12791
  }
12516
12792
  const sharedPagePath = resolve14(project.root, "app/design-system/shared/page.tsx");
12517
12793
  if (!existsSync23(sharedPagePath)) {
@@ -12521,23 +12797,23 @@ function createComponentsCommand() {
12521
12797
  const config2 = dsm.getConfig();
12522
12798
  const written = await writeDesignSystemFiles(project.root, config2, { sharedOnly: true });
12523
12799
  if (written.length > 0) {
12524
- console.log(chalk25.cyan(" Added Design System shared pages: /design-system/shared\n"));
12800
+ console.log(chalk26.cyan(" Added Design System shared pages: /design-system/shared\n"));
12525
12801
  }
12526
12802
  } catch (e) {
12527
- if (process.env.COHERENT_DEBUG === "1") console.error(chalk25.dim("DS shared pages write failed:"), e);
12803
+ if (process.env.COHERENT_DEBUG === "1") console.error(chalk26.dim("DS shared pages write failed:"), e);
12528
12804
  }
12529
12805
  }
12530
12806
  try {
12531
12807
  await writeCursorRules(project.root);
12532
12808
  } catch (e) {
12533
- if (process.env.COHERENT_DEBUG === "1") console.error(chalk25.dim("Could not update .cursorrules:"), e);
12809
+ if (process.env.COHERENT_DEBUG === "1") console.error(chalk26.dim("Could not update .cursorrules:"), e);
12534
12810
  }
12535
12811
  });
12536
12812
  return cmd;
12537
12813
  }
12538
12814
 
12539
12815
  // src/commands/import-cmd.ts
12540
- import chalk26 from "chalk";
12816
+ import chalk27 from "chalk";
12541
12817
  import ora6 from "ora";
12542
12818
  import { writeFile as writeFile7, mkdir as mkdir7 } from "fs/promises";
12543
12819
  import { resolve as resolve15, join as join18, dirname as dirname9 } from "path";
@@ -12642,25 +12918,25 @@ function createImportCommand() {
12642
12918
  }
12643
12919
  async function importFigmaAction(urlOrKey, opts) {
12644
12920
  if (typeof urlOrKey !== "string" || !urlOrKey.trim()) {
12645
- console.error(chalk26.red("\n\u274C Figma URL or file key is required.\n"));
12646
- console.log(chalk26.dim(" Usage: coherent import figma <url-or-key> --token <your-token>\n"));
12921
+ console.error(chalk27.red("\n\u274C Figma URL or file key is required.\n"));
12922
+ console.log(chalk27.dim(" Usage: coherent import figma <url-or-key> --token <your-token>\n"));
12647
12923
  process.exit(1);
12648
12924
  }
12649
12925
  const token = opts.token ?? process.env.FIGMA_ACCESS_TOKEN ?? process.env.FIGMA_TOKEN;
12650
12926
  if (!token || typeof token !== "string") {
12651
- console.error(chalk26.red("\n\u274C Figma token required.\n"));
12652
- console.log(chalk26.dim(" Use: coherent import figma <url-or-key> --token <your-token>"));
12653
- console.log(chalk26.dim(" Or set FIGMA_ACCESS_TOKEN or FIGMA_TOKEN in your environment.\n"));
12654
- console.log(chalk26.dim(" Get a token: Figma \u2192 Settings \u2192 Personal access tokens.\n"));
12927
+ console.error(chalk27.red("\n\u274C Figma token required.\n"));
12928
+ console.log(chalk27.dim(" Use: coherent import figma <url-or-key> --token <your-token>"));
12929
+ console.log(chalk27.dim(" Or set FIGMA_ACCESS_TOKEN or FIGMA_TOKEN in your environment.\n"));
12930
+ console.log(chalk27.dim(" Get a token: Figma \u2192 Settings \u2192 Personal access tokens.\n"));
12655
12931
  process.exit(1);
12656
12932
  }
12657
12933
  const generatePages = opts.pages !== false;
12658
12934
  const dryRun = Boolean(opts.dryRun);
12659
12935
  const fileKey = FigmaClient.extractFileKey(urlOrKey);
12660
12936
  if (!fileKey) {
12661
- console.error(chalk26.red("\n\u274C Invalid Figma URL or file key.\n"));
12662
- console.log(chalk26.dim(" Use a URL like: https://www.figma.com/file/ABC123/MyDesign"));
12663
- console.log(chalk26.dim(" Or the file key: ABC123\n"));
12937
+ console.error(chalk27.red("\n\u274C Invalid Figma URL or file key.\n"));
12938
+ console.log(chalk27.dim(" Use a URL like: https://www.figma.com/file/ABC123/MyDesign"));
12939
+ console.log(chalk27.dim(" Or the file key: ABC123\n"));
12664
12940
  process.exit(1);
12665
12941
  }
12666
12942
  const project = findConfig();
@@ -12837,7 +13113,7 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
12837
13113
  try {
12838
13114
  await writeCursorRules(projectRoot);
12839
13115
  } catch (e) {
12840
- if (process.env.COHERENT_DEBUG === "1") console.error(chalk26.dim("Could not update .cursorrules:"), e);
13116
+ if (process.env.COHERENT_DEBUG === "1") console.error(chalk27.dim("Could not update .cursorrules:"), e);
12841
13117
  }
12842
13118
  } else {
12843
13119
  stats.filesWritten.push(DESIGN_SYSTEM_CONFIG_PATH);
@@ -12847,7 +13123,7 @@ export const config = ${JSON.stringify(fullConfig, null, 2)} as const
12847
13123
  } catch (err) {
12848
13124
  spinner.fail("Import failed");
12849
13125
  const message = err instanceof Error ? err.message : String(err);
12850
- console.error(chalk26.red("\n\u274C " + message + "\n"));
13126
+ console.error(chalk27.red("\n\u274C " + message + "\n"));
12851
13127
  process.exit(1);
12852
13128
  }
12853
13129
  }
@@ -12855,36 +13131,36 @@ function printReport(stats, opts) {
12855
13131
  const { dryRun, generatePages, fileName } = opts;
12856
13132
  console.log("");
12857
13133
  if (dryRun) {
12858
- console.log(chalk26.yellow("\u2550\u2550\u2550 Dry run (no files written) \u2550\u2550\u2550"));
13134
+ console.log(chalk27.yellow("\u2550\u2550\u2550 Dry run (no files written) \u2550\u2550\u2550"));
12859
13135
  console.log("");
12860
13136
  }
12861
- console.log(chalk26.green("\u2705 Figma import complete"));
13137
+ console.log(chalk27.green("\u2705 Figma import complete"));
12862
13138
  console.log("");
12863
- console.log(chalk26.cyan(" Statistics"));
12864
- console.log(chalk26.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
12865
- console.log(chalk26.blue(` File: ${fileName}`));
12866
- console.log(chalk26.blue(` Color styles: ${stats.colorStyles}`));
12867
- console.log(chalk26.blue(` Text styles: ${stats.textStyles}`));
13139
+ console.log(chalk27.cyan(" Statistics"));
13140
+ console.log(chalk27.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
13141
+ console.log(chalk27.blue(` File: ${fileName}`));
13142
+ console.log(chalk27.blue(` Color styles: ${stats.colorStyles}`));
13143
+ console.log(chalk27.blue(` Text styles: ${stats.textStyles}`));
12868
13144
  console.log(
12869
- chalk26.blue(` Components: ${stats.componentsTotal} (${stats.baseCount} \u2192 base, ${stats.sharedCount} \u2192 shared)`)
13145
+ chalk27.blue(` Components: ${stats.componentsTotal} (${stats.baseCount} \u2192 base, ${stats.sharedCount} \u2192 shared)`)
12870
13146
  );
12871
- console.log(chalk26.blue(` Pages: ${stats.pagesGenerated}${!generatePages ? " (skipped by --no-pages)" : ""}`));
12872
- console.log(chalk26.blue(` design-system.config: ${stats.configUpdated ? "updated" : "\u2014"}`));
12873
- console.log(chalk26.blue(` Layout (Header/Footer): ${stats.layoutIntegrated ? "integrated" : "\u2014"}`));
12874
- console.log(chalk26.blue(` DS viewer files: ${stats.dsFilesWritten}`));
13147
+ console.log(chalk27.blue(` Pages: ${stats.pagesGenerated}${!generatePages ? " (skipped by --no-pages)" : ""}`));
13148
+ console.log(chalk27.blue(` design-system.config: ${stats.configUpdated ? "updated" : "\u2014"}`));
13149
+ console.log(chalk27.blue(` Layout (Header/Footer): ${stats.layoutIntegrated ? "integrated" : "\u2014"}`));
13150
+ console.log(chalk27.blue(` DS viewer files: ${stats.dsFilesWritten}`));
12875
13151
  console.log(
12876
- chalk26.blue(` Total files ${dryRun ? "that would be written" : "written"}: ${stats.filesWritten.length}`)
13152
+ chalk27.blue(` Total files ${dryRun ? "that would be written" : "written"}: ${stats.filesWritten.length}`)
12877
13153
  );
12878
13154
  console.log("");
12879
13155
  if (stats.filesWritten.length > 0 && stats.filesWritten.length <= 30) {
12880
- console.log(chalk26.dim(" Files:"));
12881
- stats.filesWritten.forEach((f) => console.log(chalk26.dim(` ${f}`)));
13156
+ console.log(chalk27.dim(" Files:"));
13157
+ stats.filesWritten.forEach((f) => console.log(chalk27.dim(` ${f}`)));
12882
13158
  console.log("");
12883
13159
  }
12884
13160
  }
12885
13161
 
12886
13162
  // src/commands/ds.ts
12887
- import chalk27 from "chalk";
13163
+ import chalk28 from "chalk";
12888
13164
  import ora7 from "ora";
12889
13165
  import { DesignSystemManager as DesignSystemManager14 } from "@getcoherent/core";
12890
13166
  async function dsRegenerateCommand() {
@@ -12899,16 +13175,16 @@ async function dsRegenerateCommand() {
12899
13175
  const config2 = dsm.getConfig();
12900
13176
  const written = await writeDesignSystemFiles(project.root, config2);
12901
13177
  spinner.succeed(`Regenerated ${written.length} Design System file(s)`);
12902
- console.log(chalk27.gray(" app/design-system/* and app/api/design-system/*\n"));
12903
- console.log(chalk27.cyan(" Open /design-system in the app to view.\n"));
13178
+ console.log(chalk28.gray(" app/design-system/* and app/api/design-system/*\n"));
13179
+ console.log(chalk28.cyan(" Open /design-system in the app to view.\n"));
12904
13180
  } catch (error) {
12905
- console.error(chalk27.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
13181
+ console.error(chalk28.red("\u274C Command failed:"), error instanceof Error ? error.message : "Unknown error");
12906
13182
  process.exit(1);
12907
13183
  }
12908
13184
  }
12909
13185
 
12910
13186
  // src/commands/update.ts
12911
- import chalk28 from "chalk";
13187
+ import chalk29 from "chalk";
12912
13188
  import ora8 from "ora";
12913
13189
  import { readFileSync as readFileSync17, existsSync as existsSync25 } from "fs";
12914
13190
  import { join as join19 } from "path";
@@ -12960,14 +13236,14 @@ async function updateCommand(opts) {
12960
13236
  const projectVersion = config2.coherentVersion || "0.0.0";
12961
13237
  if (compareSemver(projectVersion, CLI_VERSION4) === 0) {
12962
13238
  spinner.succeed("Project is already up to date");
12963
- console.log(chalk28.gray(` Version: v${CLI_VERSION4}
13239
+ console.log(chalk29.gray(` Version: v${CLI_VERSION4}
12964
13240
  `));
12965
13241
  return;
12966
13242
  }
12967
13243
  if (compareSemver(projectVersion, CLI_VERSION4) > 0) {
12968
13244
  spinner.warn("Project was created with a newer CLI version");
12969
- console.log(chalk28.yellow(` Project: v${projectVersion} \u2192 CLI: v${CLI_VERSION4}`));
12970
- console.log(chalk28.yellow(" Update your CLI: npm install -g @getcoherent/cli@latest\n"));
13245
+ console.log(chalk29.yellow(` Project: v${projectVersion} \u2192 CLI: v${CLI_VERSION4}`));
13246
+ console.log(chalk29.yellow(" Update your CLI: npm install -g @getcoherent/cli@latest\n"));
12971
13247
  return;
12972
13248
  }
12973
13249
  const report = {
@@ -13013,36 +13289,36 @@ async function updateCommand(opts) {
13013
13289
  }
13014
13290
  function printReport2(report) {
13015
13291
  const from = report.fromVersion ? `v${report.fromVersion}` : "unknown";
13016
- console.log(chalk28.green(`
13292
+ console.log(chalk29.green(`
13017
13293
  \u2714 Project updated: ${from} \u2192 v${report.toVersion}
13018
13294
  `));
13019
13295
  if (report.overlayFiles > 0) {
13020
- console.log(chalk28.white(` \u2714 Regenerated platform overlay (${report.overlayFiles} files)`));
13296
+ console.log(chalk29.white(` \u2714 Regenerated platform overlay (${report.overlayFiles} files)`));
13021
13297
  }
13022
13298
  if (report.migrationsApplied.length > 0) {
13023
13299
  for (const desc of report.migrationsApplied) {
13024
- console.log(chalk28.white(` \u2714 Migrated config: ${desc}`));
13300
+ console.log(chalk29.white(` \u2714 Migrated config: ${desc}`));
13025
13301
  }
13026
13302
  }
13027
13303
  if (report.rulesUpdated) {
13028
- console.log(chalk28.white(" \u2714 Updated .cursorrules and CLAUDE.md"));
13304
+ console.log(chalk29.white(" \u2714 Updated .cursorrules and CLAUDE.md"));
13029
13305
  }
13030
13306
  if (report.missingCssVars.length > 0) {
13031
13307
  console.log("");
13032
- console.log(chalk28.yellow(" \u26A0 New CSS variables available in globals.css:"));
13308
+ console.log(chalk29.yellow(" \u26A0 New CSS variables available in globals.css:"));
13033
13309
  for (const v of report.missingCssVars.slice(0, 10)) {
13034
- console.log(chalk28.gray(` ${v}`));
13310
+ console.log(chalk29.gray(` ${v}`));
13035
13311
  }
13036
13312
  if (report.missingCssVars.length > 10) {
13037
- console.log(chalk28.gray(` ... and ${report.missingCssVars.length - 10} more`));
13313
+ console.log(chalk29.gray(` ... and ${report.missingCssVars.length - 10} more`));
13038
13314
  }
13039
13315
  console.log("");
13040
- console.log(chalk28.cyan(" To add them automatically:"));
13041
- console.log(chalk28.white(" coherent update --patch-globals\n"));
13316
+ console.log(chalk29.cyan(" To add them automatically:"));
13317
+ console.log(chalk29.white(" coherent update --patch-globals\n"));
13042
13318
  }
13043
13319
  console.log("");
13044
- console.log(chalk28.dim(" Your pages and components were NOT modified."));
13045
- console.log(chalk28.dim(" Run `coherent check` to check existing pages against new rules.\n"));
13320
+ console.log(chalk29.dim(" Your pages and components were NOT modified."));
13321
+ console.log(chalk29.dim(" Run `coherent check` to check existing pages against new rules.\n"));
13046
13322
  }
13047
13323
  var EXPECTED_CSS_VARS = [
13048
13324
  "--background",
@@ -13126,7 +13402,7 @@ function patchGlobalsCss(projectRoot, missingVars) {
13126
13402
  }
13127
13403
 
13128
13404
  // src/commands/undo.ts
13129
- import chalk29 from "chalk";
13405
+ import chalk30 from "chalk";
13130
13406
  async function undoCommand(options) {
13131
13407
  try {
13132
13408
  const project = findConfig();
@@ -13135,41 +13411,41 @@ async function undoCommand(options) {
13135
13411
  const backups = listBackups(projectRoot);
13136
13412
  if (options.list) {
13137
13413
  if (backups.length === 0) {
13138
- console.log(chalk29.yellow("No backups found."));
13414
+ console.log(chalk30.yellow("No backups found."));
13139
13415
  return;
13140
13416
  }
13141
- console.log(chalk29.bold("\n\u{1F4E6} Available backups:\n"));
13417
+ console.log(chalk30.bold("\n\u{1F4E6} Available backups:\n"));
13142
13418
  for (const b of backups) {
13143
13419
  const date = new Date(b.timestamp);
13144
13420
  const timeStr = date.toLocaleString();
13145
- console.log(chalk29.white(` ${b.name}`));
13146
- console.log(chalk29.dim(` ${timeStr} \u2014 ${b.files} file(s)`));
13421
+ console.log(chalk30.white(` ${b.name}`));
13422
+ console.log(chalk30.dim(` ${timeStr} \u2014 ${b.files} file(s)`));
13147
13423
  console.log();
13148
13424
  }
13149
13425
  return;
13150
13426
  }
13151
13427
  if (backups.length === 0) {
13152
- console.log(chalk29.yellow("No backups found. Nothing to undo."));
13428
+ console.log(chalk30.yellow("No backups found. Nothing to undo."));
13153
13429
  return;
13154
13430
  }
13155
13431
  const latest = backups[0];
13156
13432
  const ok = restoreBackup(projectRoot, latest.name);
13157
13433
  if (!ok) {
13158
- console.log(chalk29.red("Failed to restore backup."));
13434
+ console.log(chalk30.red("Failed to restore backup."));
13159
13435
  return;
13160
13436
  }
13161
- console.log(chalk29.green("\n\u2705 Restored to previous state:\n"));
13162
- console.log(chalk29.dim(` Snapshot: ${new Date(latest.timestamp).toLocaleString()}`));
13163
- console.log(chalk29.dim(` Files: ${latest.files} restored`));
13164
- console.log(chalk29.cyan("\n Run: coherent preview\n"));
13437
+ console.log(chalk30.green("\n\u2705 Restored to previous state:\n"));
13438
+ console.log(chalk30.dim(` Snapshot: ${new Date(latest.timestamp).toLocaleString()}`));
13439
+ console.log(chalk30.dim(` Files: ${latest.files} restored`));
13440
+ console.log(chalk30.cyan("\n Run: coherent preview\n"));
13165
13441
  } catch (error) {
13166
- console.error(chalk29.red("\u274C Undo failed:"), error instanceof Error ? error.message : "Unknown error");
13442
+ console.error(chalk30.red("\u274C Undo failed:"), error instanceof Error ? error.message : "Unknown error");
13167
13443
  process.exit(1);
13168
13444
  }
13169
13445
  }
13170
13446
 
13171
13447
  // src/commands/sync.ts
13172
- import chalk30 from "chalk";
13448
+ import chalk31 from "chalk";
13173
13449
  import ora9 from "ora";
13174
13450
  import { existsSync as existsSync26, readFileSync as readFileSync18 } from "fs";
13175
13451
  import { join as join20, relative as relative5, dirname as dirname10 } from "path";
@@ -13407,7 +13683,7 @@ async function syncCommand(options = {}) {
13407
13683
  const doTokens = runAll || options.tokens === true;
13408
13684
  const doComponents = runAll || options.components === true;
13409
13685
  const doPatterns = runAll || options.patterns === true;
13410
- if (dryRun) console.log(chalk30.yellow(" [dry-run] No files will be written\n"));
13686
+ if (dryRun) console.log(chalk31.yellow(" [dry-run] No files will be written\n"));
13411
13687
  const spinner = ora9("Scanning project files...").start();
13412
13688
  try {
13413
13689
  const appDir = join20(project.root, "app");
@@ -13548,84 +13824,84 @@ async function syncCommand(options = {}) {
13548
13824
  spinner.succeed("Updated .cursorrules and CLAUDE.md");
13549
13825
  }
13550
13826
  console.log("");
13551
- console.log(chalk30.green(`\u2705 Design System ${dryRun ? "analyzed" : "synced"} with actual code
13827
+ console.log(chalk31.green(`\u2705 Design System ${dryRun ? "analyzed" : "synced"} with actual code
13552
13828
  `));
13553
- console.log(chalk30.blue("\u{1F4C4} Pages:"));
13829
+ console.log(chalk31.blue("\u{1F4C4} Pages:"));
13554
13830
  for (const page of discoveredPages) {
13555
13831
  const a = analyzePageCode(page.code);
13556
13832
  const comps = Object.entries(a.componentUsage || {}).filter(([, c]) => c > 0).map(([n]) => n);
13557
- console.log(chalk30.gray(` ${page.route} \u2014 ${page.name}`));
13558
- if (comps.length > 0) console.log(chalk30.gray(` Components: ${comps.join(", ")}`));
13559
- if (a.sections?.length) console.log(chalk30.gray(` Sections: ${a.sections.map((s) => s.name).join(", ")}`));
13833
+ console.log(chalk31.gray(` ${page.route} \u2014 ${page.name}`));
13834
+ if (comps.length > 0) console.log(chalk31.gray(` Components: ${comps.join(", ")}`));
13835
+ if (a.sections?.length) console.log(chalk31.gray(` Sections: ${a.sections.map((s) => s.name).join(", ")}`));
13560
13836
  }
13561
13837
  if (doTokens && extractedTokens) {
13562
13838
  console.log("");
13563
- console.log(chalk30.blue("\u{1F3A8} Design Tokens (from globals.css):"));
13839
+ console.log(chalk31.blue("\u{1F3A8} Design Tokens (from globals.css):"));
13564
13840
  const lc = Object.keys(extractedTokens.colors.light).length;
13565
13841
  const dc = Object.keys(extractedTokens.colors.dark).length;
13566
- console.log(chalk30.gray(` Light: ${lc} variables | Dark: ${dc} variables`));
13567
- console.log(chalk30.gray(` Default mode: ${extractedTokens.defaultMode}`));
13568
- if (extractedTokens.radius) console.log(chalk30.gray(` Border radius: ${extractedTokens.radius}`));
13842
+ console.log(chalk31.gray(` Light: ${lc} variables | Dark: ${dc} variables`));
13843
+ console.log(chalk31.gray(` Default mode: ${extractedTokens.defaultMode}`));
13844
+ if (extractedTokens.radius) console.log(chalk31.gray(` Border radius: ${extractedTokens.radius}`));
13569
13845
  }
13570
13846
  if (doComponents && reconcileResult) {
13571
13847
  console.log("");
13572
- console.log(chalk30.blue("\u{1F9E9} Shared Components:"));
13848
+ console.log(chalk31.blue("\u{1F9E9} Shared Components:"));
13573
13849
  for (const r of reconcileResult.removed) {
13574
- console.log(chalk30.red(` \u{1F5D1} Removed ${r.id} (${r.name}) \u2014 ${r.reason}`));
13850
+ console.log(chalk31.red(` \u{1F5D1} Removed ${r.id} (${r.name}) \u2014 ${r.reason}`));
13575
13851
  }
13576
13852
  for (const u of reconcileResult.updated) {
13577
- console.log(chalk30.cyan(` \u{1F4DD} Updated ${u.id} ${u.field}: ${u.from} \u2192 ${u.to}`));
13853
+ console.log(chalk31.cyan(` \u{1F4DD} Updated ${u.id} ${u.field}: ${u.from} \u2192 ${u.to}`));
13578
13854
  }
13579
13855
  for (const a of reconcileResult.added) {
13580
- console.log(chalk30.green(` \u2728 Added ${a.id} (${a.name}) \u2014 ${a.file} (${a.type})`));
13856
+ console.log(chalk31.green(` \u2728 Added ${a.id} (${a.name}) \u2014 ${a.file} (${a.type})`));
13581
13857
  }
13582
13858
  for (const w of reconcileResult.warnings) {
13583
- console.log(chalk30.yellow(` \u26A0 ${w.message}`));
13584
- console.log(chalk30.dim(` ${w.suggestion}`));
13859
+ console.log(chalk31.yellow(` \u26A0 ${w.message}`));
13860
+ console.log(chalk31.dim(` ${w.suggestion}`));
13585
13861
  }
13586
13862
  if (reconcileResult.removed.length === 0 && reconcileResult.updated.length === 0 && reconcileResult.added.length === 0 && reconcileResult.warnings.length === 0) {
13587
- console.log(chalk30.gray(" All components consistent \u2713"));
13863
+ console.log(chalk31.gray(" All components consistent \u2713"));
13588
13864
  }
13589
13865
  }
13590
13866
  if (doPatterns && Object.keys(stylePatterns).length > 0) {
13591
13867
  console.log("");
13592
- console.log(chalk30.blue("\u{1F4D0} Style Patterns:"));
13593
- if (stylePatterns.card) console.log(chalk30.gray(` Cards: ${stylePatterns.card.slice(0, 80)}`));
13594
- if (stylePatterns.section) console.log(chalk30.gray(` Sections: ${stylePatterns.section}`));
13595
- if (stylePatterns.terminal) console.log(chalk30.gray(` Terminal: ${stylePatterns.terminal.slice(0, 80)}`));
13596
- if (stylePatterns.iconContainer) console.log(chalk30.gray(` Icons: ${stylePatterns.iconContainer.slice(0, 80)}`));
13868
+ console.log(chalk31.blue("\u{1F4D0} Style Patterns:"));
13869
+ if (stylePatterns.card) console.log(chalk31.gray(` Cards: ${stylePatterns.card.slice(0, 80)}`));
13870
+ if (stylePatterns.section) console.log(chalk31.gray(` Sections: ${stylePatterns.section}`));
13871
+ if (stylePatterns.terminal) console.log(chalk31.gray(` Terminal: ${stylePatterns.terminal.slice(0, 80)}`));
13872
+ if (stylePatterns.iconContainer) console.log(chalk31.gray(` Icons: ${stylePatterns.iconContainer.slice(0, 80)}`));
13597
13873
  if (stylePatterns.heroHeadline)
13598
- console.log(chalk30.gray(` Hero headline: ${stylePatterns.heroHeadline.slice(0, 80)}`));
13874
+ console.log(chalk31.gray(` Hero headline: ${stylePatterns.heroHeadline.slice(0, 80)}`));
13599
13875
  if (stylePatterns.sectionTitle)
13600
- console.log(chalk30.gray(` Section title: ${stylePatterns.sectionTitle.slice(0, 80)}`));
13876
+ console.log(chalk31.gray(` Section title: ${stylePatterns.sectionTitle.slice(0, 80)}`));
13601
13877
  }
13602
13878
  const tokenUsage = extractActualTokenUsage(allPageCode);
13603
13879
  if (tokenUsage.colors.length > 0) {
13604
13880
  console.log("");
13605
- console.log(chalk30.blue("\u{1F3F7}\uFE0F Actual token usage (from classNames):"));
13881
+ console.log(chalk31.blue("\u{1F3F7}\uFE0F Actual token usage (from classNames):"));
13606
13882
  console.log(
13607
- chalk30.gray(
13883
+ chalk31.gray(
13608
13884
  ` Colors: ${tokenUsage.colors.slice(0, 12).join(", ")}${tokenUsage.colors.length > 12 ? ` (+${tokenUsage.colors.length - 12})` : ""}`
13609
13885
  )
13610
13886
  );
13611
13887
  console.log(
13612
- chalk30.gray(
13888
+ chalk31.gray(
13613
13889
  ` Typography: ${tokenUsage.typography.slice(0, 8).join(", ")}${tokenUsage.typography.length > 8 ? ` (+${tokenUsage.typography.length - 8})` : ""}`
13614
13890
  )
13615
13891
  );
13616
- console.log(chalk30.gray(` Radius: ${tokenUsage.borderRadius.join(", ")}`));
13892
+ console.log(chalk31.gray(` Radius: ${tokenUsage.borderRadius.join(", ")}`));
13617
13893
  }
13618
13894
  const reusable = extractReusablePatterns(allPageCode);
13619
13895
  if (reusable.length > 0) {
13620
13896
  console.log("");
13621
- console.log(chalk30.blue(`\u{1F501} Repeating patterns (${reusable.length} \u2014 potential reusable components):`));
13897
+ console.log(chalk31.blue(`\u{1F501} Repeating patterns (${reusable.length} \u2014 potential reusable components):`));
13622
13898
  for (const p of reusable.slice(0, 5)) {
13623
- console.log(chalk30.gray(` \xD7${p.count}: ${p.sample}${p.sample.length < p.pattern.length ? "..." : ""}`));
13899
+ console.log(chalk31.gray(` \xD7${p.count}: ${p.sample}${p.sample.length < p.pattern.length ? "..." : ""}`));
13624
13900
  }
13625
13901
  }
13626
13902
  console.log("");
13627
13903
  if (!dryRun) {
13628
- console.log(chalk30.cyan(" Open /design-system in the app to see the updated view."));
13904
+ console.log(chalk31.cyan(" Open /design-system in the app to see the updated view."));
13629
13905
  }
13630
13906
  console.log("");
13631
13907
  } catch (err) {
@@ -13636,7 +13912,7 @@ async function syncCommand(options = {}) {
13636
13912
  }
13637
13913
 
13638
13914
  // src/commands/migrate.ts
13639
- import chalk31 from "chalk";
13915
+ import chalk32 from "chalk";
13640
13916
  import ora10 from "ora";
13641
13917
  import { existsSync as existsSync27, mkdirSync as mkdirSync8, cpSync, rmSync as rmSync6, writeFileSync as writeFileSync12, readFileSync as readFileSync19, readdirSync as readdirSync9 } from "fs";
13642
13918
  import { join as join21 } from "path";
@@ -13713,13 +13989,13 @@ async function migrateAction(options) {
13713
13989
  }
13714
13990
  const guard = guardPath(projectRoot);
13715
13991
  if (existsSync27(guard)) {
13716
- console.log(chalk31.yellow("A migration is already in progress."));
13717
- console.log(chalk31.dim("Run `coherent migrate --rollback` to undo, or delete .coherent/migration-in-progress"));
13992
+ console.log(chalk32.yellow("A migration is already in progress."));
13993
+ console.log(chalk32.dim("Run `coherent migrate --rollback` to undo, or delete .coherent/migration-in-progress"));
13718
13994
  return;
13719
13995
  }
13720
13996
  const uiDir = join21(projectRoot, "components", "ui");
13721
13997
  if (!existsSync27(uiDir)) {
13722
- console.log(chalk31.yellow("No components/ui directory found. Nothing to migrate."));
13998
+ console.log(chalk32.yellow("No components/ui directory found. Nothing to migrate."));
13723
13999
  return;
13724
14000
  }
13725
14001
  const provider = getComponentProvider();
@@ -13727,16 +14003,16 @@ async function migrateAction(options) {
13727
14003
  const files = readdirSync9(uiDir).filter((f) => f.endsWith(".tsx"));
13728
14004
  const migratable = files.map((f) => f.replace(".tsx", "")).filter((id) => managedIds.has(id));
13729
14005
  if (migratable.length === 0) {
13730
- console.log(chalk31.green("All components are already up to date."));
14006
+ console.log(chalk32.green("All components are already up to date."));
13731
14007
  return;
13732
14008
  }
13733
- console.log(chalk31.cyan(`
14009
+ console.log(chalk32.cyan(`
13734
14010
  Found ${migratable.length} component(s) to migrate:`));
13735
14011
  for (const id of migratable) {
13736
- console.log(chalk31.dim(` - ${id}`));
14012
+ console.log(chalk32.dim(` - ${id}`));
13737
14013
  }
13738
14014
  if (options.dryRun) {
13739
- console.log(chalk31.yellow("\n[dry-run] No changes applied."));
14015
+ console.log(chalk32.yellow("\n[dry-run] No changes applied."));
13740
14016
  return;
13741
14017
  }
13742
14018
  const spinner = ora10("Migrating components...").start();
@@ -13753,12 +14029,12 @@ Found ${migratable.length} component(s) to migrate:`));
13753
14029
  if (result.success) {
13754
14030
  migrated++;
13755
14031
  } else {
13756
- console.warn(chalk31.yellow(` \u26A0 Failed to migrate ${id}`));
14032
+ console.warn(chalk32.yellow(` \u26A0 Failed to migrate ${id}`));
13757
14033
  }
13758
14034
  }
13759
14035
  clearGuard(projectRoot);
13760
14036
  spinner.succeed(`Migrated ${migrated}/${migratable.length} components to real shadcn/ui`);
13761
- console.log(chalk31.dim(` Backup saved to: ${backup}`));
14037
+ console.log(chalk32.dim(` Backup saved to: ${backup}`));
13762
14038
  } catch (err) {
13763
14039
  spinner.fail("Migration failed \u2014 rolling back");
13764
14040
  rollback(projectRoot);
@@ -13770,7 +14046,7 @@ Found ${migratable.length} component(s) to migrate:`));
13770
14046
  import { existsSync as existsSync28, mkdirSync as mkdirSync9, readFileSync as readFileSync20, writeFileSync as writeFileSync13 } from "fs";
13771
14047
  import { join as join22 } from "path";
13772
14048
  import { homedir } from "os";
13773
- import chalk32 from "chalk";
14049
+ import chalk33 from "chalk";
13774
14050
  import { CLI_VERSION as CLI_VERSION5 } from "@getcoherent/core";
13775
14051
  var DEBUG5 = process.env.COHERENT_DEBUG === "1";
13776
14052
  var PACKAGE_NAME = "@getcoherent/cli";
@@ -13841,8 +14117,8 @@ async function checkForUpdates() {
13841
14117
  }
13842
14118
  function printUpdateNotice(latest) {
13843
14119
  console.log(
13844
- chalk32.yellow(`
13845
- \u2B06 Update available: v${CLI_VERSION5} \u2192 v${latest}`) + chalk32.dim(`
14120
+ chalk33.yellow(`
14121
+ \u2B06 Update available: v${CLI_VERSION5} \u2192 v${latest}`) + chalk33.dim(`
13846
14122
  Run: npm update -g ${PACKAGE_NAME}
13847
14123
  `)
13848
14124
  );